From 767f045a556fc1ea52464612f9fecbe356d37ae1 Mon Sep 17 00:00:00 2001 From: yroux Date: Tue, 7 Apr 2015 13:24:05 +0000 Subject: [PATCH] gcc/ 2015-04-07 Yvan Roux Backport from trunk r217062, r217646, r218658. 2014-12-12 Zhenqiang Chen 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 * ifcvt.c (HAVE_cbranchcc4): Define. (noce_emit_cmove, noce_get_alt_condition, noce_get_condition): Use HAVE_cbranchcc4. 2014-11-04 Zhenqiang Chen Revert: 2014-11-03 Zhenqiang Chen * 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 Backport from trunk r218658. 2014-12-12 Zhenqiang Chen * 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 | 23 +++++++++++++++++++ gcc/ifcvt.c | 52 ++++++++++++++++++++++++++++++------------ gcc/testsuite/ChangeLog.linaro | 7 ++++++ gcc/testsuite/gcc.dg/pr64007.c | 50 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr64007.c diff --git a/gcc/ChangeLog.linaro b/gcc/ChangeLog.linaro index 398ac8c..499068a 100644 --- a/gcc/ChangeLog.linaro +++ b/gcc/ChangeLog.linaro @@ -1,3 +1,26 @@ +2015-04-07 Yvan Roux + + Backport from trunk r217062, r217646, r218658. + 2014-12-12 Zhenqiang Chen + + 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 + + * ifcvt.c (HAVE_cbranchcc4): Define. + (noce_emit_cmove, noce_get_alt_condition, noce_get_condition): + Use HAVE_cbranchcc4. + + 2014-11-04 Zhenqiang Chen + + Revert: + 2014-11-03 Zhenqiang Chen + * ifcvt.c (noce_emit_cmove, noce_get_alt_condition, noce_get_condition): + Allow CC mode if HAVE_cbranchcc4. + 2015-04-02 Maxim Kuvyrkov Fix testcase backported from trunk diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 7cd85d1..4fd46d2 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 e921593..b6a7538 100644 --- a/gcc/testsuite/ChangeLog.linaro +++ b/gcc/testsuite/ChangeLog.linaro @@ -1,3 +1,10 @@ +2015-04-07 Yvan Roux + + Backport from trunk r218658. + 2014-12-12 Zhenqiang Chen + + * gcc.dg/pr64007.c: New test. + 2015-04-02 Yvan Roux 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 0000000..cb0e50f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr64007.c @@ -0,0 +1,50 @@ +/* { dg-options " -O3 " } */ +/* { dg-do run } */ + +#include + +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; +} -- 2.7.4