[RTL-ifcvt] PR rtl-optimization/68624: Clean up logic that checks for clobbering...
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Thu, 3 Dec 2015 13:28:55 +0000 (13:28 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Thu, 3 Dec 2015 13:28:55 +0000 (13:28 +0000)
PR rtl-optimization/68624
* ifcvt.c (noce_try_cmove_arith): Check clobbers of temp regs in both
blocks if they exist and simplify the logic choosing the order to emit
them in.

* gcc.c-torture/execute/pr68624.c: New test.

From-SVN: r231226

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

index 65b1b2b62843a1595617ef1f03908a52ecda0b03..51778ecb9cf3b880df7c44fd829024c7ab01385a 100644 (file)
@@ -1,3 +1,10 @@
+2015-12-03  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       PR rtl-optimization/68624
+       * ifcvt.c (noce_try_cmove_arith): Check clobbers of temp regs in both
+       blocks if they exist and simplify the logic choosing the order to emit
+       them in.
+
 2015-12-03  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/66051
index 8ece8734338c38881254c0fe6f71659f807719d3..d474b3ba493aca4a86521c936f3cd86f0f368acf 100644 (file)
@@ -2172,10 +2172,6 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
        }
     }
 
-    /* If insn to set up A clobbers any registers B depends on, try to
-       swap insn that sets up A with the one that sets up B.  If even
-       that doesn't help, punt.  */
-
   modified_in_a = emit_a != NULL_RTX && modified_in_p (orig_b, emit_a);
   if (tmp_b && then_bb)
     {
@@ -2190,31 +2186,33 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
          }
 
     }
-  if (emit_a || modified_in_a)
+
+  modified_in_b = emit_b != NULL_RTX && modified_in_p (orig_a, emit_b);
+  if (tmp_a && else_bb)
     {
-      modified_in_b = emit_b != NULL_RTX && modified_in_p (orig_a, emit_b);
-      if (tmp_b && else_bb)
+      FOR_BB_INSNS (else_bb, tmp_insn)
+      /* Don't check inside insn_b.  We will have changed it to emit_b
+        with a destination that doesn't conflict.  */
+      if (!(insn_b && tmp_insn == insn_b)
+         && modified_in_p (orig_a, tmp_insn))
        {
-         FOR_BB_INSNS (else_bb, tmp_insn)
-         /* Don't check inside insn_b.  We will have changed it to emit_b
-            with a destination that doesn't conflict.  */
-         if (!(insn_b && tmp_insn == insn_b)
-             && modified_in_p (orig_a, tmp_insn))
-           {
-             modified_in_b = true;
-             break;
-           }
+         modified_in_b = true;
+         break;
        }
-      if (modified_in_b)
-       goto end_seq_and_fail;
+    }
 
+  /* If insn to set up A clobbers any registers B depends on, try to
+     swap insn that sets up A with the one that sets up B.  If even
+     that doesn't help, punt.  */
+  if (modified_in_a && !modified_in_b)
+    {
       if (!noce_emit_bb (emit_b, else_bb, b_simple))
        goto end_seq_and_fail;
 
       if (!noce_emit_bb (emit_a, then_bb, a_simple))
        goto end_seq_and_fail;
     }
-  else
+  else if (!modified_in_a)
     {
       if (!noce_emit_bb (emit_a, then_bb, a_simple))
        goto end_seq_and_fail;
@@ -2222,6 +2220,8 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
       if (!noce_emit_bb (emit_b, else_bb, b_simple))
        goto end_seq_and_fail;
     }
+  else
+    goto end_seq_and_fail;
 
   target = noce_emit_cmove (if_info, x, code, XEXP (if_info->cond, 0),
                            XEXP (if_info->cond, 1), a, b);
index 55529e05720fd2855cb50117f32904eb0205c374..3417f36f6ade8d6c522e81f1fe7f4ab764f7ada2 100644 (file)
@@ -1,3 +1,8 @@
+2015-12-03  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       PR rtl-optimization/68624
+       * gcc.c-torture/execute/pr68624.c: New test.
+
 2015-12-03  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/66051
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr68624.c b/gcc/testsuite/gcc.c-torture/execute/pr68624.c
new file mode 100644 (file)
index 0000000..abb716b
--- /dev/null
@@ -0,0 +1,30 @@
+int b, c, d, e = 1, f, g, h, j;
+
+static int
+fn1 ()
+{
+  int a = c;
+  if (h)
+    return 9;
+  g = (c || b) % e;
+  if ((g || f) && b)
+    return 9;
+  e = d;
+  for (c = 0; c > -4; c--)
+    ;
+  if (d)
+    c--;
+  j = c;
+  return d;
+}
+
+int
+main ()
+{
+  fn1 ();
+
+  if (c != -4)
+    __builtin_abort ();
+
+  return 0;
+}