[llvm] [RISCV] Teach RISCVTargetLowering::isFPImmLegal about fli+fneg (PR #149075)

Alex Bradbury via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 16 03:55:37 PDT 2025


https://github.com/asb created https://github.com/llvm/llvm-project/pull/149075

There was a mismatch between isFPImmlegal and the cases that are handled by lowerConstantFP. isFPImmLegal didn't check for the case where we support `fli` of a negated constant (and so can lower to fli+fneg). This has very minimal impact (42 insertion, 47 deletions across an rv22u64_zfa llvm-test-suite build including SPEC CPU 2017) but is added here for completeness.

---
As for testing, from what I can see we don't have consistent testing of the logic here. If you're happy this is trivial enough it can land as-is. If we do want to add tests here, this is a case where I'd probably advocate for adding C++ unit tests for isFPImmLegal directly rather than trying to test it indirectly in a potentially brittle way. But welcome your feedback/suggestions.

>From 289f95817c8859ac1495e01d53fe884f6e8f1e5d Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Wed, 16 Jul 2025 11:50:31 +0100
Subject: [PATCH] [RISCV] Teach RISCVTargetLowering::isFPImmLegal about
 fli+fneg

There was a mismatch between isFPImmlegal and the cases that are handled
by lowerConstantFP. isFPImmLegal didn't check for the case where we
support `fli` of a negated constant (and so can lower to fli+fneg). This
has very minimal impact (42 insertion, 47 deletions across an
rv22u64_zfa llvm-test-suite build including SPEC CPU 2017) but is added
here for completeness.
---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index de830666d89b8..b53f2808eeb41 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -2319,6 +2319,10 @@ bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
   if (getLegalZfaFPImm(Imm, VT) >= 0)
     return true;
 
+  // Some constants can be produced by fli+fneg.
+  if (Imm.isNegative() && getLegalZfaFPImm(-Imm, VT) >= 0)
+    return true;
+
   // Cannot create a 64 bit floating-point immediate value for rv32.
   if (Subtarget.getXLen() < VT.getScalarSizeInBits()) {
     // td can handle +0.0 or -0.0 already.



More information about the llvm-commits mailing list