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.