diff mbox

cprop fix for PR78626

Message ID ebaed4a7-711a-e282-688d-94c054d15b25@redhat.com
State New
Headers show

Commit Message

Bernd Schmidt Dec. 14, 2016, 3:46 p.m. UTC
On 12/12/2016 03:21 PM, Bernd Schmidt wrote:
> On 12/10/2016 08:58 PM, Segher Boessenkool wrote:

>> On Thu, Dec 08, 2016 at 01:21:04PM +0100, Bernd Schmidt wrote:

>>> This is another case where an optimization turns a trap_if

>>> unconditional. We have to defer changing the CFG, since the rest of

>>> cprop seems to blow up when we modify things while scanning.

>

>> The problem for PR78727 is that we also need to do this for insns that

>> already are the last insn in the block:

>>

>>> +      while (!uncond_traps.is_empty ())

>>> +    {

>>> +      rtx_insn *insn = uncond_traps.pop ();

>>> +      basic_block to_split = BLOCK_FOR_INSN (insn);

>>> +      remove_edge (split_block (to_split, insn));

>>> +      emit_barrier_after_bb (to_split);

>>> +    }

>>

>> We need that barrier, and we also need the successor edges removed

>> (which split_block+remove_edge does).

>>

>> (PR78727 works fine with just that BB_END test deleted).

>

> Ah, ok. In that case I'll probably also add a test to make sure this is

> only done for insns that weren't an unconditional trap before. Retesting...


That would be this patch. Tested as before. The two new testcases seem 
to pass with a ppc cross (but I would appreciate if someone were to run 
full tests on ppc).


Bernd

Comments

Segher Boessenkool Dec. 14, 2016, 5:49 p.m. UTC | #1
On Wed, Dec 14, 2016 at 04:46:09PM +0100, Bernd Schmidt wrote:
> That would be this patch. Tested as before. The two new testcases seem 

> to pass with a ppc cross (but I would appreciate if someone were to run 

> full tests on ppc).


Thanks, will do.


Segher
Segher Boessenkool Dec. 15, 2016, 8:38 a.m. UTC | #2
On Wed, Dec 14, 2016 at 11:49:26AM -0600, Segher Boessenkool wrote:
> On Wed, Dec 14, 2016 at 04:46:09PM +0100, Bernd Schmidt wrote:

> > That would be this patch. Tested as before. The two new testcases seem 

> > to pass with a ppc cross (but I would appreciate if someone were to run 

> > full tests on ppc).

> 

> Thanks, will do.


Bootstrapped and regression checked on powerpc64-linux {-m32,-m64};
no new problems.


Segher
Jeff Law Jan. 14, 2017, 4:54 p.m. UTC | #3
On 12/14/2016 08:46 AM, Bernd Schmidt wrote:
> On 12/12/2016 03:21 PM, Bernd Schmidt wrote:

>> On 12/10/2016 08:58 PM, Segher Boessenkool wrote:

>>> On Thu, Dec 08, 2016 at 01:21:04PM +0100, Bernd Schmidt wrote:

>>>> This is another case where an optimization turns a trap_if

>>>> unconditional. We have to defer changing the CFG, since the rest of

>>>> cprop seems to blow up when we modify things while scanning.

>>

>>> The problem for PR78727 is that we also need to do this for insns that

>>> already are the last insn in the block:

>>>

>>>> +      while (!uncond_traps.is_empty ())

>>>> +    {

>>>> +      rtx_insn *insn = uncond_traps.pop ();

>>>> +      basic_block to_split = BLOCK_FOR_INSN (insn);

>>>> +      remove_edge (split_block (to_split, insn));

>>>> +      emit_barrier_after_bb (to_split);

>>>> +    }

>>>

>>> We need that barrier, and we also need the successor edges removed

>>> (which split_block+remove_edge does).

>>>

>>> (PR78727 works fine with just that BB_END test deleted).

>>

>> Ah, ok. In that case I'll probably also add a test to make sure this is

>> only done for insns that weren't an unconditional trap before.

>> Retesting...

>

> That would be this patch. Tested as before. The two new testcases seem

> to pass with a ppc cross (but I would appreciate if someone were to run

> full tests on ppc).

>

>

> Bernd

>

>

> cprop-v2.diff

>

>

> 	PR rtl-optimization/78626

> 	PR rtl-optimization/78727

> 	* cprop.c (one_cprop_pass): Collect unconditional traps in the middle

