llvm-project
2e21bb81 - [RISCV][ISelLowering] Use Zicond for FP selects on Zfinx/Zdinx (#169299)

Commit
95 days ago
[RISCV][ISelLowering] Use Zicond for FP selects on Zfinx/Zdinx (#169299) ### Summary This patch let RISCVTargetLowering::lowerSELECT to lower some floating-point select operations through an integer zicond select when: * Zicond is available, and * FP values live in GPRs (Zfinx/Zdinx), and * Select condition is an integer type. In that scenario there is no extra cost for GPR <-> "FP GPR" moves, so we can implement FP selects with a CZERO-based sequence instead of a branch. For example, for ```c float foo(int cond, float x) { return (cond != 0) ? x : 0.0f; } ``` the current lowering produces: ```asm foo: mv a2, a0 li a0, 0 beqz a2, .LBB0_2 .LBB0_1: mv a0, a1 .LBB0_2: ret ``` With this patch, when targeting rv64ima_zicond_zfinx we instead get: ```asm foo: czero.nez a2, zero, a0 czero.eqz a0, a1, a0 or a0, a2, a0 ret ``` The existing branch-based lowering is preserved for: * targets without Zicond * targets where FP registers are separate (+f, +d without zfinx/zdinx) ### Testing Adds llvm/test/CodeGen/RISCV/zicond-fp-select-zfinx.ll to cover: * RV64 Zfinx/Zicond vs Zfinx without Zicond * RV64 Zdinx/Zicond vs Zdinx without Zicond * RV32 Zfinx/Zicond vs Zfinx without Zicond Also adds baseline RV32F/RV64F/RV64D cases to ensure we still use branches when FP registers are separate. The tests check that: * With Zicond + Zfinx/Zdinx, FP select lowers to a CZERO+OR sequence with no conditional branches. * Without Zicond (or without Zfinx/Zdinx), we still get branch-based code and no czero.* instructions.
Author
Parents
Loading