public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] PR58143/58227 wrong code at -O3
@ 2013-08-28 21:28 Bernd Edlinger
  2013-08-29 10:04 ` Richard Biener
  0 siblings, 1 reply; 9+ messages in thread
From: Bernd Edlinger @ 2013-08-28 21:28 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 820 bytes --]

The lim pass (aka loop invariant motion) can move conditional expressions with possible undefined behavior out of the if statement inside a loop which may cause the loop optimization to silently generate wrong code as PR tree-optimization/58143 and PR tree-optimization/58227 demonstrate. 

This patch prevents lim from moving code that might cause undefined behavior.

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.

The patch was boot-strapped and regression tested on i686-pc-linux-gnu and 
X86_64-linux-gnu

OK for trunk?

Regards
Bernd Edlinger 		 	   		  

[-- Attachment #2: changelog-lim.txt --]
[-- Type: text/plain, Size: 565 bytes --]

2013-08-28  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	PR tree-optimization/58143
	PR tree-optimization/58227
	Prevent lim from moving conditional expressions
	if that could trigger undefined behavior.
	* gimple.h (gimple_could_trap_p_2): New function.
	* gimple.c (gimple_could_trap_p_2): New function.
	(gimple_could_trap_p_1): Call gimple_could_trap_p_2.
	* tree-ssa-loop-im.c (movement_possibility): Likewise.


testsuite/

	* gcc.dg/pr58143.c: New test.
	* gcc.target/i386/pr53397-1.c: Added -fno-strict-overflow.
	* gcc.target/i386/pr53397-2.c: Likewise.


[-- Attachment #3: patch-lim.diff --]
[-- Type: application/octet-stream, Size: 5435 bytes --]

--- gcc/gimple.c	2013-08-16 11:05:52.000000000 +0200
+++ gcc/gimple.c	2013-08-23 19:12:59.000000000 +0200
@@ -2391,16 +2391,19 @@ gimple_has_side_effects (const_gimple s)
   return false;
 }
 
-/* Helper for gimple_could_trap_p and gimple_assign_rhs_could_trap_p.
+/* Helper for gimple_could_trap_p_1.
    Return true if S can trap.  When INCLUDE_MEM is true, check whether
    the memory operations could trap.  When INCLUDE_STORES is true and
-   S is a GIMPLE_ASSIGN, the LHS of the assignment is also checked.  */
+   S is a GIMPLE_ASSIGN, the LHS of the assignment is also checked.
+   When INCLUDE_UNDEFINED is true, check whether the operation could
+   trap or invoke undefined behavior.  */
 
 bool
-gimple_could_trap_p_1 (gimple s, bool include_mem, bool include_stores)
+gimple_could_trap_p_2 (gimple s, bool include_mem, bool include_stores, bool include_undefined)
 {
   tree t, div = NULL_TREE;
   enum tree_code op;
+  bool honor_trapv;
 
   if (include_mem)
     {
@@ -2426,12 +2429,14 @@ gimple_could_trap_p_1 (gimple s, bool in
     case GIMPLE_ASSIGN:
       t = gimple_expr_type (s);
       op = gimple_assign_rhs_code (s);
+      honor_trapv = INTEGRAL_TYPE_P (t)
+		    && (TYPE_OVERFLOW_TRAPS (t)
+			|| (include_undefined
+			    && TYPE_OVERFLOW_UNDEFINED (t)));
       if (get_gimple_rhs_class (op) == GIMPLE_BINARY_RHS)
 	div = gimple_assign_rhs2 (s);
       return (operation_could_trap_p (op, FLOAT_TYPE_P (t),
-				      (INTEGRAL_TYPE_P (t)
-				       && TYPE_OVERFLOW_TRAPS (t)),
-				      div));
+				      honor_trapv, div));
 
     default:
       break;
@@ -2440,6 +2445,17 @@ gimple_could_trap_p_1 (gimple s, bool in
   return false;
 }
 
+/* Helper for gimple_could_trap_p and gimple_assign_rhs_could_trap_p.
+   Return true if S can trap.  When INCLUDE_MEM is true, check whether
+   the memory operations could trap.  When INCLUDE_STORES is true and
+   S is a GIMPLE_ASSIGN, the LHS of the assignment is also checked.  */
+
+bool
+gimple_could_trap_p_1 (gimple s, bool include_mem, bool include_stores)
+{
+  return gimple_could_trap_p_2 (s, include_mem, include_stores, false);
+}
+
 /* Return true if statement S can trap.  */
 
 bool
--- gcc/gimple.h	2013-08-16 14:38:04.000000000 +0200
+++ gcc/gimple.h	2013-08-23 18:36:19.000000000 +0200
@@ -846,6 +846,7 @@ void gimple_cond_set_condition_from_tree
 bool gimple_has_side_effects (const_gimple);
 bool gimple_could_trap_p (gimple);
 bool gimple_could_trap_p_1 (gimple, bool, bool);
+bool gimple_could_trap_p_2 (gimple, bool, bool, bool);
 bool gimple_assign_rhs_could_trap_p (gimple);
 void gimple_regimplify_operands (gimple, gimple_stmt_iterator *);
 bool empty_body_p (gimple_seq);
--- gcc/tree-ssa-loop-im.c	2013-04-30 10:14:09.000000000 +0200
+++ gcc/tree-ssa-loop-im.c	2013-08-23 21:15:50.000000000 +0200
@@ -407,7 +407,7 @@ movement_possibility (gimple stmt)
     return MOVE_IMPOSSIBLE;
 
   if (TREE_CODE (lhs) != SSA_NAME
-      || gimple_could_trap_p (stmt))
+      || gimple_could_trap_p_2 (stmt, true, true, true))
     return MOVE_PRESERVE_EXECUTION;
 
   /* Non local loads in a transaction cannot be hoisted out.  Well,
--- gcc/testsuite/gcc.dg/pr58143.c	1970-01-01 01:00:00.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr58143.c	2013-08-20 13:56:01.000000000 +0200
@@ -0,0 +1,49 @@
+/* PR tree-optimization/58143 */
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+
+int a, b, c, d, e, f, g, h, i;
+
+int foo ()
+{
+  return c < 0 && a < -2147483647 - 1 - c ? 0 : 1;
+}
+
+int *bar ()
+{
+  int j; 
+  i = h ? 2 + h : 0;
+  for (j = 0; j < 1; j++)
+    for (d = 0; d; d++)
+      for (e = 1; e;)
+	return 0;
+  return 0;
+}
+
+int baz ()
+{
+  for (; b >= 0; b--)
+    for (c = 1; c >= 0; c--)
+      {
+	for (;;)
+	  {
+	    for (f = 0; f < 2; f++)
+	      {
+		g = foo ();
+		bar ();
+	      }
+	    if (c)
+	      break;
+	    return 0;
+	  }
+      }
+  return 0;
+}
+
+int main ()
+{
+  baz ();
+  if (b != 0)
+    __builtin_abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.target/i386/pr53397-1.c	2012-10-10 17:31:27.000000000 +0200
+++ gcc/testsuite/gcc.target/i386/pr53397-1.c	2013-08-25 11:54:16.000000000 +0200
@@ -1,7 +1,7 @@
 /* Prefetching when the step is loop invariant.  */
 /* { dg-do compile } */
 /* { dg-require-effective-target sse2 } */
-/* { dg-options "-O3 -msse2 -fprefetch-loop-arrays -fdump-tree-aprefetch-details --param min-insn-to-prefetch-ratio=3 --param simultaneous-prefetches=10 -fdump-tree-aprefetch-details" } */
+/* { dg-options "-O3 -msse2 -fprefetch-loop-arrays -fno-strict-overflow --param min-insn-to-prefetch-ratio=3 --param simultaneous-prefetches=10 -fdump-tree-aprefetch-details" } */
 
 
 double data[16384];
--- gcc/testsuite/gcc.target/i386/pr53397-2.c	2012-10-10 17:31:27.000000000 +0200
+++ gcc/testsuite/gcc.target/i386/pr53397-2.c	2013-08-25 11:54:37.000000000 +0200
@@ -1,7 +1,7 @@
 /* Not prefetching when the step is loop variant.  */
 /* { dg-do compile } */
 /* { dg-require-effective-target sse2 } */
-/* { dg-options "-O3 -msse2 -fprefetch-loop-arrays -fdump-tree-aprefetch-details --param min-insn-to-prefetch-ratio=3 --param simultaneous-prefetches=10 -fdump-tree-aprefetch-details" } */
+/* { dg-options "-O3 -msse2 -fprefetch-loop-arrays -fno-strict-overflow --param min-insn-to-prefetch-ratio=3 --param simultaneous-prefetches=10 -fdump-tree-aprefetch-details" } */
 
 double data[16384];
 void donot_prefetch_when_non_constant_step_is_variant(int step, int n)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] PR58143/58227 wrong code at -O3
  2013-08-28 21:28 [PATCH] PR58143/58227 wrong code at -O3 Bernd Edlinger
@ 2013-08-29 10:04 ` Richard Biener
  2013-08-30 16:50   ` Bernd Edlinger
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Biener @ 2013-08-29 10:04 UTC (permalink / raw)
  To: Bernd Edlinger; +Cc: gcc-patches

On Wed, Aug 28, 2013 at 11:24 PM, Bernd Edlinger
<bernd.edlinger@hotmail.de> wrote:
> The lim pass (aka loop invariant motion) can move conditional expressions with possible undefined behavior out of the if statement inside a loop which may cause the loop optimization to silently generate wrong code as PR tree-optimization/58143 and PR tree-optimization/58227 demonstrate.
>
> This patch prevents lim from moving code that might cause undefined behavior.
>
> 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.
>
> The patch was boot-strapped and regression tested on i686-pc-linux-gnu and
> X86_64-linux-gnu
>
> OK for trunk?

2013-08-28  Bernd Edlinger  <bernd.edlinger@hotmail.de>

PR tree-optimization/58143
PR tree-optimization/58227
Prevent lim from moving conditional expressions
if that could trigger undefined behavior.
* gimple.h (gimple_could_trap_p_2): New function.
* gimple.c (gimple_could_trap_p_2): New function.
(gimple_could_trap_p_1): Call gimple_could_trap_p_2.
* tree-ssa-loop-im.c (movement_possibility): Likewise.

Please fold the overall comment into the movement_possibility changelog.

Can you instead of introducing gimple_could_trap_p_2 simply change the
signature and name of gimple_could_trap_p_1 please?  It is only called
three times.
A proper name could be gimple_could_trap_or_invoke_undefined_p.

That you need to change the two testcases makes me nervous (also please
use -fwrapv, not -fno-strict-overflow) - did you check what happens for them?

Thanks,
Richard.



> Regards
> Bernd Edlinger

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH] PR58143/58227 wrong code at -O3
  2013-08-29 10:04 ` Richard Biener
