re PR rtl-optimization/58662 (wrong code at -O2 for dumb condition)
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Sun, 13 Oct 2013 13:29:28 +0000 (13:29 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sun, 13 Oct 2013 13:29:28 +0000 (13:29 +0000)
PR rtl-optimization/58662
* combine.c (try_combine): Take into account death nodes on I2 when
splitting a PARALLEL of two independent SETs.  Fix dump message.

From-SVN: r203498

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr58662.c [new file with mode: 0644]

index 5ad86db2457c5fe9426d54af9585d3f39ca2d897..2f0bfcec36393fe7876726a5ea817a18b7429c81 100644 (file)
@@ -1,3 +1,9 @@
+2013-10-13  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR rtl-optimization/58662
+       * combine.c (try_combine): Take into account death nodes on I2 when
+       splitting a PARALLEL of two independent SETs.  Fix dump message.
+
 2013-10-12  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/51244
index fcf60cd08aa5971bd92af83c8f382b4f4fd91985..13f5e29e3d616c5a601ca24574631c87be83bc9d 100644 (file)
@@ -3693,29 +3693,42 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p,
           && ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0)))
                 && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1)))))
     {
+      rtx set0 = XVECEXP (newpat, 0, 0);
+      rtx set1 = XVECEXP (newpat, 0, 1);
+
       /* Normally, it doesn't matter which of the two is done first,
         but the one that references cc0 can't be the second, and
         one which uses any regs/memory set in between i2 and i3 can't
-        be first.  */
-      if (!use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)),
-                             DF_INSN_LUID (i2))
+        be first.  The PARALLEL might also have been pre-existing in i3,
+        so we need to make sure that we won't wrongly hoist a SET to i2
+        that would conflict with a death note present in there.  */
+      if (!use_crosses_set_p (SET_SRC (set1), DF_INSN_LUID (i2))
+         && !(REG_P (SET_DEST (set1))
+              && find_reg_note (i2, REG_DEAD, SET_DEST (set1)))
+         && !(GET_CODE (SET_DEST (set1)) == SUBREG
+              && find_reg_note (i2, REG_DEAD,
+                                SUBREG_REG (SET_DEST (set1))))
 #ifdef HAVE_cc0
-         && !reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0))
+         && !reg_referenced_p (cc0_rtx, set0)
 #endif
         )
        {
-         newi2pat = XVECEXP (newpat, 0, 1);
-         newpat = XVECEXP (newpat, 0, 0);
+         newi2pat = set1;
+         newpat = set0;
        }
-      else if (!use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 0)),
-                                  DF_INSN_LUID (i2))
+      else if (!use_crosses_set_p (SET_SRC (set0), DF_INSN_LUID (i2))
+              && !(REG_P (SET_DEST (set0))
+                   && find_reg_note (i2, REG_DEAD, SET_DEST (set0)))
+              && !(GET_CODE (SET_DEST (set0)) == SUBREG
+                   && find_reg_note (i2, REG_DEAD,
+                                     SUBREG_REG (SET_DEST (set0))))
 #ifdef HAVE_cc0
-              && !reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 1))
+              && !reg_referenced_p (cc0_rtx, set1)
 #endif
              )
        {
-         newi2pat = XVECEXP (newpat, 0, 0);
-         newpat = XVECEXP (newpat, 0, 1);
+         newi2pat = set0;
+         newpat = set1;
        }
       else
        {
@@ -4261,9 +4274,8 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p,
       }
 
     /* Update reg_stat[].nonzero_bits et al for any changes that may have
-       been made to this insn.  The order of
-       set_nonzero_bits_and_sign_copies() is important.  Because newi2pat
-       can affect nonzero_bits of newpat */
+       been made to this insn.  The order is important, because newi2pat
+       can affect nonzero_bits of newpat.  */
     if (newi2pat)
       note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
     note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
@@ -4283,7 +4295,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p,
     {
       if (dump_file)
        {
-         fprintf (dump_file, "modifying insn i1 ");
+         fprintf (dump_file, "modifying insn i0 ");
          dump_insn_slim (dump_file, i0);
        }
       df_insn_rescan (i0);
@@ -4321,7 +4333,6 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p,
 
   /* Set new_direct_jump_p if a new return or simple jump instruction
      has been created.  Adjust the CFG accordingly.  */
-
   if (returnjump_p (i3) || any_uncondjump_p (i3))
     {
       *new_direct_jump_p = 1;
index 07e2d4ccdd49c5433de4775f23e1976bca46fd66..362186f2628defffc1aa04e1214e68531d5b9aee 100644 (file)
@@ -1,3 +1,7 @@
+2013-10-13  Richard Biener  <rguenther@suse.de>
+
+       * gcc.c-torture/execute/pr58662.c: New test.
+
 2013-10-12  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/51244
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58662.c b/gcc/testsuite/gcc.c-torture/execute/pr58662.c
new file mode 100644 (file)
index 0000000..dc0d5f0
--- /dev/null
@@ -0,0 +1,22 @@
+extern void abort (void);
+
+int a, c, d;
+volatile int b;
+
+static int
+foo (int p1, short p2)
+{
+  return p1 / p2;
+}
+
+int
+main ()
+{
+  char e;
+  d = foo (a == 0, (0, 35536)); 
+  e = d % 14;
+  b = e && c;
+  if (b != 0)
+    abort ();
+  return 0;
+}