Hi, The patch add runtime check to fix s390 build fail (https://gcc.gnu.org/ml/gcc-patches/2014-11/msg00050.html).
And there is additional code to workaround s390 cstorecc4 issue. Bootstrap and no make check regression on X86-64. Build s390-linux-gnu and s390x-linux-gnu. I do not have env to run full s390 tests. Would anyone in the TO list help to run the s390 tests? Thanks! -Zhenqiang ChangeLog: 2014-11-06 Zhenqiang Chen <zhenqiang.c...@arm.com> * ifcvt.c (noce_emit_cmove, noce_get_alt_condition, noce_get_condition): Allow CC mode if HAVE_cbranchcc4. (noce_emit_store_flag): Change CC REG as cond_complex. diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index f4002f9..7f7b7c1 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -849,7 +849,10 @@ noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep, enum rtx_code code; cond_complex = (! general_operand (XEXP (cond, 0), VOIDmode) - || ! general_operand (XEXP (cond, 1), VOIDmode)); + || ! general_operand (XEXP (cond, 1), VOIDmode) + /* For s390, CC REG is general_operand. But cstorecc4 only + handles CCZ1, which can not handle others like CCU. */ + || GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_CC); /* If earliest == jump, or when the condition is complex, try to build the store_flag insn directly. */ @@ -1459,10 +1462,18 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code, end_sequence (); } - /* Don't even try if the comparison operands are weird. */ + /* Don't even try if the comparison operands are weird + except that the target supports cbranchcc4. */ if (! general_operand (cmp_a, GET_MODE (cmp_a)) || ! general_operand (cmp_b, GET_MODE (cmp_b))) - return NULL_RTX; + { +#ifdef HAVE_cbranchcc4 + if (GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC + || cmp_b != const0_rtx + || !(HAVE_cbranchcc4)) +#endif + return NULL_RTX; + } #if HAVE_conditional_move unsignedp = (code == LTU || code == GEU @@ -1788,6 +1799,11 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target, rtx cond, set; rtx_insn *insn; int reverse; + int allow_cc_mode = false; +#ifdef HAVE_cbranchcc4 + allow_cc_mode = HAVE_cbranchcc4; +#endif + /* If target is already mentioned in the known condition, return it. */ if (reg_mentioned_p (target, if_info->cond)) @@ -1909,7 +1925,7 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target, } cond = canonicalize_condition (if_info->jump, cond, reverse, - earliest, target, false, true); + earliest, target, allow_cc_mode, true); if (! cond || ! reg_mentioned_p (target, cond)) return NULL; @@ -2365,6 +2381,10 @@ noce_get_condition (rtx_insn *jump, rtx_insn **earliest, bool then_else_reversed { rtx cond, set, tmp; bool reverse; + int allow_cc_mode = false; +#ifdef HAVE_cbranchcc4 + allow_cc_mode = HAVE_cbranchcc4; +#endif if (! any_condjump_p (jump)) return NULL_RTX; @@ -2401,7 +2421,7 @@ noce_get_condition (rtx_insn *jump, rtx_insn **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, false, true); + NULL_RTX, allow_cc_mode, true); /* We don't handle side-effects in the condition, like handling REG_INC notes and making sure no duplicate conditions are emitted. */