> -----Original Message-----
> From: Alfie Richards <[email protected]>
> Sent: 08 August 2026 00:11
> To: [email protected]
> Cc: Alex Coplan <[email protected]>; Alice Carlotti
> <[email protected]>; [email protected];
> [email protected]; Tamar Christina <[email protected]>;
> [email protected]; [email protected]; [email protected]; Alfie
> Richards <[email protected]>
> Subject: [PATCH v2 02/13] aarch64: Make reads/writes to FFR expensive
> 
> With later changes to RDFFR to use subregisters we see forward prop
> begin to duplicate FFR reads. This change prevents that.
> 

Do you have a testcase that shows this?

> gcc/ChangeLog:
> 
>       * config/aarch64/aarch64.cc (aarch64_insn_cost): Add extra costs
>       for FFR reads/writes.
> ---
>  gcc/config/aarch64/aarch64.cc | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index 3041a6ee62a..e7522e49efd 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -16989,8 +16989,16 @@ aarch64_frame_allocation_cost
> (frame_cost_type,
>  static int
>  aarch64_insn_cost (rtx_insn *insn, bool speed)
>  {
> +  int extra_cost = 0;
> +
> +  /* Reads and sets to FFR are expensive. Mark them as such to prevent
> +     duplication.  */
> +  if (recog_memoized (insn) != -1
> +      && get_attr_sve_type (insn) == SVE_TYPE_SVE_FFR)
> +    extra_cost = 100;
> +

That seems quite expensive. Does it really need to be that much?
A testcase would be nice :)

I can certainly believe the cost of RDFFR should not be the default cost,
but I think this is in the wrong place and it shouldn't use the scheduling type
attributes.  The above for instance also makes setffr more expensive.

Instead I think this should be in aarch64_rtx_costs in the branch that's
costing a full INSN, (i.e. the case SET: ) but to identify an rdffr as an
instruction with a predicate destination and FFRT_REGNUM mentioned
in the source.

Then just use the normal COSTS_N_INSN macro to scale costs to insn costs
and use the same turning param you introduce later on. So something like

static int
aarch64_ffr_op_cost (rtx set)
{
  if (GET_CODE (set) != SET)
    return 0;

  rtx dest = SET_DEST (set);
  rtx x = SET_SRC (set);

  if (GET_CODE (x) == UNSPEC
      && XINT (x, 1) == UNSPEC_PTEST
      && refers_to_regno_p (FFRT_REGNUM, x))
    return COSTS_N_INSNS (aarch64_tune_params.vec_costs->sve->rdffr_cost);

  if (REG_P (dest)
      && aarch64_sve_pred_mode_p (GET_MODE (dest))
      && refers_to_regno_p (FFRT_REGNUM, x))
      return COSTS_N_INSNS (aarch64_tune_params.vec_costs->sve->rdffr_cost);

  return 0;
}

>    if (rtx set = single_set (insn))
> -    return set_rtx_cost (set, speed);
> +    return set_rtx_cost (set, speed) + extra_cost;
> 
>    /* If the instruction does multiple sets in parallel, use the cost
>       of the most expensive set.  This copes with instructions that set
> @@ -17005,10 +17013,10 @@ aarch64_insn_cost (rtx_insn *insn, bool
> speed)
>         if (GET_CODE (x) == SET)
>           max_cost = std::max (max_cost, set_rtx_cost (x, speed));
>       }
> -      return max_cost;
> +      return max_cost + extra_cost;
>      }
> 
> -  return pattern_cost (pat, speed);
> +  return pattern_cost (pat, speed) + extra_cost;
>  }
> 
>  /* Implement TARGET_INIT_BUILTINS.  */
> --
> 2.43.0

Reply via email to