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.