https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69760
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |wrong-code Status|REOPENED |NEW Component|c |tree-optimization --- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- It's still true that L*k is still an int multiplication and if that overflows the behavior is undefined. In .original you can see if (k >= 0 && k < n) { *(a + (sizetype) ((long unsigned int) (L * k) * 8)) = 0.0; } which means the FE only makes sure to carry out the multiplication by the element size in sizetype, the index multiplication is done as written. -fno-strict-overflow or -fwrapv fix the bug. ubsan instruments like if (_12 != 0) goto <bb 4>; else goto <bb 5>; <bb 4>: _14 = UBSAN_CHECK_MUL (L_13(D), k_8); _15 = (long unsigned int) _14; _16 = _15 * 8; _18 = a_17(D) + _16; so it seems it should catch overflow there (and it doesn't overflow here). IVOPTs OTOH rewrites the IV to sth with initial value computed as a + ((sizetype)(L * -m) * 8) We increment that IV by (sizetype)L * 8. That's bogus as L * -m might overflow in int. Now the question is how it arrives at this initial value.