[llvm] [RISCV][ISelLowering] Use Zicond for FP selects on Zfinx/Zdinx (PR #169299)

via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 25 07:42:24 PST 2025


fennecJ wrote:

I noticed that when lowering a floating-point SELECT to integer Zicond 
operations on RV64, converting an `f32` `+0.0` results in a 
`RISCVISD::FMV_X_ANYEXTW_RV64` node. It seems that this target-specific
node represents a register move, which obscures the underlying const-zero
value from the instruction selector and prevents the backend from
pattern-matching it into a single `czero` instruction.

For the following example:

```asm
  define dso_local noundef float @select_i1_f32_0(i1 %cond, float %t) nounwind {
  entry:
    %sel = select i1 %cond, float %t, float 0.000000e+00
    ret float %sel
  }
```
On RV32 (e.g, RV32ZFINX_ZICOND, no need to call FMV_X), this  previously resulted in:

```asm
    czero.eqz a0, a1, a0
    ret
```

However,
On RV64 (e.g., +zicond +zdinx), this previously resulted in:
```asm
    czero.nez  a2, zero, a0
    czero.eqz  a0, a1, a0
    or         a0, a2, a0
    ret
```
Since the "else" value is zero, we can utilize the mechanism that czero
like instruction will store zero into rd based on cond reg and optimized
this scenario in to a single instruction.
By explicitly detecting `+0.0` and lowering it to a constant integer 0,
the newest commit enables the single czero generation for above example.
```asm
    czero.eqz  a0, a1, a0
    ret
```

https://github.com/llvm/llvm-project/pull/169299


More information about the llvm-commits mailing list