This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: cprop fix for PR78626


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

	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;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]