On 5/28/2026 1:52 AM, Jin Ma wrote:
> The GCC Internals Manual, section 19.8 "Register Classes", documents
> REGNO_REG_CLASS as:
>
>    REGNO_REG_CLASS (regno)                                      [Macro]
>      A C expression whose value is a register class containing hard
>      register regno.  In general there is more than one such class;
>      choose a class which is minimal, meaning that no smaller class
>      also contains the register.
>
> riscv_regno_to_class[] currently maps every FP hard register to
> RVC_FP_REGS, but RVC_FP_REGS only contains f8-f15.  The entries for
> f0-f7 and f16-f31 therefore violate the "containing hard register
> regno" half of the contract: the returned class does not contain the
> register at all.
>
> The mismatch corrupts IRA's cost model.  setup_allocno_cost_vector
> indexes the per-hard-reg cost slot via REGNO_REG_CLASS:
>
>    rclass = REGNO_REG_CLASS (hard_regno);
>    num = cost_classes_ptr->index[rclass];
>    ...
>    reg_costs[j] = COSTS (costs, i)->cost[num];
>
> After setup_regno_cost_classes_by_mode adds RVC_FP_REGS to the cost
> classes, the cost for e.g. f16 is silently read from the RVC_FP_REGS
> slot.
>
> The new fp-reg-class.c testcase puts eight "cf"- and sixteen "f"-
> constrained doubles live across a call.  In the buggy state IRA
> places the cf pseudos outside the cf class and LRA recovers with
> sixteen fmv.d to fs* registers; with the fix IRA spills those values
> honestly and the IRA "+++Costs" line reports a non-zero "mem"
> component.
>
> Fix it by giving each FP hard register its minimal class: FP_REGS for
> f0-f7 and f16-f31, RVC_FP_REGS for f8-f15.  As a companion change,
> switch riscv_secondary_memory_needed from class-equality tests to
> reg_class_subset_p so it still recognises the FP side regardless of
> which subclass the table returns.
>
> gcc/ChangeLog:
>
>       * config/riscv/riscv.cc (riscv_regno_to_class): Use the minimal
>       class containing each FP hard register: FP_REGS for f0-f7 and
>       f16-f31, RVC_FP_REGS for f8-f15.
>       (riscv_secondary_memory_needed): Use reg_class_subset_p to
>       detect FP classes.
>
> gcc/testsuite/ChangeLog:
>
>       * gcc.target/riscv/fp-reg-class.c: New test.
OK.  Curious how you found this.  Guessing you were looking at a 
benchmark and saw more fmv instructions than looked sensible?

Thanks!
jeff

Reply via email to