> 	of a block, and split such blocks after everything else is finished.

>

> 	PR rtl-optimization/78626

> 	PR rtl-optimization/78727

> 	* gcc.dg/torture/pr78626.c: New test.

> 	* gcc.dg/torture/pr78727.c: New test.

This is OK.  I also re-tested ppc64le-linux since it's been about 3 
weeks since this patch was submitted.

I went ahead and committed the patch since you're on PTO and it kills 
stuff on the regression hit list.

jeff
diff mbox

Patch

	PR rtl-optimization/78626
	PR rtl-optimization/78727
	* cprop.c (one_cprop_pass): Collect unconditional traps in the middle
	of a block, and split such blocks after everything else is finished.

	PR rtl-optimization/78626
	PR rtl-optimization/78727
	* gcc.dg/torture/pr78626.c: New test.
	* gcc.dg/torture/pr78727.c: New test.

Index: gcc/cprop.c
===================================================================
--- gcc/cprop.c	(revision 243548)
+++ gcc/cprop.c	(working copy)
@@ -1794,7 +1794,7 @@  one_cprop_pass (void)
   if (set_hash_table.n_elems > 0)
     {
       basic_block bb;
-      rtx_insn *insn;
+      auto_vec<rtx_insn *> uncond_traps;
 
       alloc_cprop_mem (last_basic_block_for_fn (cfun),
 		       set_hash_table.n_elems);
@@ -1810,6 +1810,9 @@  one_cprop_pass (void)
 		      EXIT_BLOCK_PTR_FOR_FN (cfun),
 		      next_bb)
 	{
+	  bool seen_uncond_trap = false;
+	  rtx_insn *insn;
+
 	  /* Reset tables used to keep track of what's still valid [since
 	     the start of the block].  */
 	  reset_opr_set_tables ();
@@ -1817,6 +1820,10 @@  one_cprop_pass (void)
 	  FOR_BB_INSNS (bb, insn)
 	    if (INSN_P (insn))
 	      {
+		bool was_uncond_trap
+		  = (GET_CODE (PATTERN (insn)) == TRAP_IF
+		     && XEXP (PATTERN (insn), 0) == const1_rtx);
+
 		changed |= cprop_insn (insn);
 
 		/* Keep track of everything modified by this insn.  */
@@ -1825,11 +1832,27 @@  one_cprop_pass (void)
 		       insn into a NOTE, or deleted the insn.  */
 		if (! NOTE_P (insn) && ! insn->deleted ())
 		  mark_oprs_set (insn);
+
+		if (!was_uncond_trap && !seen_uncond_trap
+		    && GET_CODE (PATTERN (insn)) == TRAP_IF
+		    && XEXP (PATTERN (insn), 0) == const1_rtx)
+		  {
+		    seen_uncond_trap = true;
+		    uncond_traps.safe_push (insn);
+		  }
 	      }
 	}
 
       changed |= bypass_conditional_jumps ();
 
+      while (!uncond_traps.is_empty ())
+	{
+	  rtx_insn *insn = uncond_traps.pop ();
+	  basic_block to_split = BLOCK_FOR_INSN (insn);
+	  remove_edge (split_block (to_split, insn));
+	  emit_barrier_after_bb (to_split);
+	}
+
       FREE_REG_SET (reg_set_bitmap);
       free_cprop_mem ();
     }
Index: gcc/testsuite/gcc.dg/torture/pr78626.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr78626.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr78626.c	(working copy)
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+
+int qs;
+
+void
+ms (int g1)
+{
+  int cy;
+  int *fr = &cy;
+
+  for (;;)
+    {
+      *fr = 1;
+      fr = &g1;
+
+      while (qs != 0)
+        {
+          if (qs | cy)
+            qs = g1 / 0; /* { dg-warning "division" } */
+          ++qs;
+        }
+
+      cy = 1;
+      while (cy != 0)
+        cy = 2;
+    }
+}
Index: gcc/testsuite/gcc.dg/torture/pr78727.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr78727.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr78727.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+
+int
+dd (int gj, unsigned int o7)
+{
+  long long int e8 = gj;
+
+  e8 |= gj + 1u;
+  if (e8 != 0)
+    {
+      short int *mn = (short int *)&e8;
+      int pv;
+
+      e8 &= e8 > gj;
+      gj = o7 > e8;
+      pv = ((gj != 0) ? gj : *mn) && e8;
+      gj |= *mn / pv;
+    }
+
+  return gj;
+}