On 12/18/2025 1:10 AM, Meng-Tsung Tsai wrote:
When the Zfinx extension (or Zdinx/Zhinx) is enabled, FP values reside
in GPR. Which means we may be able to materialize a FP constant using
int instructions. Currently, however, FP constants are typically loaded
from constant pool via memory loads.
This patch allows the compiler to materialize FP constants directly in
GPRs using integer instructions (like lui, addi) if the cost is low
enough and zfinx like extension is enabled (so the FP value lies in GPR)
This avoids memory access overhead and reduces cache pressure.
For example, given the following C code:
float foo() {
// 0x3fc00000
return 1.5f;
}
Original codegen (with Zfinx):
foo():
lui a5,%hi(.LC0)
lw a0,%lo(.LC0)(a5)
ret
.LC0:
.word 1069547520
After this patch:
foo():
lui a0, 261120 # hex(261120) = 0x3FC00
ret
gcc/ChangeLog:
* config/riscv/iterators.md (GPRF_XLEN): New mode iterator for
floating-point modes that fit in a single XLEN register.
* config/riscv/riscv.cc (riscv_const_insns): Calculate cost for
materializing FP constants as integers when Zfinx is enabled.
* config/riscv/riscv.md (*mov<mode>_zfinx_const): New pattern
and splitter to materialize FP constants using integer logic.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/zfinx-const-li.c: New test for FP
materialization.
I think this conflicts with a recent patch from Philipp which also
provides the ability to construct some FP constants in integer registers.
The biggest conceptual difference is Philipp's work applies even when
without Zfinx. Let's consider -0.0. That's just
bset dest,x0,31 or bset dest,x0,63 dependent on if it's a 32 or 64 bit
floating point value. That's profitable to construct in a GPR
irrespective of Zfinx. In fact I would expect any FP constant where the
bit pattern can be constructed in <= 4 instructions to be profitable to
construct in a GPR first due to the cost of memory loads.
I'm slightly in favor of Philipp's version because of it's more general
applicability. It would certainly be useful if you could play with his
and report back if there's meaningful cases yours handles that Philipp's
doesn't.
THanks,
Jeff