https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83703
Bug ID: 83703 Summary: Loop termination condition ignored in -O3, works in -O2 or with smaller values Product: gcc Version: 7.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: freddie_chopin at op dot pl Target Milestone: --- Example code: -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- #include <stdint.h> #include <stdio.h> const int32_t limit {359}; const int32_t in[] { 5999999, 6000000, 6000001, 11999999, 12000000, 12000001, 17999999, 18000000, 18000001, 25999999, 26000000, }; const int32_t out[] { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, }; int main() { for (int32_t b1 = -limit; b1 < limit; ++b1) { for (int32_t b0 = -limit; b0 < limit; ++b0) { for (int32_t a0 = -limit; a0 < limit; ++a0) { if (a0 == 0) continue; int fail = 0; for (size_t i {}; i < sizeof(out) / sizeof(*out) && fail == 0; ++i) { fail |= (b1 * in[i] + b0) / a0 != out[i]; } if (fail == 0) { printf("success! %i %i %i\n", (int)b1, (int)b0, (int)a0); return 0; } } } printf("fail! %i\n", (int)b1); } return 0; } -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- This code works as intended when compiled with -O2 - last iteration of the outer loop is with b1 == 358. However when compiled with -O3, the outer's loop condition is completely ignored - the loop passes well above the value of `limit` and continues infinitely. Increasing the value of `limit` gives exactly the same result. This fails: $ gcc -O3 reg.cpp -Wall -Wextra && ./a.out fail! -359 fail! -358 ... fail! 964 fail! 965 ^C $ This works: $ gcc -O2 reg.cpp -Wall -Wextra && ./a.out fail! -359 fail! -358 ... fail! 357 fail! 358 $ When I change `limit` to 358, at -O3 there is only ONE iteration. $ gcc -O3 reg.cpp -Wall -Wextra && ./a.out fail! -358 $ When I change `limit` to 357, the program works as intended at -O3. Any value lower and it's the same $ gcc --version gcc (GCC) 7.2.1 20171128 Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Tested on two PCs with Arch Linux, but both are actually mostly identical in h/w and s/w.