diff mbox

[RTL-ifcvt] PR rtl-optimization/68506: Fix emitting order of insns in IF-THEN-JOIN case

Message ID 5658261A.1030201@arm.com
State Accepted
Commit 14af28ba5aa467556c30cf20a8ee27e83590314f
Headers show

Commit Message

Kyrylo Tkachov Nov. 27, 2015, 9:44 a.m. UTC
On 26/11/15 16:54, Kyrill Tkachov wrote:
>

> On 26/11/15 16:49, Bernd Schmidt wrote:

>> On 11/26/2015 05:45 PM, Kyrill Tkachov wrote:

>>>          that doesn't help, punt.  */

>>>

>>> -  modified_in_a = emit_a != NULL_RTX && modified_in_p (orig_b, emit_a);

>>>     if (tmp_b && then_bb)

>>>       {

>> These bits I thought would be part of a followup patch (which would also guard against single_set problems), and as I mentioned I'd rather have a checking assert.

> Yes, you're right. I have the checking_assert statement in the followup that I've been testing.

> I'll move the deletion of these two statements there as well to minimise the changes to this patch.

>

> I'll move these bits to that patch, re-build cc1 and commit.

>


Here it is.
I'm committing this to trunk.

Thanks,
Kyrill

2015-11-26  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     PR rtl-optimization/68506
     * ifcvt.c (noce_try_cmove_arith): Try emitting the else basic block
     first if emit_a exists or then_bb modifies 'b'.  Reindent if-else
     blocks.

2015-11-26  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     PR rtl-optimization/68506
     * gcc.c-torture/execute/pr68506.c: New test.

> Thanks for your guidance,

> Kyrill

>

>> So take these deletions out and leave them for the followup, and the patch is ok everywhere. No need for a full retest given that practically the same patch has been tested already, just make sure you can build cc1.

>>

>>

>> Bernd

>>

>

Comments

Kyrylo Tkachov Nov. 27, 2015, 2:33 p.m. UTC | #1
On 27/11/15 14:09, Richard Biener wrote:
> On Fri, Nov 27, 2015 at 10:44 AM, Kyrill Tkachov <kyrylo.tkachov@arm.com> wrote:

>> On 26/11/15 16:54, Kyrill Tkachov wrote:

>>>

>>> On 26/11/15 16:49, Bernd Schmidt wrote:

>>>> On 11/26/2015 05:45 PM, Kyrill Tkachov wrote:

>>>>>           that doesn't help, punt.  */

>>>>>

>>>>> -  modified_in_a = emit_a != NULL_RTX && modified_in_p (orig_b, emit_a);

>>>>>      if (tmp_b && then_bb)

>>>>>        {

>>>> These bits I thought would be part of a followup patch (which would also

>>>> guard against single_set problems), and as I mentioned I'd rather have a

>>>> checking assert.

>>> Yes, you're right. I have the checking_assert statement in the followup

>>> that I've been testing.

>>> I'll move the deletion of these two statements there as well to minimise

>>> the changes to this patch.

>>>

>>> I'll move these bits to that patch, re-build cc1 and commit.

>>>

>> Here it is.

>> I'm committing this to trunk.

> I think this causes

>

> FAIL: gcc.c-torture/execute/20050124-1.c   -O2  (internal compiler error)

> FAIL: gcc.c-torture/execute/20050124-1.c   -O2  (test for excess errors)

> WARNING: gcc.c-torture/execute/20050124-1.c   -O2  compilation failed to produce

>   executable

> FAIL: gcc.c-torture/execute/20050124-1.c   -O2 -flto -fno-use-linker-plugin -flt

> o-partition=none  (internal compiler error)

> FAIL: gcc.c-torture/execute/20050124-1.c   -O2 -flto -fno-use-linker-plugin -flt

> o-partition=none  (test for excess errors)

> ....


Sorry for that.
That is caused not by this patch but rather by the followup
https://gcc.gnu.org/ml/gcc-patches/2015-11/msg03327.html

The checking assert fails:
gcc_checking_assert (!emit_a || !modified_in_p (orig_b, emit_a));
emit_a is:
(parallel [
         (set (reg:SI 93)
             (plus:SI (reg/v:SI 88 [ i ])
                 (const_int 2 [0x2])))
         (clobber (reg:CC 17 flags))
     ])

and and orig_b is:
(if_then_else:SI (eq (reg:CC 17 flags)
         (const_int 0 [0]))
     (reg/v:SI 87 [ <retval> ])
     (reg/v:SI 88 [ i ]))

So I think our assumption that this case would never trigger by this point doesn't hold
due to the CC reg clobber.
So the code before that patch was probably correct.
I think we should revert https://gcc.gnu.org/ml/gcc-patches/2015-11/msg03327.html then.

Kyrill

> /space/rguenther/src/svn/trunk2/gcc/testsuite/gcc.c-torture/execute/20050124-1.c:19:1:

> internal compiler error: in noce_try_cmove_arith, at ifcvt.c:2180^M

> 0x11f919d noce_try_cmove_arith^M

>          /space/rguenther/src/svn/trunk2/gcc/ifcvt.c:2180^M

> 0x11fb93f noce_process_if_block^M

>          /space/rguenther/src/svn/trunk2/gcc/ifcvt.c:3525^M

> 0x11fdd0e noce_find_if_block^M

>          /space/rguenther/src/svn/trunk2/gcc/ifcvt.c:3974^M

> 0x11fdd0e find_if_header^M

>          /space/rguenther/src/svn/trunk2/gcc/ifcvt.c:4179^M

> 0x11fdd0e if_convert^M

>          /space/rguenther/src/svn/trunk2/gcc/ifcvt.c:5326^M

> 0x11ff32d execute^M

>

>

> on x86_64 with -m64 and -m32.

>

> Richard.

>

>> Thanks,

>> Kyrill

>>

>> 2015-11-26  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

>>

>>      PR rtl-optimization/68506

>>      * ifcvt.c (noce_try_cmove_arith): Try emitting the else basic block

>>      first if emit_a exists or then_bb modifies 'b'.  Reindent if-else

>>      blocks.

>>

>> 2015-11-26  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

>>

>>      PR rtl-optimization/68506

>>      * gcc.c-torture/execute/pr68506.c: New test.

>>

>>> Thanks for your guidance,

>>> Kyrill

>>>

>>>> So take these deletions out and leave them for the followup, and the

>>>> patch is ok everywhere. No need for a full retest given that practically the

>>>> same patch has been tested already, just make sure you can build cc1.

>>>>

>>>>

>>>> Bernd

>>>>
Kyrylo Tkachov Nov. 27, 2015, 2:41 p.m. UTC | #2
On 27/11/15 14:35, Bernd Schmidt wrote:
> On 11/27/2015 03:33 PM, Kyrill Tkachov wrote:

>> Sorry for that.

>> That is caused not by this patch but rather by the followup

>> https://gcc.gnu.org/ml/gcc-patches/2015-11/msg03327.html

>>

>> The checking assert fails:

>> gcc_checking_assert (!emit_a || !modified_in_p (orig_b, emit_a));

>> emit_a is:

>> (parallel [

>>          (set (reg:SI 93)

>>              (plus:SI (reg/v:SI 88 [ i ])

>>                  (const_int 2 [0x2])))

>>          (clobber (reg:CC 17 flags))

>>      ])

>>

>> and and orig_b is:

>> (if_then_else:SI (eq (reg:CC 17 flags)

>>          (const_int 0 [0]))

>>      (reg/v:SI 87 [ <retval> ])

>>      (reg/v:SI 88 [ i ]))

>>

>> So I think our assumption that this case would never trigger by this

>> point doesn't hold

>> due to the CC reg clobber.

>> So the code before that patch was probably correct.

>> I think we should revert

>> https://gcc.gnu.org/ml/gcc-patches/2015-11/msg03327.html then.

>

> Yes. Sorry. I thought orig_b would hold "normal" objects and not such an if-then-else.

>


Reverted with r231019.
Sorry for not catching it myself earlier.

Kyrill

>

> Bernd

>
diff mbox

Patch

commit ba7633ec30e8e25d7dc1975893bf56eadf223404
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Date:   Tue Nov 24 11:49:30 2015 +0000

    PR rtl-optimization/68506: Fix emitting order of insns in IF-THEN-JOIN case

diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index af7a3b9..3ce9fe6 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -2220,40 +2220,38 @@  noce_try_cmove_arith (struct noce_if_info *if_info)
 	  }
 
     }