@ 2013-08-30 16:50   ` Bernd Edlinger
  2013-09-03 10:31     ` Richard Biener
  0 siblings, 1 reply; 9+ messages in thread
From: Bernd Edlinger @ 2013-08-30 16:50 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 3307 bytes --]

On Thu, 29 Aug 2013 11:54:22, Richard Biener wrote:
> On Wed, Aug 28, 2013 at 11:24 PM, Bernd Edlinger
> <bernd.edlinger@hotmail.de> wrote:
>> The lim pass (aka loop invariant motion) can move conditional expressions with
>> possible undefined behavior out of the if statement inside a loop which may cause the
>> loop optimization to silently generate wrong code as PR tree-optimization/58143 and
>> PR tree-optimization/58227 demonstrate.
>>
>> This patch prevents lim from moving code that might cause undefined behavior.
>>
>> 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.
>>
>> The patch was boot-strapped and regression tested on i686-pc-linux-gnu and
>> X86_64-linux-gnu
>>
>> OK for trunk?
>
> 2013-08-28 Bernd Edlinger <bernd.edlinger@hotmail.de>
>
> PR tree-optimization/58143
> PR tree-optimization/58227
> Prevent lim from moving conditional expressions
> if that could trigger undefined behavior.
> * gimple.h (gimple_could_trap_p_2): New function.
> * gimple.c (gimple_could_trap_p_2): New function.
> (gimple_could_trap_p_1): Call gimple_could_trap_p_2.
> * tree-ssa-loop-im.c (movement_possibility): Likewise.
>
> Please fold the overall comment into the movement_possibility changelog.
>

