[Bug tree-optimization/82282] New: PRE cannot blindly fold integer-to-pointer/pointer-to-integer round-trips
nunoplopes at sapo dot pt
gcc-bugzilla@gcc.gnu.org
Thu Sep 21 16:31:00 GMT 2017
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.
More information about the Gcc-bugs
mailing list