> Anyways, instead what I do here is normalize all expansions of > conditional moves to be of the form: > > (set op0 (if_then_else (cmp X Y) > op3 > op0)) > > and in the instruction patterns I use "register_operand" and > constraint "0" for operand 4. > > This is enough to keep the combiner from recognizing sequences > like the above. > > Committed to trunk. > > gcc/ > > * config/sparc/sparc-protos.h (sparc_expand_conditional_move): Declare. > * config/sparc/sparc.md (mov<I:mode>cc, mov<F:mode>cc): Call it. > (*mov<I:mode>_cc_v9): Normalize to expect operand 0 always in operand 4. > (*mov<I:mode>_cc_reg_sp64): Likewise. > (*movsf_cc_v9): Likewise. > (*movsf_cc_reg_sp64): Likewise. > (*movdf_cc_v9): Likewise. > (*movdf_cc_reg_sp64): Likewise. > (*movtf_cc_hq_v9): Likewise. > (*movtf_cc_reg_hq_sp64): Likewise. > (*movtf_cc_v9): Likewise. > (*movtf_cc_reg_sp64): Likewise. > * config/sparc/sparc.c (sparc_expand_conditional_move): New function. > (sparc_print_operand): Delete 'c' and 'd' handling, no longer used.
This has reintroduced PR target/49965. > @@ -11377,4 +11361,58 @@ sparc_secondary_reload (bool in_p, rtx x, > reg_class_t rclass_i, return NO_REGS; > } > > +bool > +sparc_expand_conditional_move (enum machine_mode mode, rtx *operands) > +{ > + enum rtx_code rc = GET_CODE (operands[1]); > + enum machine_mode cmp_mode; > + rtx cc_reg, dst, cmp; > + > + cmp = operands[1]; > + cmp_mode = GET_MODE (XEXP (cmp, 0)); > + if (cmp_mode == DImode && !TARGET_ARCH64) > + return false; > + > + dst = operands[0]; > + > + if (! rtx_equal_p (operands[2], dst) > + && ! rtx_equal_p (operands[3], dst)) > + { > + if (reg_overlap_mentioned_p (dst, cmp)) > + dst = gen_reg_rtx (mode); > + > + emit_move_insn (dst, operands[3]); > + } > + else if (operands[2] == dst) > + { > + operands[2] = operands[3]; > + > + if (GET_MODE_CLASS (cmp_mode) == MODE_FLOAT) > + rc = reverse_condition_maybe_unordered (rc); > + else > + rc = reverse_condition (rc); > + } > + > + if (cmp_mode == TFmode && !TARGET_HARD_QUAD) > + cmp = sparc_emit_float_lib_cmp (XEXP (cmp, 0), XEXP (cmp, 1), rc); You cannot cache anything from operands[1] as sparc_emit_float_lib_cmp will modify it, including RC. > + if (XEXP (cmp, 1) == const0_rtx > + && GET_CODE (XEXP (cmp, 0)) == REG > + && cmp_mode == DImode > + && v9_regcmp_p (rc)) > + cc_reg = XEXP (cmp, 0); > + else > + cc_reg = gen_compare_reg_1 (rc, XEXP (cmp, 0), XEXP (cmp, 1)); > + > + cmp = gen_rtx_fmt_ee (rc, GET_MODE (cc_reg), cc_reg, const0_rtx); RC is wrong here if we went through sparc_emit_float_lib_cmp above. -- Eric Botcazou