http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58143
--- Comment #9 from Bernd Edlinger <bernd.edlinger at hotmail dot de> --- (In reply to Jakub Jelinek from comment #8) > That patch looks wrong, and would very likely penalize tons of code, this > predicate is used in many places in the compiler and the operations don't > trap. yes, thanks, I agree. This means then the "lim" pass (and probably others like "ifcvt" too) will move code out of the inner loop, as long as it does not trap. But this creates undefined results, and that should not be used by the loop optimization to throw away the loop termination code. In this case I'd say the only other simple solution will be to take out the function infer_loop_bounds_from_signedness() completely at tree-ssa-loop-niter.c, right? To illustrate what this function can do here is another example: loop.c: extern int bar (); int foo () { int i, k; for (i=0; i<4; i++) { k=1000000000*i; if (bar ()) break; } return k; } if you compile this function with -O3 the resulting code is very surprising (with zero warnings): foo: .LFB0: .cfi_startproc subl $12, %esp .cfi_def_cfa_offset 16 call bar testl %eax, %eax jne .L3 call bar testl %eax, %eax .p2align 4,,4 jne .L4 .p2align 4,,6 call bar movl $2000000000, %eax .L2: addl $12, %esp .cfi_remember_state .cfi_def_cfa_offset 4 ret .p2align 4,,7 .p2align 3 .L3: .cfi_restore_state xorl %eax, %eax jmp .L2 .p2align 4,,7 .p2align 3 .L4: movl $1000000000, %eax jmp .L2 Due to the fact, that k will overflow at the forth iteration, the loop is terminated at the third iteration! The reasoning is that the only way to prevent the undefined behaviour of k, one of the first tree invocations of bar must terminate the loop, and thus the loop is only unrolled 3 times. But if the loop is a bit more complex it will not be unrolled, and in this case the normal loop termination conditin "i<4" will not be used at all, resulting in an endless loop. To prevent the loop unrolling I can add a printf: loop.c: extern int bar (); int foo () { int i, k; for (i=0; i<4; i++) { k=1000000000*i; __builtin_printf("loop %d\n", i); if (bar ()) break; } return k; } Now this is an endless loop (bar always returns 0 but the compiler does not know)! foo: .LFB0: .cfi_startproc pushl %ebx .cfi_def_cfa_offset 8 .cfi_offset 3, -8 xorl %ebx, %ebx subl $24, %esp .cfi_def_cfa_offset 32 .L2: movl %ebx, 4(%esp) movl $.LC0, (%esp) call printf call bar testl %eax, %eax jne .L6 addl $1, %ebx .p2align 4,,3 jmp .L2 .p2align 4,,7 .p2align 3 .L6: addl $24, %esp .cfi_def_cfa_offset 8 imull $1000000000, %ebx, %eax popl %ebx .cfi_restore 3 .cfi_def_cfa_offset 4 ret .cfi_endproc