> 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

Reply via email to