https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70274
Bug ID: 70274 Summary: optimization goes astray and adds completely redundant code Product: gcc Version: 5.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: l_belev at yahoo dot com Target Milestone: --- here is c code that demonstrates the problem: double x; unsigned n; void foo() { while (n > 8) { n -= 8; x *= 3.0; } } compiled with options: -O2 -fomit-frame-pointer -quiet -ffast-math -march=core2 then observe the result assembly (i will paste part of it here for convenience): .... _foo: movl _n, %edx cmpl $8, %edx jbe L1 movsd _x, %xmm0 movl %edx, %eax movsd LC0, %xmm1 .p2align 4,,10 L3: mulsd %xmm1, %xmm0 subl $8, %eax cmpl $8, %eax ja L3 leal -9(%edx), %eax // redundant code subl $8, %edx // redundant code movsd %xmm0, _x andl $-8, %eax // redundant code subl %eax, %edx // redundant code movl %edx, _n L1: ret ... Apparently GCC notices opportunity for strength-reduction (or something else, i'm not sure what) about the variable n and produces code that directly calculates n without the need of the loop (the instructions i marked with "redundant code"). But GCC fails to consider that the loop is run anyway (because it has other effects besides calculating n, which can't be strength-reduced). So after the end of the loop, the final value of n is already available, but GCC decides to discard it and re-calculates it again by means of the witty "strength-reduced" code. That is completely redundant.