https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100315
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Version|unknown |12.0 Keywords|wrong-code | Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- I think that's OK - the outer while (1) loop invokes UB if a is zero (e overflows) so we can assume that path isn't taken (CD-DCE produces this by noting that the outer loop is finite). It's a bit "unconcious" arriving at this, but well ... Marking useful stmt: foo (); Found loop 1 to be finite: upper bound found. (****) Processing worklist: processing: foo (); Eliminating unnecessary statements: Deleting : e_7 = e_2 + 1; Deleting : if (a.0_1 != 0) Deleting : a.0_1 = a; Deleting : e_2 = PHI <0(2), _7(6)> Removing basic block 6 ;; basic block 6, loop depth 1 ;; pred: goto <bb 3>; [INV] (****) that causes the loop 'control' to be elided which for endless loops where only UB makes it "finite" causes some random transform. At -O1 we do not perform CD-DCE, instead IPA analyzes 'a' to be not modified and thus zero so we can fold if (c) to if (0). With -O3 we have already eliminated this control based on UB (but in the other direction). So in the end the testcase invokes UB and thus is quite meaningless. Making 'e' unsigned int produces the same result from -O3 as -O1 and the call to foo is eliminated.