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 = ...;