https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106892
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|WAITING |NEW CC| |rguenth at gcc dot gnu.org Keywords| |wrong-code --- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Li Shaohua from comment #3) > Yes, I reduced it too much. Here is the new one with return value in g() > function. > > a, b, c, d, e; > f[8]; > g() { > while (a) > a >>= 4; > return 0; > } > h(i) { > if (i >= '0') > return i - '0'; > } > j(i) { > b = 2; > for (; g() <= 7; b++) > if (i) { > for (; e <= 7; e++) { > c = 1; > for (; c <= 7; c++) { > d = h(b + 48); > f[-d + 4] ^= 3; > } > } > return; > } > } > main() { > j(1); > printf("%d\n", f[2]); > } When I apply the same "fix" to h() (add a return 0 or __builtin_unreachable ()) the code works again. Note I think the missing return stmt isn't reached at runtime. Disabling either unswitching or loop splitting makes the issue go away, enabling both ontop of -O2 doesn't trigger it. We early inline h into j where h looks like int h (int i) { int _3; <bb 2> : if (i_1(D) > 47) goto <bb 3>; [INV] else goto <bb 4>; [INV] <bb 3> : _3 = i_1(D) + -48; // predicted unlikely by early return (on trees) predictor. return _3; <bb 4> : return; } which results in b.2_1 = b; _2 = b.2_1 + 48; _3 = h (_2); d = _3; becoming b.2_1 = b; _2 = b.2_1 + 48; if (_2 > 47) goto <bb 6>; [34.00%] else goto <bb 7>; [66.00%] <bb 6> : _30 = _2 + -48; _43 = _30; <bb 7> : # _39 = PHI <_43(6), _37(5)> _3 = _39; d = _3; note that the return; case results in _37 to be used which is completely random. That said, our handling of an unreachable missing return in the IL is likely counter productive. Cleaned up testcase: int a, b, c, d, e; int f[8]; int g() { while (a) a >>= 4; return 0; } int h(int i) { if (i >= '0') return i - '0'; //__builtin_unreachable (); } void j(int i) { b = 2; for (; g() <= 7; b++) if (i) { for (; e <= 7; e++) { c = 1; for (; c <= 7; c++) { d = h(b + 48); f[-d + 4] ^= 3; } } return; } } int main() { j(1); if (f[2] != 0) __builtin_abort (); }