[Bug tree-optimization/58143] [4.8/4.9 regression] wrong code at -O3
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58143 --- Comment #15 from Bernd Edlinger bernd.edlinger at hotmail dot de --- This patch was posted at: http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01733.html
[Bug tree-optimization/58143] [4.8/4.9 regression] wrong code at -O3
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58143 Bernd Edlinger bernd.edlinger at hotmail dot de changed: What|Removed |Added Attachment #30693|0 |1 is obsolete|| --- Comment #14 from Bernd Edlinger bernd.edlinger at hotmail dot de --- Created attachment 30699 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30699action=edit patch to prevent undefined execution in lim OK, this time only the lim pass should be the prevented from introducing undefined behavior that was not there originally. This triggered a minor regression in gcc.target/i386/pr53397-1.c; Here lim used to move the expression 2*step out of the loop, but this may cause undefined behavior on case of overflow, I propose to resolve this by adding -fno-strict-overflow, The test case looks pretty constructed anyway.
[Bug tree-optimization/58143] [4.8/4.9 regression] wrong code at -O3
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58143 Bernd Edlinger bernd.edlinger at hotmail dot de changed: What|Removed |Added Attachment #30681|0 |1 is obsolete|| --- Comment #10 from Bernd Edlinger bernd.edlinger at hotmail dot de --- Created attachment 30693 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30693action=edit possible fix, next try... This variant eliminates the infer_loop_bounds_from_signedness function and some of the invokes undefined behavior warnings. Bootstrapped, and regression tested on i686-pc-linux-gnu. And by the way, it fixes PR57904 too. How do you like it now ?
[Bug tree-optimization/58143] [4.8/4.9 regression] wrong code at -O3
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58143 --- Comment #11 from Jakub Jelinek jakub at gcc dot gnu.org --- No, that is wrong as well.
[Bug tree-optimization/58143] [4.8/4.9 regression] wrong code at -O3
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58143 --- Comment #12 from Bernd Edlinger bernd.edlinger at hotmail dot de --- (In reply to Jakub Jelinek from comment #11) No, that is wrong as well. Because it is too destructive? Maybe. I think this is a general problem here. 1. the undefined behavior warning may be triggered by artefacts from the lim pass or in the class_48.f90 case. 2. surprise optimizations may happen without this warning, see my previous comment #9. 3. in the case of integer overflow, reliable does only say that the operation is executed in every iteration, but not that the result is acually used for something, as in Zhedong's example. With array bounds I have not the same problem, here as I'd say if the array is accessed beyond the limit, the guarantee is void anyway, and the lim pass would never move an array access out of the if statement, right? But there are examples where the undefined behavior warning is not emitted after a possible array bounds exception. A nice example for this is gmp-4.3.2/tests/mpz/t-scan.c This example has a array bounds error: static const int offset[] = { -2, -1, 0, 1, 2, 3 }; ... for (oindex = 0; oindex = numberof (offset); oindex++) // +-1 error here { o = offset[oindex]; ... if (got != want) { ... exit (1); // this cancels the aggressive-loop-optimizations warning } ... } The generated code at -O2 is without the loop termination check, surprise surprise... What do you think?
[Bug tree-optimization/58143] [4.8/4.9 regression] wrong code at -O3
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58143 --- Comment #13 from Jakub Jelinek jakub at gcc dot gnu.org --- Because the bug is in lim, so hacking around it in other parts of the compiler and removing desirable optimizations just to mitigate the bug is not the right way to fix it. Either lim shouldn't move the expressions if they are conditional in the loop body and might trigger undefined behavior in the place where it has been moved to while it might not trigger undefined behavior originally, or lim should transform them into expressions that won't trigger undefined behavior while moving them if it can't prove this will not happen (in this case that would mean performing the arithmetics in a type that doesn't have undefined behavior on overflow).
[Bug tree-optimization/58143] [4.8/4.9 regression] wrong code at -O3
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58143 Eric Botcazou ebotcazou at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |NEW Version|unknown |4.8.0 Last reconfirmed||2013-08-21 Component|middle-end |tree-optimization CC||ebotcazou at gcc dot gnu.org Ever confirmed|0 |1 Summary|wrong code at -O3 on|[4.8/4.9 regression] wrong |x86_64-linux-gnu|code at -O3 Target Milestone|--- |4.8.2
[Bug tree-optimization/58143] [4.8/4.9 regression] wrong code at -O3
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58143 Jakub Jelinek jakub at gcc dot gnu.org changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #8 from Jakub Jelinek jakub at gcc dot gnu.org --- 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.
[Bug tree-optimization/58143] [4.8/4.9 regression] wrong code at -O3
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; i4; i++) { k=10*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 callbar testl %eax, %eax jne .L3 callbar testl %eax, %eax .p2align 4,,4 jne .L4 .p2align 4,,6 callbar movl$20, %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$10, %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 i4 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; i4; i++) { k=10*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) callprintf callbar 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 $10, %ebx, %eax popl%ebx .cfi_restore 3 .cfi_def_cfa_offset 4 ret .cfi_endproc