On Fri, Nov 21, 2014 at 2:51 AM, Ulrich Weigand <uweig...@de.ibm.com> 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 > ulrich.weig...@de.ibm.com >