On Mon, Sep 30, 2024 at 01:26:53PM +0200, Jonas Oberhauser wrote: > > > Am 9/28/2024 um 4:49 PM schrieb Alan Stern: > > On Sat, Sep 28, 2024 at 09:51:27AM -0400, Mathieu Desnoyers wrote: > > > Compiler CSE and SSA GVN optimizations can cause the address dependency > > > of addresses returned by rcu_dereference to be lost when comparing those > > > pointers with either constants or previously loaded pointers. > > > > > > Introduce ptr_eq() to compare two addresses while preserving the address > > > dependencies for later use of the address. It should be used when > > > comparing an address returned by rcu_dereference(). > > > > > > This is needed to prevent the compiler CSE and SSA GVN optimizations > > > from replacing the registers holding @a or @b based on their > > > > "Replacing" isn't the right word. What the compiler does is use one > > rather than the other. Furthermore, the compiler can play these games > > even with values that aren't in registers. > > > > You should just say: "... from using @a (or @b) in places where the > > source refers to @b (or @a) (based on the fact that after the > > comparison, the two are known to be equal), which does not ..." > > I should also point out that it is not enough to prevent the compiler from > using @a instead of @b. > > It must also be prevented from assigning @b=@a, which it is often allowed to > do after finding @a==@b. Wouldn't that be a bug? Consider this litmus test: int x = 0; int y = 45; int z = 0; void P0(int *x, int *y, int *z) { int r1, r2; r1 = READ_ONCE(*x); r2 = READ_ONCE(*y); if (r1 == r2) { WRITE_ONCE(*z, 1); // L1: WRITE_ONCE(*y, r1); } } void P1(int *x, int *y) { int r3; WRITE_ONCE(*x, 45); WRITE_ONCE(*y, 56); r3 = READ_ONCE(*y); } exists (z=1 /\ 1:r3=45) (* Not allowed *) If the compiler were to make the extra assignment (basically, uncommenting the line marked L1) then the exists clause could be satisfied. That would indicate there's a bug in the compiler. Alan