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.