aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>2015-04-07 13:24:05 +0000
committeryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>2015-04-07 13:24:05 +0000
commit767f045a556fc1ea52464612f9fecbe356d37ae1 (patch)
tree477ce48a4ca737b0dbfb9dc768572e7110a8e9ef
parent15b6058dff9c2eb6bcfde5aa5d7c10744d842e46 (diff)
gcc/
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
-rw-r--r--gcc/ChangeLog.linaro23
-rw-r--r--gcc/ifcvt.c52
-rw-r--r--gcc/testsuite/ChangeLog.linaro7
-rw-r--r--gcc/testsuite/gcc.dg/pr64007.c50
4 files changed, 117 insertions, 15 deletions
diff --git a/gcc/ChangeLog.linaro b/gcc/ChangeLog.linaro
index 398ac8c2bcc..499068a65e9 100644
--- a/gcc/ChangeLog.linaro
+++ b/gcc/ChangeLog.linaro
@@ -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
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 7cd85d1fecf..4fd46d254d1 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -63,6 +63,10 @@
+ 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;
diff --git a/gcc/testsuite/ChangeLog.linaro b/gcc/testsuite/ChangeLog.linaro
index e921593b56d..b6a7538a6d8 100644
--- a/gcc/testsuite/ChangeLog.linaro
+++ b/gcc/testsuite/ChangeLog.linaro
@@ -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
index 00000000000..cb0e50f6cb8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr64007.c
@@ -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;
+}