-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[RISCV] Teach RISCVTargetLowering::isFPImmLegal about fli+fneg #149075
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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/pr-subscribers-backend-risc-v Author: Alex Bradbury (asb) ChangesThere was a mismatch between isFPImmlegal and the cases that are handled by lowerConstantFP. isFPImmLegal didn't check for the case where we support 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. Full diff: https://github.com/llvm/llvm-project/pull/149075.diff 1 Files Affected:
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.
|
I removed this in #108316. isLegalFPImm is not supposed to be in sync with lowerConstantFP. lowerConstantFP handles things that aren't legal. |
Thanks for the reference. How would you define "legal" constants for isFPImmLegal because by my reading of the function, it's currently counting anything that can be handled with two instructions (e.g. -0.0 via fmv x0 then fneg, and FP values with bit patterns that can be loaded with a single int instruction then fmv). |
I thought "legal" was anything that was handled by the code in But looking closer, LegalizeDAG.cpp only checks |
Looking at how it's used from DAGCombiner that had been my expectation. Support for selecting the FP value "natively" is a bit debatable on RISC-V, but I think "will be generated cheaply using a small number of instructions rather than loaded from the constant pool" is reasonable, and seems consistent with how that function is implemented today (other than missing the fli+fneg case). As noted in the commit message, this has almost no impact on llvm-test-suite. But I'd still like to land it for completeness and consistency (and of course the chance of unexpected negative impact seems negligible). What do you think? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I think I'm ok with this. But I want to note that this only works because LowerConstantFP creates a RISCVISD::FLI node. Which it does because visitFNEG will always converts ConstantFP+fneg into a ConstantFP of the negated value without checking isFPImmLegal. The RISCVISD::FLI hides the sequence from constant folding.
If we were to ever make visitFNEG obey isFPImmLegal and change LowerConstantFP to emit ConstantFP+FNEG instead of FLI+FNEG, we would infinite loop.
…fneg (#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. See the PR thread llvm/llvm-project#149075 for furrther discussion about the degree to which isFPImmLegal and lowerConstantFP are consistent. We ultimately agreed it makes sense to add fli+fneg, but there may be other future cases where it doesn't make sense to match.
…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. See the PR thread llvm#149075 for furrther discussion about the degree to which isFPImmLegal and lowerConstantFP are consistent. We ultimately agreed it makes sense to add fli+fneg, but there may be other future cases where it doesn't make sense to match.
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.