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.

Bootstrapped and tested on x86_64-linux, and reportedly fixes the problem on ppc, ok?


Bernd
	PR rtl-optimization/78626
	* 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
	* gcc.dg/torture/pr78626.c: New test.

Index: gcc/cprop.c
===================================================================
--- gcc/cprop.c	(revision 243310)
+++ 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)
 	{
+	  rtx_insn *first_uncond_trap = NULL;
+	  rtx_insn *insn;
+
 	  /* Reset tables used to keep track of what's still valid [since
 	     the start of the block].  */
 	  reset_opr_set_tables ();
@@ -1825,11 +1828,26 @@ one_cprop_pass (void)
 		       insn into a NOTE, or deleted the insn.  */
 		if (! NOTE_P (insn) && ! insn->deleted ())
 		  mark_oprs_set (insn);
+
+		if (first_uncond_trap == NULL
+		    && GET_CODE (PATTERN (insn)) == TRAP_IF
+		    && XEXP (PATTERN (insn), 0) == const1_rtx)
+		  first_uncond_trap = insn;
 	      }
+	  if (first_uncond_trap != NULL && first_uncond_trap != BB_END (bb))
+	    uncond_traps.safe_push (first_uncond_trap);
 	}
 
       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;
+    }
+}

Reply via email to