On 9/9/26 12:22 AM, Bohan Lei wrote:
This is based on Zhijin Zeng's v3 patch
(https://gcc.gnu.org/pipermail/gcc-patches/2025-January/673406.html).
This commit modifies riscv_can_change_mode_class and
riscv_hard_regno_mode_ok to allow IRA to allocate an FPR to a pseudo
that is used in a interger mode in some places.
A typical scenario would be cases with bit-level uses of floating-point
variables. The current IRA can only allocate them in GPRs, and any FP
use of it would create a new FPR reload, which can lead to lots of
redundant fmv.d.x instructions in the function. The attached case
(LLM-generated) is a reduced one that can still show the underlying
issue.
I am not using Zhijin's original testcase in this version because
register renaming has accidentally helped eliminate the redundant fmv
instructions in that case.
Also note that the tiebility change in that patch is not included in
this version. We found that change can lead to more regressions and
would require special handling. Nonetheless, we found one redundant
fmv.x.d instruction in our complete lgamma case downstream, not verified
with the trunk though, which can be eliminated with the tieability
change. (After all, FP and integer modes being tieable makes it hard
track separate live ranges of integer uses and FP uses of the same
variable.) We may submit a separate tieability patch after gathering
enough evidence that this could lead to real performance issues.
Regtested on rv64gcv and rv32gcv, no regression.
Assisted-by: Codex
Co-authored-by: Zhijin Zeng <[email protected]>
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_hard_regno_mode_ok): Allow SImode
and DImode in GPRs.
(riscv_can_change_mode_class): Allow mode changing between
integer and FP modes.
* config/riscv/riscv.md: Add f,f constraints to SI and HI moves.
* config/riscv/vector.md: Restore X constraint for vr,vr LRA
move patterns to prevent ICE caused by FPR-allocated scratch.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/fmv-lgamma.c: New test.
So this is how things have worked on most targets through the years.
ie, provide the right alternatives in the movXX patterns so that a
floating point mode can live in a GPR and integer modes in an FPR. So
at least conceptually what you're trying to do was the default way to
handle stuff until fairly recently when some ports have tried to avoid
those scenarios.
RISC-V has direct ways to move between GPRs and FPRs so when we have an
object used in different modes, we can move back and forth without
needing secondary memory, which is definitely good. That's been a sort
spot through the years.
I'm a little surprised that you didn't have to adjust the movhi, movdi,
movsf, movdf, movhf, and movbf patterns. I'd kind of expect them to
need similar kinds of handling.
Have you done any benchmarking beyond the lgamma case? What about other
codebases? glibc has the kinds of code you're looking to handle more
sensibly, so it'd be good to build glibc with your patch as well.
So generally supportive, but would like to see more build/benchmarking
data as I've seen this kind of thing go sideways before.
Jeff