On Wed, Jul 19, 2023 at 01:36:23PM +0000, Richard Biener wrote: > > If we have a match between at least one of the comparison operands and > > op2/op3, I think having equivalency there is perhaps more important than > > the canonicalization, but it would be nice not to break it even if there > > is no match. So, perhaps force_reg only if there is a match? > > force_reg (cmpmode, force_reg (cmpmode, x)) is equivalent to > > force_reg (cmpmode, x), so perhaps: > > { > > if (rtx_equal_p (orig_op0, op2)) > > op2p = XEXP (comparison, 0) = force_reg (cmpmode, orig_op0); > > if (rtx_equal_p (orig_op0, op3)) > > op3p = XEXP (comparison, 0) > > = force_reg (cmpmode, XEXP (comparison, 0)); > > } > > and similarly for the other body? > > I don't think we'll have op3 == op2 == orig_op0 because if > op2 == op3 the > > /* If the two source operands are identical, that's just a move. */ > > if (rtx_equal_p (op2, op3)) > { > if (!target) > target = gen_reg_rtx (mode); > > emit_move_insn (target, op3); > return target; > > code should have triggered. So we should know we invoke force_reg > only once for each comparison operand check? > > So I'm going to test the following ontop of the patch.
Please use else if instead of the second if then. Ok with that change. > --- a/gcc/optabs.cc > +++ b/gcc/optabs.cc > @@ -5131,11 +5131,10 @@ emit_conditional_move (rtx target, struct > rtx_comparison comp, > > COSTS_N_INSNS (1)) > && can_create_pseudo_p ()) > { > - XEXP (comparison, 0) = force_reg (cmpmode, orig_op0); > if (rtx_equal_p (orig_op0, op2)) > - op2p = XEXP (comparison, 0); > + op2p = XEXP (comparison, 0) = force_reg (cmpmode, > orig_op0); > if (rtx_equal_p (orig_op0, op3)) > - op3p = XEXP (comparison, 0); > + op3p = XEXP (comparison, 0) = force_reg (cmpmode, > orig_op0); > } > if (CONSTANT_P (orig_op1) && optimize > && (rtx_cost (orig_op1, mode, COMPARE, 0, > @@ -5143,11 +5142,10 @@ emit_conditional_move (rtx target, struct > rtx_comparison comp, > > COSTS_N_INSNS (1)) > && can_create_pseudo_p ()) > { > - XEXP (comparison, 1) = force_reg (cmpmode, orig_op1); > if (rtx_equal_p (orig_op1, op2)) > - op2p = XEXP (comparison, 1); > + op2p = XEXP (comparison, 1) = force_reg (cmpmode, > orig_op1); > if (rtx_equal_p (orig_op1, op3)) > - op3p = XEXP (comparison, 1); > + op3p = XEXP (comparison, 1) = force_reg (cmpmode, > orig_op1); > } > prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1), > GET_CODE (comparison), NULL_RTX, unsignedp, Jakub