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

--- Comment #4 from Nuno Lopes <nunoplopes at sapo dot pt> ---
There are two major transformations going on:
  if (u != v) {
    v = u;
  }
=>
  v = u

(with v, u integers)

and:

  glb = (int*)(uinptr_t)foo)
=>
  glb = foo


Doing both triggers the end-to-end miscompilation for a C program that exhibits
no UB.  That means that one of transformations is wrong.
Disabling integer propagation would be really weird and bad.
So we are left with making "(int*)(uinptr_t)foo -> foo" an invalid
transformation in general.  It's correct in some cases, but not always.

AA is behaving correctly because it is working just over pointers (since
integer casts were removed) and thus it is allowed to looking strictly at
data-flow dependencies.

The fix, we believe, is simple: remove the transformation "(int*)(uinptr_t)foo
-> foo", or enable it just in the cases when it's correct.
For example, it's correct in this case:
  int v = p; // p is provably dereferenceable
  int *q = v;
  *q = ..;
    =>
  *p = ...;

but it's not correct in this case (at GIMPLE/SSA level):
  int v = p; // p may *not* be dereferenceable
  int *q = v;
  *q = ..;
    =>
  *p = ...;

Reply via email to