https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70020
Bug ID: 70020 Summary: Forward propagation leaves compile-time computable conditional in IL Product: gcc Version: 6.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: law at redhat dot com CC: law at gcc dot gnu.org, law at redhat dot com, su at cs dot ucdavis.edu Depends on: 70005 Target Milestone: --- +++ This bug was initially created as a clone of Bug #70005 +++ Given this code originally from BZ70005 ------------------------------------------------------- unsigned char a = 6; int b, c; static void fn1 () { int i = a > 1 ? 1 : a, j = 6 & (c = a && (b = a)); int d = 0, e = a, f = ~c, g = b || a; unsigned char h = ~a; if (a) f = j; if (h && g) d = a; i = -~(f * d * h) + c && (e || i) ^ f; if (i != 1) __builtin_abort (); } int main () { fn1 (); return 0; } --- At -O2 on x86-64 we have the following in the .dse3 dump: ;; basic block 6, loop depth 0, count 0, freq 7300, maybe hot ;; prev block 5, next block 7, flags: (NEW, REACHABLE) ;; pred: 8 [100.0%] (FALLTHRU,EXECUTABLE) ;; 5 (TRUE_VALUE,EXECUTABLE) # iftmp.2_35 = PHI <1(8), 0(5)> # e_58 = PHI <_5(8), 0(5)> # iftmp.0_67 = PHI <1(8), 0(5)> _23 = iftmp.2_35 + 1; if (_23 != 0) goto <bb 7>; else goto <bb 10>; Which forwprop turns into: ;; basic block 6, loop depth 0, count 0, freq 7300, maybe hot ;; prev block 5, next block 7, flags: (NEW, REACHABLE) ;; pred: 8 [100.0%] (FALLTHRU,EXECUTABLE) ;; 5 (TRUE_VALUE,EXECUTABLE) # iftmp.2_35 = PHI <1(8), 0(5)> # e_58 = PHI <_5(8), 0(5)> # iftmp.0_67 = PHI <1(8), 0(5)> if (iftmp.2_35 != -1) goto <bb 7>; else goto <bb 10>; The condition is obviously the compile-time constant true. Walking backwards to vrp2 we have: # iftmp.2_35 = PHI <1(10), 0(12)> [ ... ] ;; basic block 8, loop depth 0, count 0, freq 7300, maybe hot ;; Invalid sum of incoming frequencies 4999, should be 7300 ;; prev block 7, next block 9, flags: (NEW, REACHABLE) ;; pred: 7 [100.0%] (FALLTHRU,EXECUTABLE) ;; 6 [50.0%] (TRUE_VALUE,EXECUTABLE) # d_17 = PHI <0(7), e_58(6)> # iftmp.2_56 = PHI <iftmp.2_35(7), iftmp.2_35(6)> # e_59 = PHI <e_58(7), e_58(6)> # f_61 = PHI <0(7), 0(6)> # h_65 = PHI <0(7), h_52(6)> # iftmp.0_68 = PHI <iftmp.0_67(7), iftmp.0_67(6)> _19 = d_17 * f_61; _20 = (int) h_65; _21 = _19 * _20; _22 = _21 + 1; _23 = _22 + iftmp.2_56; if (_23 != 0) goto <bb 9>; else goto <bb 13>; Unfortunately VRP doesn't catch that f_61 is [0, 0]. Most likely because there was another path through bb8 which was eliminated by jump threading (which is a subroutine that runs after VRP is complete). phicopyprop comes along and simplifies that mess into: # iftmp.2_35 = PHI <1(10), 0(12)> [ ... ] ;; basic block 8, loop depth 0, count 0, freq 7300, maybe hot ;; Invalid sum of incoming frequencies 4999, should be 7300 ;; prev block 7, next block 9, flags: (NEW, REACHABLE) ;; pred: 7 [100.0%] (FALLTHRU,EXECUTABLE) ;; 6 [50.0%] (TRUE_VALUE,EXECUTABLE) # d_17 = PHI <0(7), e_58(6)> # h_65 = PHI <0(7), h_52(6)> _20 = (int) h_65; _23 = iftmp.2_35 + 1; if (_23 != 0) goto <bb 9>; else goto <bb 13>; Which is probably the first place we might have a reasonable chance at catching this. But forwprop is probably a better place because it's working with: ;; basic block 6, loop depth 0, count 0, freq 7300, maybe hot ;; prev block 5, next block 7, flags: (NEW, REACHABLE) ;; pred: 8 [100.0%] (FALLTHRU,EXECUTABLE) ;; 5 (TRUE_VALUE,EXECUTABLE) # iftmp.2_35 = PHI <1(8), 0(5)> # e_58 = PHI <_5(8), 0(5)> # iftmp.0_67 = PHI <1(8), 0(5)> if (iftmp.2_35 != -1) goto <bb 7>; else goto <bb 10>; Anyway this probably isn't terribly important, but I didn't want it to get lost. Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70005 [Bug 70005] [6 Regression] wrong code at -O2 and -O3 on x86_64-linux-gnu