https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82282

--- Comment #2 from Nuno Lopes <nunoplopes at sapo dot pt> ---
This is different from PR82177. That bug is in AA, this one is not.

See the C source:
  uintptr_t u = (uintptr_t) (x + 1);
  uintptr_t v = (uintptr_t) y;

  // if b1 true, then b2 must be true as well
  int b1 = u != v;
  int b2 = u+1 != v+1;

  if (b1) {
    v = u;
  }
  // glb = y if b1 false, glb = u if b1 true
  glb = (int*) v;

  if (b2) {
    // glb = x
    glb = x;
  }

  // glb = y if b1/b2 false, glb = x if b1/b2 true

So at this point, glb can alias either x or y. There's not UB. The cast is from
a legitimate value.
The problem is that gcc replaces
  if (u != v) {
    v = u;
  }

simply with:
v = u;

Which is a correct integer transformation. The deal is that it breaks the
data-flow dependency on 'y'. When the int2ptr cast is removed from "glb =
(int*)v", we get "glb = x + 1", which is wrong.  This behavior couldn't ever
happen in the C program.

Reply via email to