On Fri, Nov 21, 2014 at 2:51 AM, Ulrich Weigand <[email protected]> wrote:
> Richard Biener wrote:
>
>> This probably caused bootstrap on s390x-linux to fail as in PR63952
>> (last checked with rev. 217714).
>
> It seems we have both a back-end bug and a middle-end bug here.
>
> First of all, this code in optabs.c:prepare_cmp_insn is quite strange:
>
> if (GET_MODE_CLASS (mode) == MODE_CC)
> {
> gcc_assert (can_compare_p (comparison, CCmode, ccp_jump));
> *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
> return;
> }
>
> Note that can_compare_p checks whether the back-end accepts a test
> RTX created via:
> test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
>
> All back-end cbranchcc4 patterns however verify that the first operand
> of the comparison is the flags register, so a const0_rtx will never
> match. It doesn't seem useful to call can_compare_p with CCmode at all.
>
> The patch below changes prepare_cmp_insn do do an explicit
> insn_operand_matches test using the actual operands, just like
> is also done for non-CCmode comparisons.
>
>
> However, even so this is still rejected by the s390 back end. This is
> because the s390 cbranchcc4 pattern is really quite wrong; it is restricted
> to accepting only EQ/NE comparisons when it could simply accept any valid
> comparison (i.e. where s390_comparison is true).
>
> In addition, it has a TARGET_HARD_FLOAT check for no reason I can see,
> and it has custom expander code that is in all cases a no-op and results
> in exactly the pattern in the insn to be emitted anyway.
>
> Fixed by the patch below as well.
>
>
> Tested on s390x-ibm-linux (with and without --with-arch=z196).
>
> OK for mainline?
Ok.
Thanks,
Richard.
> Bye,
> Ulrich
>
>
> ChangeLog:
>
> PR rtl-optimization/63952
> * optabs.c (prepare_cmp_insn): Do not call can_compare_p for CCmode.
> * config/s390/s390.md ("cbranchcc4"): Accept any s390_comparison.
> Remove incorrect TARGET_HARD_FLOAT check and no-op expander code.
>
> Index: gcc/optabs.c
> ===================================================================
> *** gcc/optabs.c (revision 217784)
> --- gcc/optabs.c (working copy)
> *************** prepare_cmp_insn (rtx x, rtx y, enum rtx
> *** 4167,4174 ****
>
> if (GET_MODE_CLASS (mode) == MODE_CC)
> {
> ! gcc_assert (can_compare_p (comparison, CCmode, ccp_jump));
> ! *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
> return;
> }
>
> --- 4167,4177 ----
>
> if (GET_MODE_CLASS (mode) == MODE_CC)
> {
> ! enum insn_code icode = optab_handler (cbranch_optab, CCmode);
> ! test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
> ! gcc_assert (icode != CODE_FOR_nothing
> ! && insn_operand_matches (icode, 0, test));
> ! *ptest = test;
> return;
> }
>
> Index: gcc/config/s390/s390.md
> ===================================================================
> *** gcc/config/s390/s390.md (revision 217784)
> --- gcc/config/s390/s390.md (working copy)
> ***************
> *** 8142,8157 ****
>
> (define_expand "cbranchcc4"
> [(set (pc)
> ! (if_then_else (match_operator 0 "s390_eqne_operator"
> [(match_operand 1 "cc_reg_operand" "")
> ! (match_operand 2 "const0_operand" "")])
> (label_ref (match_operand 3 "" ""))
> (pc)))]
> ! "TARGET_HARD_FLOAT"
> ! "s390_emit_jump (operands[3],
> ! s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
> ! DONE;")
> !
>
>
> ;;
> --- 8142,8154 ----
>
> (define_expand "cbranchcc4"
> [(set (pc)
> ! (if_then_else (match_operator 0 "s390_comparison"
> [(match_operand 1 "cc_reg_operand" "")
> ! (match_operand 2 "const_int_operand" "")])
> (label_ref (match_operand 3 "" ""))
> (pc)))]
> ! ""
> ! "")
>
>
> ;;
>
> --
> Dr. Ulrich Weigand
> GNU/Linux compilers and toolchain
> [email protected]
>