[Bug tree-optimization/58143] [4.8/4.9 regression] wrong code at -O3

2013-08-28 Thread bernd.edlinger at hotmail dot de
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

2013-08-25 Thread bernd.edlinger at hotmail dot de
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

2013-08-23 Thread bernd.edlinger at hotmail dot de
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

2013-08-23 Thread jakub at gcc dot gnu.org
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

2013-08-23 Thread bernd.edlinger at hotmail dot de
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

2013-08-23 Thread jakub at gcc dot gnu.org
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

2013-08-21 Thread ebotcazou at gcc dot gnu.org
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

2013-08-21 Thread jakub at gcc dot gnu.org
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

2013-08-21 Thread bernd.edlinger at hotmail dot de
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