gcc/
authoryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 7 Apr 2015 13:24:05 +0000 (13:24 +0000)
committeryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 7 Apr 2015 13:24:05 +0000 (13:24 +0000)
2015-04-07  Yvan Roux  <yvan.roux@linaro.org>

Backport from trunk r217062, r217646, r218658.
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-11-17  Zhenqiang Chen  <zhenqiang.chen@arm.com>

* ifcvt.c (HAVE_cbranchcc4): Define.
(noce_emit_cmove, noce_get_alt_condition, noce_get_condition):
Use HAVE_cbranchcc4.

2014-11-04  Zhenqiang Chen  <zhenqiang.chen@arm.com>

Revert:
2014-11-03  Zhenqiang Chen  <zhenqiang.chen@arm.com>
* ifcvt.c (noce_emit_cmove, noce_get_alt_condition, noce_get_condition):
Allow CC mode if HAVE_cbranchcc4.

gcc/testsuite/
2015-04-07  Yvan Roux  <yvan.roux@linaro.org>

Backport from trunk r218658.
2014-12-12  Zhenqiang Chen  <zhenqiang.chen@arm.com>

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

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@221894 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 398ac8c..499068a 100644 (file)
@@ -1,3 +1,26 @@
+2015-04-07  Yvan Roux  <yvan.roux@linaro.org>
+
+       Backport from trunk r217062, r217646, r218658.
+       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-11-17  Zhenqiang Chen  <zhenqiang.chen@arm.com>
+
+       * ifcvt.c (HAVE_cbranchcc4): Define.
+       (noce_emit_cmove, noce_get_alt_condition, noce_get_condition):
+       Use HAVE_cbranchcc4.
+
+       2014-11-04  Zhenqiang Chen  <zhenqiang.chen@arm.com>
+
+       Revert:
+               2014-11-03  Zhenqiang Chen  <zhenqiang.chen@arm.com>
+       * ifcvt.c (noce_emit_cmove, noce_get_alt_condition, noce_get_condition):
+       Allow CC mode if HAVE_cbranchcc4.
+
 2015-04-02  Maxim Kuvyrkov  <maxim.kuvyrkov@linaro.org>
 
        Fix testcase backported from trunk
index 7cd85d1..4fd46d2 100644 (file)
    + 1)
 #endif
 
+#ifndef HAVE_cbranchcc4
+#define HAVE_cbranchcc4 0
+#endif
+
 #define IFCVT_MULTIPLE_DUMPS 1
 
 #define NULL_BLOCK     ((basic_block) NULL)
@@ -1000,6 +1004,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.
@@ -1010,6 +1026,7 @@ end_ifcvt_sequence (struct noce_if_info *if_info)
 {
   rtx insn;
   rtx seq = get_insns ();
+  rtx cc = cc_in_cond (if_info->cond);
 
   set_used_flags (if_info->x);
   set_used_flags (if_info->cond);
@@ -1024,7 +1041,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_RTX;
 
   return seq;
@@ -1437,10 +1456,9 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
   if (! general_operand (cmp_a, GET_MODE (cmp_a))
       || ! general_operand (cmp_b, GET_MODE (cmp_b)))
     {
-#if HAVE_cbranchcc4
-      if (GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC
+      if (!(HAVE_cbranchcc4)
+         || GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC
          || cmp_b != const0_rtx)
-#endif
        return NULL_RTX;
     }
 
@@ -1760,11 +1778,6 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
 {
   rtx cond, set, insn;
   int reverse;
-  int allow_cc_mode = false;
-#if HAVE_cbranchcc4
-  allow_cc_mode = true;
-#endif
-
 
   /* If target is already mentioned in the known condition, return it.  */
   if (reg_mentioned_p (target, if_info->cond))
@@ -1886,7 +1899,7 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
     }
 
   cond = canonicalize_condition (if_info->jump, cond, reverse,
-                                earliest, target, allow_cc_mode, true);
+                                earliest, target, HAVE_cbranchcc4, true);
   if (! cond || ! reg_mentioned_p (target, cond))
     return NULL;
 
@@ -2337,10 +2350,6 @@ noce_get_condition (rtx jump, rtx *earliest, bool then_else_reversed)
 {
   rtx cond, set, tmp;
   bool reverse;
-  int allow_cc_mode = false;
-#if HAVE_cbranchcc4
-  allow_cc_mode = true;
-#endif
 
   if (! any_condjump_p (jump))
     return NULL_RTX;
@@ -2377,7 +2386,7 @@ noce_get_condition (rtx jump, rtx *earliest, bool then_else_reversed)
   /* Otherwise, fall back on canonicalize_condition to do the dirty
      work of manipulating MODE_CC values and COMPARE rtx codes.  */
   tmp = canonicalize_condition (jump, cond, reverse, earliest,
-                               NULL_RTX, allow_cc_mode, true);
+                               NULL_RTX, HAVE_cbranchcc4, true);
 
   /* We don't handle side-effects in the condition, like handling
      REG_INC notes and making sure no duplicate conditions are emitted.  */
@@ -2510,6 +2519,7 @@ noce_process_if_block (struct noce_if_info *if_info)
   rtx 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
 
@@ -2618,6 +2628,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.  */
@@ -2773,6 +2790,7 @@ check_cond_move_block (basic_block bb,
                       rtx cond)
 {
   rtx 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.  */
@@ -2831,6 +2849,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;
+
       slot = pointer_map_insert (vals, (void *) dest);
       *slot = (void *) src;
 
index e921593..b6a7538 100644 (file)
@@ -1,3 +1,10 @@
+2015-04-07  Yvan Roux  <yvan.roux@linaro.org>
+
+       Backport from trunk r218658.
+       2014-12-12  Zhenqiang Chen  <zhenqiang.chen@arm.com>
+
+       * gcc.dg/pr64007.c: New test.
+
 2015-04-02  Yvan Roux  <yvan.roux@linaro.org>
 
        Backport from trunk r218961.
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;
+}