done.

> Can you instead of introducing gimple_could_trap_p_2 simply change the
> signature and name of gimple_could_trap_p_1 please? It is only called
> three times.
> A proper name could be gimple_could_trap_or_invoke_undefined_p.
>

done.

> That you need to change the two testcases makes me nervous (also please
> use -fwrapv, not -fno-strict-overflow) - did you check what happens for them?
>

Yes, I looked at that again.  That is an interesting story.
Initially the function looks like:

for (a = 1; a < step; a++) {
   for (b = 0; b <n; b += 2 * step) {

when the lim pass is invoked that looks like:

if (step> 1 && n> 0) {
  for (a = 1; a < step; a++) {
    pretmp = step * 2;
    for (b = 0; b < n; b += pretmp) {

Well "step*2" was initially at loop level 2, but now I see, it is actually at loop level 1.

When lim does not move this out of the loop the test case fails.
But if lim moves this statement out of the loop despite the possible undefined
behavior, the test case passes.

Now I think this is good opportunity for a simple heuristic:

If a statement is at loop level 1 we can move it out of the loop,
regardless of the fact, that it may invoke undefined behavior, because if it is
moved then out of any loops, and thus it cannot be an induction variable and
cause problems with aggressive loop optimizations later.

Only statements with possible undefined behavior in nested loops can become
induction variable if lim moves them from one loop into an outer loop.

Therefore with extremely much luck the test case will pass unmodified.
I tried it, and the patch passes bootstrap and causes zero regressions
with this heuristic.

Ok for trunk now?

Thanks
Bernd.

> Thanks,
> Richard.
>
>
>
>> Regards
>> Bernd Edlinger 		 	   		  

[-- Attachment #2: changelog-lim.txt --]
[-- Type: text/plain, Size: 718 bytes --]

2013-08-30  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	PR tree-optimization/58143
	PR tree-optimization/58227
	* gimple.c (gimple_could_trap_p_1): Rename to ...
	(gimple_could_trap_or_invoke_undefined_p): ... this
	and add new parameter include_undefined.
	(gimple_could_trap_or_invoke_undefined_p): Adjust.
	(gimple_assign_rhs_could_trap_p): Adjust.
	* gimple.h (gimple_could_trap_p_1): Renamed.
	* tree-if-conv.c (ifcvt_could_trap_p): Adjust.
	* tree-ssa-loop-im.c (movement_possibility): Prevent
	lim from moving conditional expressions if that could
	trigger undefined behavior in nested loops.
	(determine_invariantness_stmt): Determine if this
	is a nested loop.


testsuite/

	* gcc.dg/pr58143.c: New test.


[-- Attachment #3: patch-lim.diff --]
[-- Type: application/octet-stream, Size: 5995 bytes --]

--- gcc/gimple.c	2013-08-16 11:05:52.000000000 +0200
+++ gcc/gimple.c	2013-08-29 22:49:09.000000000 +0200
@@ -2394,13 +2394,17 @@ gimple_has_side_effects (const_gimple s)
 /* Helper for gimple_could_trap_p and gimple_assign_rhs_could_trap_p.
    Return true if S can trap.  When INCLUDE_MEM is true, check whether
    the memory operations could trap.  When INCLUDE_STORES is true and
-   S is a GIMPLE_ASSIGN, the LHS of the assignment is also checked.  */
+   S is a GIMPLE_ASSIGN, the LHS of the assignment is also checked.
+   When INCLUDE_UNDEFINED is true, check whether the operation could
+   trap or invoke undefined behavior.  */
 
 bool
-gimple_could_trap_p_1 (gimple s, bool include_mem, bool include_stores)
+gimple_could_trap_or_invoke_undefined_p (gimple s, bool include_mem,
+			bool include_stores, bool include_undefined)
 {
   tree t, div = NULL_TREE;
   enum tree_code op;
+  bool honor_trapv;
 
   if (include_mem)
     {
@@ -2426,12 +2430,14 @@ gimple_could_trap_p_1 (gimple s, bool in
     case GIMPLE_ASSIGN:
       t = gimple_expr_type (s);
       op = gimple_assign_rhs_code (s);
+      honor_trapv = INTEGRAL_TYPE_P (t)
+		    && (TYPE_OVERFLOW_TRAPS (t)
+			|| (include_undefined
+			    && TYPE_OVERFLOW_UNDEFINED (t)));
       if (get_gimple_rhs_class (op) == GIMPLE_BINARY_RHS)
 	div = gimple_assign_rhs2 (s);
       return (operation_could_trap_p (op, FLOAT_TYPE_P (t),
-				      (INTEGRAL_TYPE_P (t)
-				       && TYPE_OVERFLOW_TRAPS (t)),
-				      div));
+				      honor_trapv, div));
 
     default:
       break;
@@ -2445,7 +2451,7 @@ gimple_could_trap_p_1 (gimple s, bool in
 bool
 gimple_could_trap_p (gimple s)
 {
-  return gimple_could_trap_p_1 (s, true, true);
+  return gimple_could_trap_or_invoke_undefined_p (s, true, true, false);
 }
 
 /* Return true if RHS of a GIMPLE_ASSIGN S can trap.  */
@@ -2454,7 +2460,7 @@ bool
 gimple_assign_rhs_could_trap_p (gimple s)
 {
   gcc_assert (is_gimple_assign (s));
-  return gimple_could_trap_p_1 (s, true, false);
+  return gimple_could_trap_or_invoke_undefined_p (s, true, false, false);
 }
 
 
--- gcc/gimple.h	2013-08-16 14:38:04.000000000 +0200
+++ gcc/gimple.h	2013-08-29 20:13:44.000000000 +0200
@@ -845,7 +845,7 @@ gimple gimple_build_cond_from_tree (tree
 void gimple_cond_set_condition_from_tree (gimple, tree);
 bool gimple_has_side_effects (const_gimple);
 bool gimple_could_trap_p (gimple);
-bool gimple_could_trap_p_1 (gimple, bool, bool);
+bool gimple_could_trap_or_invoke_undefined_p (gimple, bool, bool, bool);
 bool gimple_assign_rhs_could_trap_p (gimple);
 void gimple_regimplify_operands (gimple, gimple_stmt_iterator *);
 bool empty_body_p (gimple_seq);
--- gcc/tree-if-conv.c	2013-08-05 22:16:05.000000000 +0200
+++ gcc/tree-if-conv.c	2013-08-29 20:24:46.000000000 +0200
@@ -671,7 +671,7 @@ static bool
 ifcvt_could_trap_p (gimple stmt, vec<data_reference_p> refs)
 {
   if (gimple_vuse (stmt)
-      && !gimple_could_trap_p_1 (stmt, false, false)
+      && !gimple_could_trap_or_invoke_undefined_p (stmt, false, false, false)
       && ifcvt_memrefs_wont_trap (stmt, refs))
     return false;
 
--- gcc/tree-ssa-loop-im.c	2013-04-30 10:14:09.000000000 +0200
+++ gcc/tree-ssa-loop-im.c	2013-08-29 21:19:27.000000000 +0200
@@ -340,10 +340,12 @@ for_each_index (tree *addr_p, bool (*cbc
    If it is possible to hoist the statement STMT, but we must avoid making
    it executed if it would not be executed in the original program (e.g.
    because it may trap), return MOVE_PRESERVE_EXECUTION.
+   If STMT is in a NESTED loop and STMT could invoke undefined behavior,
+   return MOVE_PRESERVE_EXECUTION.
    Otherwise return MOVE_IMPOSSIBLE.  */
 
 enum move_pos
-movement_possibility (gimple stmt)
+movement_possibility (gimple stmt, bool nested)
 {
   tree lhs;
   enum move_pos ret = MOVE_POSSIBLE;
@@ -407,7 +409,7 @@ movement_possibility (gimple stmt)
     return MOVE_IMPOSSIBLE;
 
   if (TREE_CODE (lhs) != SSA_NAME
-      || gimple_could_trap_p (stmt))
+      || gimple_could_trap_or_invoke_undefined_p (stmt, true, true, nested))
     return MOVE_PRESERVE_EXECUTION;
 
   /* Non local loads in a transaction cannot be hoisted out.  Well,
@@ -1055,10 +1057,12 @@ determine_invariantness_stmt (struct dom
   bool maybe_never = ALWAYS_EXECUTED_IN (bb) == NULL;
   struct loop *outermost = ALWAYS_EXECUTED_IN (bb);
   struct lim_aux_data *lim_data;
+  bool nested;
 
   if (!loop_outer (bb->loop_father))
     return;
 
+  nested = loop_depth (bb->loop_father) > 1;
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "Basic block %d (loop %d -- depth %d):\n\n",
 	     bb->index, bb->loop_father->num, loop_depth (bb->loop_father));
@@ -1075,7 +1079,7 @@ determine_invariantness_stmt (struct dom
       {
 	stmt = gsi_stmt (bsi);
 
-	pos = movement_possibility (stmt);
+	pos = movement_possibility (stmt, nested);
 	if (pos == MOVE_IMPOSSIBLE)
 	  continue;
 
@@ -1104,7 +1108,7 @@ determine_invariantness_stmt (struct dom
     {
       stmt = gsi_stmt (bsi);
 
-      pos = movement_possibility (stmt);
+      pos = movement_possibility (stmt, nested);
       if (pos == MOVE_IMPOSSIBLE)
 	{
 	  if (nonpure_call_p (stmt))
--- gcc/testsuite/gcc.dg/pr58143.c	1970-01-01 01:00:00.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr58143.c	2013-08-20 13:56:01.000000000 +0200
@@ -0,0 +1,49 @@
+/* PR tree-optimization/58143 */
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+
+int a, b, c, d, e, f, g, h, i;
+
+int foo ()
+{
+  return c < 0 && a < -2147483647 - 1 - c ? 0 : 1;
+}
+
+int *bar ()
+{
+  int j;
+  i = h ? 2 + h : 0;
+  for (j = 0; j < 1; j++)
+    for (d = 0; d; d++)
+      for (e = 1; e;)
+	return 0;
+  return 0;
+}
+
+int baz ()
+{
+  for (; b >= 0; b--)
+    for (c = 1; c >= 0; c--)
+      {
+	for (;;)
+	  {
+	    for (f = 0; f < 2; f++)
+	      {
+		g = foo ();
+		bar ();
+	      }
+	    if (c)
+	      break;
+	    return 0;
+	  }
+      }
+  return 0;
+}
+
+int main ()
+{
+  baz ();
+  if (b != 0)
+    __builtin_abort ();
+  return 0;
+}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] PR58143/58227 wrong code at -O3
  2013-08-30 16:50   ` Bernd Edlinger
@ 2013-09-03 10:31     ` Richard Biener
  2013-09-04 16:45       ` Bernd Edlinger
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Biener @ 2013-09-03 10:31 UTC (permalink / raw)
  To: Bernd Edlinger; +Cc: gcc-patches

On Fri, Aug 30, 2013 at 6:43 PM, Bernd Edlinger
<bernd.edlinger@hotmail.de> wrote:
> On Thu, 29 Aug 2013 11:54:22, Richard Biener wrote:
>> On Wed, Aug 28, 2013 at 11:24 PM, Bernd Edlinger
>> <bernd.edlinger@hotmail.de> wrote:
>>> The lim pass (aka loop invariant motion) can move conditional expressions with
>>> possible undefined behavior out of the if statement inside a loop which may cause the
>>> loop optimization to silently generate wrong code as PR tree-optimization/58143 and
>>> PR tree-optimization/58227 demonstrate.
>>>
>>> This patch prevents lim from moving code that might cause undefined behavior.
>>>
>>> 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.
>>>
>>> The patch was boot-strapped and regression tested on i686-pc-linux-gnu and
>>> X86_64-linux-gnu
>>>
>>> OK for trunk?
>>
>> 2013-08-28 Bernd Edlinger <bernd.edlinger@hotmail.de>
>>
>> PR tree-optimization/58143
>> PR tree-optimization/58227
>> Prevent lim from moving conditional expressions
>> if that could trigger undefined behavior.
>> * gimple.h (gimple_could_trap_p_2): New function.
>> * gimple.c (gimple_could_trap_p_2): New function.
>> (gimple_could_trap_p_1): Call gimple_could_trap_p_2.
>> * tree-ssa-loop-im.c (movement_possibility): Likewise.
>>
>> Please fold the overall comment into the movement_possibility changelog.
>>
>
> done.
>
>> Can you instead of introducing gimple_could_trap_p_2 simply change the
>> signature and name of gimple_could_trap_p_1 please? It is only called
>> three times.
>> A proper name could be gimple_could_trap_or_invoke_undefined_p.
>>
>
> done.
>
>> That you need to change the two testcases makes me nervous (also please
>> use -fwrapv, not -fno-strict-overflow) - did you check what happens for them?
>>
>
> Yes, I looked at that again.  That is an interesting story.
> Initially the function looks like:
>
> for (a = 1; a < step; a++) {
>    for (b = 0; b <n; b += 2 * step) {
>
> when the lim pass is invoked that looks like:
>
> if (step> 1 && n> 0) {
>   for (a = 1; a < step; a++) {
>     pretmp = step * 2;
>     for (b = 0; b < n; b += pretmp) {
>
> Well "step*2" was initially at loop level 2, but now I see, it is actually at loop level 1.
>
> When lim does not move this out of the loop the test case fails.
> But if lim moves this statement out of the loop despite the possible undefined
> behavior, the test case passes.
>
> Now I think this is good opportunity for a simple heuristic:
>
> If a statement is at loop level 1 we can move it out of the loop,
> regardless of the fact, that it may invoke undefined behavior, because if it is
> moved then out of any loops, and thus it cannot be an induction variable and
> cause problems with aggressive loop optimizations later.

VRP can still cause wrong-code issues (it's probably hard to generate a
testcase though).  Also a less conservative check would be to see
whether we hoist _into_ loop level 0 (though we cannot check that at
the point where you placed the check).

> Only statements with possible undefined behavior in nested loops can become
> induction variable if lim moves them from one loop into an outer loop.
>
> Therefore with extremely much luck the test case will pass unmodified.
> I tried it, and the patch passes bootstrap and causes zero regressions
> with this heuristic.
>
> Ok for trunk now?

Jakub mentioned another possibility - make sure the moved expression
does not invoke undefined behavior by computing in an unsigned type.

That said, for the sake of backporting we need a patch as simple as
possible - so it would be interesting to see whether the patch without
the loop 1 heuristic has any effect on say SPEC CPU 2006 performance.

Thanks,
Richard.

> Thanks
> Bernd.
>
>> Thanks,
>> Richard.
>>
>>
>>
>>> Regards
>>> Bernd Edlinger

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH] PR58143/58227 wrong code at -O3
  2013-09-03 10:31     ` Richard Biener
@ 2013-09-04 16:45       ` Bernd Edlinger
  2013-09-16  8:27         ` [PING] " Bernd Edlinger
  0 siblings, 1 reply; 9+ messages in thread
From: Bernd Edlinger @ 2013-09-04 16:45 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2130 bytes --]

On Tue, 3 Sep 2013 12:31:50, Richard Biener wrote:
> On Fri, Aug 30, 2013 at 6:43 PM, Bernd Edlinger
> <bernd.edlinger@hotmail.de> wrote:
>> Now I think this is good opportunity for a simple heuristic:
>>
>> If a statement is at loop level 1 we can move it out of the loop,
>> regardless of the fact, that it may invoke undefined behavior, because if it is
>> moved then out of any loops, and thus it cannot be an induction variable and
>> cause problems with aggressive loop optimizations later.
>
> VRP can still cause wrong-code issues (it's probably hard to generate a
> testcase though). Also a less conservative check would be to see
> whether we hoist _into_ loop level 0 (though we cannot check that at
> the point where you placed the check).

Well, then I should better revert this heuristic again.
 
>> Only statements with possible undefined behavior in nested loops can become
>> induction variable if lim moves them from one loop into an outer loop.
>>
>> Therefore with extremely much luck the test case will pass unmodified.
>> I tried it, and the patch passes bootstrap and causes zero regressions
>> with this heuristic.
>>
>> Ok for trunk now?
>
> Jakub mentioned another possibility - make sure the moved expression
> does not invoke undefined behavior by computing in an unsigned type.

That is a possibility, but on the other hand, that would obscure the undefined
behavior and thus prevent other possible optimizations later.

Another possibility would be to move the statement together with the
enclosing if-statement, thus really preserving the execution.
 
> That said, for the sake of backporting we need a patch as simple as
> possible - so it would be interesting to see whether the patch without
> the loop 1 heuristic has any effect on say SPEC CPU 2006 performance.

I do not have access to that test, but on the dhrystone benchmark this patch
has no influence whatsoever.

Attached you'll find the latest version of my patch without the heuristic.
Bootstrapped on i686-pc-linux-gnu and regression tested again.

Ok for trunk and 4.8 branch? 		 	   		  

[-- Attachment #2: changelog-lim.txt --]
[-- Type: text/plain, Size: 712 bytes --]

2013-09-03  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	PR tree-optimization/58143
	PR tree-optimization/58227
	* gimple.c (gimple_could_trap_p_1): Rename to ...
	(gimple_could_trap_or_invoke_undefined_p): ... this
	and add new parameter include_undefined.
	(gimple_could_trap_or_invoke_undefined_p): Adjust.
	(gimple_assign_rhs_could_trap_p): Adjust.
	* gimple.h (gimple_could_trap_p_1): Renamed.
	* tree-if-conv.c (ifcvt_could_trap_p): Adjust.
	* tree-ssa-loop-im.c (movement_possibility): Prevent
	lim from moving conditional expressions if that could
	trigger undefined behavior.


testsuite/

	* gcc.dg/pr58143.c: New test.
	* gcc.target/i386/pr53397-1.c: Adjust.
	* gcc.target/i386/pr53397-2.c: Adjust.


[-- Attachment #3: patch-lim.diff --]
[-- Type: application/octet-stream, Size: 5852 bytes --]

--- gcc/gimple.c	2013-08-16 11:05:52.000000000 +0200
+++ gcc/gimple.c	2013-08-29 22:49:09.000000000 +0200
@@ -2394,13 +2394,17 @@ gimple_has_side_effects (const_gimple s)
 /* Helper for gimple_could_trap_p and gimple_assign_rhs_could_trap_p.
    Return true if S can trap.  When INCLUDE_MEM is true, check whether
    the memory operations could trap.  When INCLUDE_STORES is true and
-   S is a GIMPLE_ASSIGN, the LHS of the assignment is also checked.  */
+   S is a GIMPLE_ASSIGN, the LHS of the assignment is also checked.
+   When INCLUDE_UNDEFINED is true, check whether the operation could
+   trap or invoke undefined behavior.  */
 
 bool
-gimple_could_trap_p_1 (gimple s, bool include_mem, bool include_stores)
+gimple_could_trap_or_invoke_undefined_p (gimple s, bool include_mem,
+			bool include_stores, bool include_undefined)
 {
   tree t, div = NULL_TREE;
   enum tree_code op;
+  bool honor_trapv;
 
   if (include_mem)
     {
@@ -2426,12 +2430,14 @@ gimple_could_trap_p_1 (gimple s, bool in
     case GIMPLE_ASSIGN:
       t = gimple_expr_type (s);
       op = gimple_assign_rhs_code (s);
+      honor_trapv = INTEGRAL_TYPE_P (t)
+		    && (TYPE_OVERFLOW_TRAPS (t)
+			|| (include_undefined
+			    && TYPE_OVERFLOW_UNDEFINED (t)));
       if (get_gimple_rhs_class (op) == GIMPLE_BINARY_RHS)
 	div = gimple_assign_rhs2 (s);
       return (operation_could_trap_p (op, FLOAT_TYPE_P (t),
-				      (INTEGRAL_TYPE_P (t)
-				       && TYPE_OVERFLOW_TRAPS (t)),
-				      div));
+				      honor_trapv, div));
 
     default:
       break;
@@ -2445,7 +2451,7 @@ gimple_could_trap_p_1 (gimple s, bool in
 bool
 gimple_could_trap_p (gimple s)
 {
-  return gimple_could_trap_p_1 (s, true, true);
+  return gimple_could_trap_or_invoke_undefined_p (s, true, true, false);
 }
 
 /* Return true if RHS of a GIMPLE_ASSIGN S can trap.  */
@@ -2454,7 +2460,7 @@ bool
 gimple_assign_rhs_could_trap_p (gimple s)
 {
   gcc_assert (is_gimple_assign (s));
-  return gimple_could_trap_p_1 (s, true, false);
+  return gimple_could_trap_or_invoke_undefined_p (s, true, false, false);
 }
 
 
--- gcc/gimple.h	2013-08-16 14:38:04.000000000 +0200
+++ gcc/gimple.h	2013-08-29 20:13:44.000000000 +0200
@@ -845,7 +845,7 @@ gimple gimple_build_cond_from_tree (tree
 void gimple_cond_set_condition_from_tree (gimple, tree);
 bool gimple_has_side_effects (const_gimple);
 bool gimple_could_trap_p (gimple);
-bool gimple_could_trap_p_1 (gimple, bool, bool);
+bool gimple_could_trap_or_invoke_undefined_p (gimple, bool, bool, bool);
 bool gimple_assign_rhs_could_trap_p (gimple);
 void gimple_regimplify_operands (gimple, gimple_stmt_iterator *);
 bool empty_body_p (gimple_seq);
--- gcc/tree-if-conv.c	2013-08-05 22:16:05.000000000 +0200
+++ gcc/tree-if-conv.c	2013-08-29 20:24:46.000000000 +0200
@@ -671,7 +671,7 @@ static bool
 ifcvt_could_trap_p (gimple stmt, vec<data_reference_p> refs)
 {
   if (gimple_vuse (stmt)
-      && !gimple_could_trap_p_1 (stmt, false, false)
+      && !gimple_could_trap_or_invoke_undefined_p (stmt, false, false, false)
       && ifcvt_memrefs_wont_trap (stmt, refs))
     return false;
 
--- gcc/tree-ssa-loop-im.c	2013-04-30 10:14:09.000000000 +0200
+++ gcc/tree-ssa-loop-im.c	2013-09-03 20:15:38.000000000 +0200
@@ -407,7 +407,7 @@ movement_possibility (gimple stmt)
     return MOVE_IMPOSSIBLE;
 
   if (TREE_CODE (lhs) != SSA_NAME
-      || gimple_could_trap_p (stmt))
+      || gimple_could_trap_or_invoke_undefined_p (stmt, true, true, true))
     return MOVE_PRESERVE_EXECUTION;
 
   /* Non local loads in a transaction cannot be hoisted out.  Well,
--- gcc/testsuite/gcc.dg/pr58143.c	1970-01-01 01:00:00.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr58143.c	2013-08-20 13:56:01.000000000 +0200
@@ -0,0 +1,49 @@
+/* PR tree-optimization/58143 */
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+
+int a, b, c, d, e, f, g, h, i;
+
+int foo ()
+{
+  return c < 0 && a < -2147483647 - 1 - c ? 0 : 1;
+}
+
+int *bar ()
+{
+  int j;
+  i = h ? 2 + h : 0;
+  for (j = 0; j < 1; j++)
+    for (d = 0; d; d++)
+      for (e = 1; e;)
+	return 0;
+  return 0;
+}
+
+int baz ()
+{
+  for (; b >= 0; b--)
+    for (c = 1; c >= 0; c--)
+      {
+	for (;;)
+	  {
+	    for (f = 0; f < 2; f++)
+	      {
+		g = foo ();
+		bar ();
+	      }
+	    if (c)
+	      break;
+	    return 0;
+	  }
+      }
+  return 0;
+}
+
+int main ()
+{
+  baz ();
+  if (b != 0)
+    __builtin_abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.target/i386/pr53397-1.c	2012-10-10 17:31:27.000000000 +0200
+++ gcc/testsuite/gcc.target/i386/pr53397-1.c	2013-09-03 20:36:50.000000000 +0200
@@ -1,7 +1,7 @@
 /* Prefetching when the step is loop invariant.  */
 /* { dg-do compile } */
 /* { dg-require-effective-target sse2 } */
-/* { dg-options "-O3 -msse2 -fprefetch-loop-arrays -fdump-tree-aprefetch-details --param min-insn-to-prefetch-ratio=3 --param simultaneous-prefetches=10 -fdump-tree-aprefetch-details" } */
+/* { dg-options "-O3 -msse2 -fprefetch-loop-arrays -fwrapv --param min-insn-to-prefetch-ratio=3 --param simultaneous-prefetches=10 -fdump-tree-aprefetch-details" } */
 
 
 double data[16384];
--- gcc/testsuite/gcc.target/i386/pr53397-2.c	2012-10-10 17:31:27.000000000 +0200
+++ gcc/testsuite/gcc.target/i386/pr53397-2.c	2013-09-03 20:37:08.000000000 +0200
@@ -1,7 +1,7 @@
 /* Not prefetching when the step is loop variant.  */
 /* { dg-do compile } */
 /* { dg-require-effective-target sse2 } */
-/* { dg-options "-O3 -msse2 -fprefetch-loop-arrays -fdump-tree-aprefetch-details --param min-insn-to-prefetch-ratio=3 --param simultaneous-prefetches=10 -fdump-tree-aprefetch-details" } */
+/* { dg-options "-O3 -msse2 -fprefetch-loop-arrays -fwrapv --param min-insn-to-prefetch-ratio=3 --param simultaneous-prefetches=10 -fdump-tree-aprefetch-details" } */
 
 double data[16384];
 void donot_prefetch_when_non_constant_step_is_variant(int step, int n)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PING] [PATCH] PR58143/58227 wrong code at -O3
  2013-09-04 16:45       ` Bernd Edlinger
@ 2013-09-16  8:27         ` Bernd Edlinger
  2013-10-06 12:22           ` Bernd Edlinger
  0 siblings, 1 reply; 9+ messages in thread
From: Bernd Edlinger @ 2013-09-16  8:27 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

ping...

On Wed, 4 Sep 2013 18:45:39, Bernd Edlinger wrote:
>
> On Tue, 3 Sep 2013 12:31:50, Richard Biener wrote:
>> On Fri, Aug 30, 2013 at 6:43 PM, Bernd Edlinger
>> <bernd.edlinger@hotmail.de> wrote:
>>> Now I think this is good opportunity for a simple heuristic:
>>>
>>> If a statement is at loop level 1 we can move it out of the loop,
>>> regardless of the fact, that it may invoke undefined behavior, because if it is
>>> moved then out of any loops, and thus it cannot be an induction variable and
>>> cause problems with aggressive loop optimizations later.
>>
>> VRP can still cause wrong-code issues (it's probably hard to generate a
>> testcase though). Also a less conservative check would be to see
>> whether we hoist _into_ loop level 0 (though we cannot check that at
>> the point where you placed the check).
>
> Well, then I should better revert this heuristic again.
>
>>> Only statements with possible undefined behavior in nested loops can become
>>> induction variable if lim moves them from one loop into an outer loop.
>>>
>>> Therefore with extremely much luck the test case will pass unmodified.
>>> I tried it, and the patch passes bootstrap and causes zero regressions
>>> with this heuristic.
>>>
>>> Ok for trunk now?
>>
>> Jakub mentioned another possibility - make sure the moved expression
>> does not invoke undefined behavior by computing in an unsigned type.
>
> That is a possibility, but on the other hand, that would obscure the undefined
> behavior and thus prevent other possible optimizations later.
>
> Another possibility would be to move the statement together with the
> enclosing if-statement, thus really preserving the execution.
>
>> That said, for the sake of backporting we need a patch as simple as
>> possible - so it would be interesting to see whether the patch without
>> the loop 1 heuristic has any effect on say SPEC CPU 2006 performance.
>
> I do not have access to that test, but on the dhrystone benchmark this patch
> has no influence whatsoever.
>
> Attached you'll find the latest version of my patch without the heuristic.
> Bootstrapped on i686-pc-linux-gnu and regression tested again.
>
> Ok for trunk and 4.8 branch? 		 	   		  

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PING] [PATCH] PR58143/58227 wrong code at -O3
  2013-09-16  8:27         ` [PING] " Bernd Edlinger
@ 2013-10-06 12:22           ` Bernd Edlinger
  2013-10-15  9:18             ` Richard Biener
  0 siblings, 1 reply; 9+ messages in thread
From: Bernd Edlinger @ 2013-10-06 12:22 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

Ping!


How I should proceed with this patch, is it OK?

The latest version was posted at: http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00234.html

Thanks,
Bernd.

>
> ping...
>
> On Wed, 4 Sep 2013 18:45:39, Bernd Edlinger wrote:
>>
>> On Tue, 3 Sep 2013 12:31:50, Richard Biener wrote:
>>> On Fri, Aug 30, 2013 at 6:43 PM, Bernd Edlinger
>>> <bernd.edlinger@hotmail.de> wrote:
>>>> Now I think this is good opportunity for a simple heuristic:
>>>>
>>>> If a statement is at loop level 1 we can move it out of the loop,
>>>> regardless of the fact, that it may invoke undefined behavior, because if it is
>>>> moved then out of any loops, and thus it cannot be an induction variable and
>>>> cause problems with aggressive loop optimizations later.
>>>
>>> VRP can still cause wrong-code issues (it's probably hard to generate a
>>> testcase though). Also a less conservative check would be to see
>>> whether we hoist _into_ loop level 0 (though we cannot check that at
>>> the point where you placed the check).
>>
>> Well, then I should better revert this heuristic again.
>>
>>>> Only statements with possible undefined behavior in nested loops can become
>>>> induction variable if lim moves them from one loop into an outer loop.
>>>>
>>>> Therefore with extremely much luck the test case will pass unmodified.
>>>> I tried it, and the patch passes bootstrap and causes zero regressions
>>>> with this heuristic.
>>>>
>>>> Ok for trunk now?
>>>
>>> Jakub mentioned another possibility - make sure the moved expression
>>> does not invoke undefined behavior by computing in an unsigned type.
>>
>> That is a possibility, but on the other hand, that would obscure the undefined
>> behavior and thus prevent other possible optimizations later.
>>
>> Another possibility would be to move the statement together with the
>> enclosing if-statement, thus really preserving the execution.
>>
>>> That said, for the sake of backporting we need a patch as simple as
>>> possible - so it would be interesting to see whether the patch without
>>> the loop 1 heuristic has any effect on say SPEC CPU 2006 performance.
>>
>> I do not have access to that test, but on the dhrystone benchmark this patch
>> has no influence whatsoever.
>>
>> Attached you'll find the latest version of my patch without the heuristic.
>> Bootstrapped on i686-pc-linux-gnu and regression tested again.
>>
>> Ok for trunk and 4.8 branch? 		 	   		  

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PING] [PATCH] PR58143/58227 wrong code at -O3
  2013-10-06 12:22           ` Bernd Edlinger
@ 2013-10-15  9:18             ` Richard Biener
  2013-10-16 12:48               ` Michael Matz
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Biener @ 2013-10-15  9:18 UTC (permalink / raw)
  To: Bernd Edlinger; +Cc: gcc-patches

On Sun, Oct 6, 2013 at 2:22 PM, Bernd Edlinger
<bernd.edlinger@hotmail.de> wrote:
> Ping!
>
>
> How I should proceed with this patch, is it OK?
>
> The latest version was posted at: http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00234.html

I have now attached a quick draft of a patch that rewrites the moved stmts
to not exhibit possibly undefined signed overflow.

Richard.

> Thanks,
> Bernd.
>
>>
>> ping...
>>
>> On Wed, 4 Sep 2013 18:45:39, Bernd Edlinger wrote:
>>>
>>> On Tue, 3 Sep 2013 12:31:50, Richard Biener wrote:
>>>> On Fri, Aug 30, 2013 at 6:43 PM, Bernd Edlinger
>>>> <bernd.edlinger@hotmail.de> wrote:
>>>>> Now I think this is good opportunity for a simple heuristic:
>>>>>
>>>>> If a statement is at loop level 1 we can move it out of the loop,
>>>>> regardless of the fact, that it may invoke undefined behavior, because if it is
>>>>> moved then out of any loops, and thus it cannot be an induction variable and
>>>>> cause problems with aggressive loop optimizations later.
>>>>
>>>> VRP can still cause wrong-code issues (it's probably hard to generate a
>>>> testcase though). Also a less conservative check would be to see
>>>> whether we hoist _into_ loop level 0 (though we cannot check that at
>>>> the point where you placed the check).
>>>
>>> Well, then I should better revert this heuristic again.
>>>
>>>>> Only statements with possible undefined behavior in nested loops can become
>>>>> induction variable if lim moves them from one loop into an outer loop.
>>>>>
>>>>> Therefore with extremely much luck the test case will pass unmodified.
>>>>> I tried it, and the patch passes bootstrap and causes zero regressions
>>>>> with this heuristic.
>>>>>
>>>>> Ok for trunk now?
>>>>
>>>> Jakub mentioned another possibility - make sure the moved expression
>>>> does not invoke undefined behavior by computing in an unsigned type.
>>>
>>> That is a possibility, but on the other hand, that would obscure the undefined
>>> behavior and thus prevent other possible optimizations later.
>>>
>>> Another possibility would be to move the statement together with the
>>> enclosing if-statement, thus really preserving the execution.
>>>
>>>> That said, for the sake of backporting we need a patch as simple as
>>>> possible - so it would be interesting to see whether the patch without
>>>> the loop 1 heuristic has any effect on say SPEC CPU 2006 performance.
>>>
>>> I do not have access to that test, but on the dhrystone benchmark this patch
>>> has no influence whatsoever.
>>>
>>> Attached you'll find the latest version of my patch without the heuristic.
>>> Bootstrapped on i686-pc-linux-gnu and regression tested again.
>>>
>>> Ok for trunk and 4.8 branch?

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PING] [PATCH] PR58143/58227 wrong code at -O3
  2013-10-15  9:18             ` Richard Biener
@ 2013-10-16 12:48               ` Michael Matz
  0 siblings, 0 replies; 9+ messages in thread
From: Michael Matz @ 2013-10-16 12:48 UTC (permalink / raw)
  To: Richard Biener; +Cc: Bernd Edlinger, gcc-patches

Hi,

On Tue, 15 Oct 2013, Richard Biener wrote:

> On Sun, Oct 6, 2013 at 2:22 PM, Bernd Edlinger
> <bernd.edlinger@hotmail.de> wrote:
> > How I should proceed with this patch, is it OK?
> >
> > The latest version was posted at: http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00234.html
> 
> I have now attached a quick draft of a patch that rewrites the moved stmts

No, you haven't :)


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-10-16 12:31 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-28 21:28 [PATCH] PR58143/58227 wrong code at -O3 Bernd Edlinger
2013-08-29 10:04 ` Richard Biener
2013-08-30 16:50   ` Bernd Edlinger
2013-09-03 10:31     ` Richard Biener
2013-09-04 16:45       ` Bernd Edlinger
2013-09-16  8:27         ` [PING] " Bernd Edlinger
2013-10-06 12:22           ` Bernd Edlinger
2013-10-15  9:18             ` Richard Biener
2013-10-16 12:48               ` Michael Matz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).