]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR rtl-optimization/78626
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 14 Jan 2017 16:52:18 +0000 (16:52 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 14 Jan 2017 16:52:18 +0000 (16:52 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@244467 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cprop.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr78626.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr78727.c [new file with mode: 0644]

index 910605368d34862d6b482372290e3e26d4fbe8d4..746f6af65cec204b2fbbe2d7f4188089588c5486 100644 (file)
@@ -1,3 +1,10 @@
+2017-01-14  Bernd Schmidt  <bschmidt@redhat.com>
+
+       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.
+
 2017-01-14  Alan Modra  <amodra@gmail.com>
 
        PR target/72749
index b210e944f8439c257ed8e0bfe495443ca961bdf0..b6c2bc431fd77a59c3f8cae6be495b8626581b0d 100644 (file)
@@ -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 70ccd17ba7205f4c60a7705db26fa8fad5df54aa..625c99a7d22222cce936964aebd74656cde8fb54 100644 (file)
@@ -1,3 +1,10 @@
+2017-01-14  Bernd Schmidt  <bschmidt@redhat.com>
+
+        PR rtl-optimization/78626
+        PR rtl-optimization/78727
+       * gcc.dg/torture/pr78626.c: New test.
+       * gcc.dg/torture/pr78727.c: New test.
+
 2017-01-14  Alan Modra  <amodra@gmail.com>
 
        * gcc.c-torture/compile/pr72749.c: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/pr78626.c b/gcc/testsuite/gcc.dg/torture/pr78626.c
new file mode 100644 (file)
index 0000000..ed4775a
--- /dev/null
@@ -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;
+    }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr78727.c b/gcc/testsuite/gcc.dg/torture/pr78727.c
new file mode 100644 (file)
index 0000000..93cc3d7
--- /dev/null
@@ -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;
+}