https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107709
Bug ID: 107709
Summary: IVOPTs is introducing a non-zero assumption
Product: gcc
Version: 13.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: amacleod at redhat dot com
Target Milestone: ---
Ive been working on fixing https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78655 ,
which basically adds an inferred range to
ptr1 = ptr2 + non-zero-const
such that ptr2 will be non-zero after this statement. Ive spent the last
couple of days trying to figure out why fortran is failing in a bootstrap, and
I think I finally have it figured out. fortran/scanner.c is being miscompiled
at -O2, and it boils down to the following testcase:
char *nextc;
void huh ()
{
int i;
char c;
for (i = 0; i < 5; i++)
{
c = (nextc == 0) ? '\n' : *nextc++;
if (c != ' ')
break;
}
}
The very beginning of this function, just before going into ivopts, looks like:
char * prephitmp_3;
char * pretmp_4;
unsigned int ivtmp_14;
unsigned int ivtmp_15;
<bb 2> [local count: 243289824]:
pretmp_4 = nextc;
<bb 3> [local count: 894749065]:
# prephitmp_3 = PHI <_2(7), pretmp_4(2)>
# ivtmp_14 = PHI <ivtmp_15(7), 5(2)>
if (prephitmp_3 != 0B)
goto <bb 5>; [96.34%]
else
goto <bb 8>; [3.66%]
<bb 8> [local count: 32747817]:
<bb 4> [local count: 243289824]:
return;
note that prephitmp_3 will be pretmp4 to start the loop (edge 2->3), and then
it is checked against 0 (NULL) and processing only continues to BB5 if it isnt
NULL.
After IVOPTS runs, this is transformed into:
<bb 2> [local count: 243289824]:
pretmp_4 = nextc;
_12 = pretmp_4 + 5; <-- New introduction
<bb 3> [local count: 894749065]:
# prephitmp_3 = PHI <_2(7), pretmp_4(2)>
if (prephitmp_3 != 0B)
goto <bb 5>; [96.34%]
else
goto <bb 8>; [3.66%]
<bb 8> [local count: 32747817]:
<bb 4> [local count: 243289824]:
return;
Note it has added
_12 = pretmp_4 + 5
to basic block 2.
With the new code to instruct VRP that ptr1 = ptr2 + const means ptr2 is
non-null, it now propagates a range of [+1, +INF] for pretmp_4 on the edge
2->3, and that allows the condition which checks prephitmp_3 != 0 to be folded,
as _2 is always non-zero as well.
It seems that IVOPTS should not be adding that statement into BB2? It is
introducing a non-zero assumption that is not there before.