https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82282
Bug ID: 82282 Summary: PRE cannot blindly fold integer-to-pointer/pointer-to-integer round-trips Product: gcc Version: 6.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: nunoplopes at sapo dot pt CC: gil.hur at sf dot snu.ac.kr, jeehoon.kang at sf dot snu.ac.kr, juneyoung.lee at sf dot snu.ac.kr, regehr at cs dot utah.edu, sanjoy at playingwithpointers dot com Target Milestone: --- The following program gets miscompiled by gcc: $ cat foo.c #include <stdio.h> #include <stdint.h> int* glb; int* tmp[10]; void main(int argc, char* argv) { int x[1] = { 555 }, y[1] = { 777 }; uintptr_t u = (uintptr_t) (x + 1); uintptr_t v = (uintptr_t) y; uintptr_t w; int b1 = u != v; int b2 = u+1 != v+1; int* z; if (b1) { printf("b1 TRUE.\n"); v = u; } glb = (int*) v; for (int i=0; i < 10; i++) tmp[i] = (int*) v; if (b2) { printf("b2 TRUE.\n"); glb = x; } w = u; for (int i = 0; i < 100; ++i) { if (w < v) { w += 1; } } if (v == w) { z = x; } else { printf("IMPOSSIBLE!\n"); z = y; } *z = 555; *glb = 1; printf("x=%d y=%d\n", x[0], y[0]); } $ gcc -O3 -fdump-tree-all foo.c $ ./a x=555 y=777 We start with: u_14 = (uintptr_t) &MEM[(void *)&x + 4B]; v_15 = (uintptr_t) &y; if (u_14 != v_15) goto <bb 3>; else goto <bb 4>; <bb 4>: # v_1 = PHI <v_15(2), u_14(3)> v.0_19 = (int *) v_1 glb = v.0_19; Which is then (correctly) transformed by phiopt2 to: if (u_14 != v_15) goto <bb 3>; else goto <bb 4>; <bb 4>: # v_1 = PHI <u_14(2), u_14(3)> v.0_19 = (int *) v_1; glb = v.0_19; Then PRE incorrectly removes the pointer-to-integer/integer-to-point cast round-trip through the PHI node: glb = &MEM[(void *)&x + 4B]; This is wrong because we've now lost the information that glb may also alias with y, as seen by the alias analysis report: glb = { ESCAPED NONLOCAL x } After a few more rounds of copy propagation and "dom3", "777" is constant propagated to the printf call, since the store to glb cannot possibly alias 'y' anymore. All the subsequent transformations are correct. The bug is that PRE cannot blindly do a transformation of "int2ptr(ptr2int(x)) -> x". Test case by Gil Hur.