-    if (emit_a && modified_in_a)
-      {
-	modified_in_b = emit_b != NULL_RTX && modified_in_p (orig_a, emit_b);
-	if (tmp_b && else_bb)
-	  {
-	    FOR_BB_INSNS (else_bb, tmp_insn)
-	    /* Don't check inside insn_b.  We will have changed it to emit_b
-	       with a destination that doesn't conflict.  */
-	      if (!(insn_b && tmp_insn == insn_b)
-		  && modified_in_p (orig_a, tmp_insn))
-		{
-		  modified_in_b = true;
-		  break;
-		}
-
-	  }
-	if (modified_in_b)
-	  goto end_seq_and_fail;
-
-	if (!noce_emit_bb (emit_b, else_bb, b_simple))
-	  goto end_seq_and_fail;
+  if (emit_a || modified_in_a)
+    {
+      modified_in_b = emit_b != NULL_RTX && modified_in_p (orig_a, emit_b);
+      if (tmp_b && else_bb)
+	{
+	  FOR_BB_INSNS (else_bb, tmp_insn)
+	  /* Don't check inside insn_b.  We will have changed it to emit_b
+	     with a destination that doesn't conflict.  */
+	  if (!(insn_b && tmp_insn == insn_b)
+	      && modified_in_p (orig_a, tmp_insn))
+	    {
+	      modified_in_b = true;
+	      break;
+	    }
+	}
+      if (modified_in_b)
+	goto end_seq_and_fail;
 
-	if (!noce_emit_bb (emit_a, then_bb, a_simple))
-	  goto end_seq_and_fail;
-      }
-    else
-      {
-	if (!noce_emit_bb (emit_a, then_bb, a_simple))
-	  goto end_seq_and_fail;
+      if (!noce_emit_bb (emit_b, else_bb, b_simple))
+	goto end_seq_and_fail;
 
-	if (!noce_emit_bb (emit_b, else_bb, b_simple))
-	  goto end_seq_and_fail;
+      if (!noce_emit_bb (emit_a, then_bb, a_simple))
+	goto end_seq_and_fail;
+    }
+  else
+    {
+      if (!noce_emit_bb (emit_a, then_bb, a_simple))
+	goto end_seq_and_fail;
 
-      }
+      if (!noce_emit_bb (emit_b, else_bb, b_simple))
+	goto end_seq_and_fail;
+    }
 
   target = noce_emit_cmove (if_info, x, code, XEXP (if_info->cond, 0),
 			    XEXP (if_info->cond, 1), a, b);
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr68506.c b/gcc/testsuite/gcc.c-torture/execute/pr68506.c
new file mode 100644
index 0000000..15984ed
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr68506.c
@@ -0,0 +1,63 @@ 
+/* { dg-options "-fno-builtin-abort" } */
+
+int a, b, m, n, o, p, s, u, i;
+char c, q, y;
+short d;
+unsigned char e;
+static int f, h;
+static short g, r, v;
+unsigned t;
+
+extern void abort ();
+
+int
+fn1 (int p1)
+{
+  return a ? p1 : p1 + a;
+}
+
+unsigned char
+fn2 (unsigned char p1, int p2)
+{
+  return p2 >= 2 ? p1 : p1 >> p2;
+}
+
+static short
+fn3 ()
+{
+  int w, x = 0;
+  for (; p < 31; p++)
+    {
+      s = fn1 (c | ((1 && c) == c));
+      t = fn2 (s, x);
+      c = (unsigned) c > -(unsigned) ((o = (m = d = t) == p) <= 4UL) && n;
+      v = -c;
+      y = 1;
+      for (; y; y++)
+	e = v == 1;
+      d = 0;
+      for (; h != 2;)
+	{
+	  for (;;)
+	    {
+	      if (!m)
+		abort ();
+	      r = 7 - f;
+	      x = e = i | r;
+	      q = u * g;
+	      w = b == q;
+	      if (w)
+		break;
+	    }
+	  break;
+	}
+    }
+  return x;
+}
+
+int
+main ()
+{
+  fn3 ();
+  return 0;
+}