re PR rtl-optimization/63917 (r217646 caused many failures)
authorZhenqiang Chen <zhenqiang.chen@arm.com>
Fri, 12 Dec 2014 05:51:19 +0000 (05:51 +0000)
committerZhenqiang Chen <zqchen@gcc.gnu.org>
Fri, 12 Dec 2014 05:51:19 +0000 (05:51 +0000)
2014-12-12  Zhenqiang Chen  <zhenqiang.chen@arm.com>

PR rtl-optimization/63917
* ifcvt.c (cc_in_cond): New function.
(end_ifcvt_sequence): Make sure new generated insns do not clobber CC.
(noce_process_if_block, check_cond_move_block): Check CC references.

testsuite/ChangeLog:
2014-12-12  Zhenqiang Chen  <zhenqiang.chen@arm.com>

* gcc.dg/pr64007.c: New test.

From-SVN: r218658

gcc/ChangeLog
gcc/ifcvt.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr64007.c [new file with mode: 0644]

index 7478b0f02b2d7ea9499fb7673b80b28bd0d15e4e..d9a4bded7c5ccbbd3b65ed283dbb1ed891627320 100644 (file)
@@ -1,3 +1,10 @@
+2014-12-12  Zhenqiang Chen  <zhenqiang.chen@arm.com>
+
+       PR rtl-optimization/63917
+       * ifcvt.c (cc_in_cond): New function.
+       (end_ifcvt_sequence): Make sure new generated insns do not clobber CC.
+       (noce_process_if_block, check_cond_move_block): Check CC references.
+
 2014-12-11  Andrew Pinski  <apinski@cavium.com>
 
        * config/aarch64/aarch64-protos.h (tune_params): Add align field.
index f7a922425823c4d931d9d6c77e3e8643addff7c0..f0159c18a88b5233a82112e73d50647adc816c71 100644 (file)
@@ -1016,6 +1016,18 @@ noce_emit_move_insn (rtx x, rtx y)
                   0, 0, outmode, y);
 }
 
+/* Return the CC reg if it is used in COND.  */
+
+static rtx
+cc_in_cond (rtx cond)
+{
+  if (HAVE_cbranchcc4 && cond
+      && GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_CC)
+    return XEXP (cond, 0);
+
+  return NULL_RTX;
+}
+
 /* Return sequence of instructions generated by if conversion.  This
    function calls end_sequence() to end the current stream, ensures
    that are instructions are unshared, recognizable non-jump insns.
@@ -1026,6 +1038,7 @@ end_ifcvt_sequence (struct noce_if_info *if_info)
 {
   rtx_insn *insn;
   rtx_insn *seq = get_insns ();
+  rtx cc = cc_in_cond (if_info->cond);
 
   set_used_flags (if_info->x);
   set_used_flags (if_info->cond);
@@ -1040,7 +1053,9 @@ end_ifcvt_sequence (struct noce_if_info *if_info)
      allows proper placement of required clobbers.  */
   for (insn = seq; insn; insn = NEXT_INSN (insn))
     if (JUMP_P (insn)
-       || recog_memoized (insn) == -1)
+       || recog_memoized (insn) == -1
+          /* Make sure new generated code does not clobber CC.  */
+       || (cc && set_of (cc, insn)))
       return NULL;
 
   return seq;
@@ -2544,6 +2559,7 @@ noce_process_if_block (struct noce_if_info *if_info)
   rtx_insn *insn_a, *insn_b;
   rtx set_a, set_b;
   rtx orig_x, x, a, b;
+  rtx cc;
 
   /* We're looking for patterns of the form
 
@@ -2655,6 +2671,13 @@ noce_process_if_block (struct noce_if_info *if_info)
   if_info->a = a;
   if_info->b = b;
 
+  /* Skip it if the instruction to be moved might clobber CC.  */
+  cc = cc_in_cond (cond);
+  if (cc
+      && (set_of (cc, insn_a)
+         || (insn_b && set_of (cc, insn_b))))
+    return FALSE;
+
   /* Try optimizations in some approximation of a useful order.  */
   /* ??? Should first look to see if X is live incoming at all.  If it
      isn't, we don't need anything but an unconditional set.  */
@@ -2811,6 +2834,7 @@ check_cond_move_block (basic_block bb,
                       rtx cond)
 {
   rtx_insn *insn;
+  rtx cc = cc_in_cond (cond);
 
    /* We can only handle simple jumps at the end of the basic block.
       It is almost impossible to update the CFG otherwise.  */
@@ -2868,6 +2892,10 @@ check_cond_move_block (basic_block bb,
          && modified_between_p (src, insn, NEXT_INSN (BB_END (bb))))
        return FALSE;
 
+      /* Skip it if the instruction to be moved might clobber CC.  */
+      if (cc && set_of (cc, insn))
+       return FALSE;
+
       vals->put (dest, src);
 
       regs->safe_push (dest);
index 1c06df09b106cf9ecf6ecf177f4abf493327db6b..fc4869fe2552270212ac135f8c08aa0f506b31cf 100644 (file)
@@ -1,3 +1,7 @@
+2014-12-12  Zhenqiang Chen  <zhenqiang.chen@arm.com>
+
+       * gcc.dg/pr64007.c: New test.
+
 2014-12-12  Bin Cheng  <bin.cheng@arm.com>
 
        * gcc.target/aarch64/ldp_stp_2.c: Make test less vulnerable.
diff --git a/gcc/testsuite/gcc.dg/pr64007.c b/gcc/testsuite/gcc.dg/pr64007.c
new file mode 100644 (file)
index 0000000..cb0e50f
--- /dev/null
@@ -0,0 +1,50 @@
+/* { dg-options " -O3 " } */
+/* { dg-do run } */
+
+#include <assert.h>
+
+int d, i;
+
+struct S
+{
+  int f0;
+} *b, c, e, h, **g = &b;
+
+static struct S *f = &e;
+
+int
+fn1 (int p)
+{
+  int a = 0;
+  return a || p < 0 || p >= 2 || 1 >> p;
+}
+
+int
+main ()
+{
+  int k = 1, l, *m = &c.f0;
+
+  for (;;)
+    {
+      l = fn1 (i);
+      *m = k && i;
+      if (l)
+       {
+         int n[1] = {0};
+       }
+      break;
+    }
+
+  *g = &h;
+
+  assert (b);
+
+  if (d)
+    (*m)--;
+  d = (f != 0) | (i >= 0);
+
+  if (c.f0 != 0)
+    __builtin_abort ();
+
+  return 0;
+}