[llvm] [Transforms] Resolve FIXME: No Lowering of FNeg to FMul unless it is safe (PR #85252)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 14 13:31:06 PDT 2024
https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/85252
>From f1fb8aa3b4ecbaa3143de69c9554b3c9f1e677f9 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Thu, 14 Mar 2024 14:17:00 -0400
Subject: [PATCH 1/2] [Transforms] Pre-commit tests (NFC)
---
.../Transforms/Reassociate/fast-basictest.ll | 58 +++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/llvm/test/Transforms/Reassociate/fast-basictest.ll b/llvm/test/Transforms/Reassociate/fast-basictest.ll
index c1842d0cde456c..cd0be7aed86c3f 100644
--- a/llvm/test/Transforms/Reassociate/fast-basictest.ll
+++ b/llvm/test/Transforms/Reassociate/fast-basictest.ll
@@ -578,3 +578,61 @@ define float @test18(float %A, float %B) {
%Z = fadd fast float %Y, 1.200000e+01
ret float %Z
}
+
+; Do not fneg fast float unless it has nnan
+
+define float @scalar(float %a) {
+; CHECK-LABEL: @scalar(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[NEG:%.*]] = fmul fast float [[A:%.*]], 2.000000e+00
+; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[NEG]], [[A]]
+; CHECK-NEXT: ret float [[MUL]]
+;
+entry:
+ %b = fmul fast float %a, -2.0
+ %neg = fneg fast float %a
+ %mul = fmul fast float %neg, %b
+ ret float %mul
+}
+
+define float @scalar_nnan(float %a) {
+; CHECK-LABEL: @scalar_nnan(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[NEG:%.*]] = fmul fast float [[A:%.*]], 2.000000e+00
+; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[NEG]], [[A]]
+; CHECK-NEXT: ret float [[MUL]]
+;
+entry:
+ %b = fmul fast nnan float %a, -2.0
+ %neg = fneg fast nnan float %a
+ %mul = fmul fast nnan float %neg, %b
+ ret float %mul
+}
+
+define <4 x float> @vector(<4 x float> %a) {
+; CHECK-LABEL: @vector(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[NEG:%.*]] = fmul fast <4 x float> [[A:%.*]], <float -1.000000e+00, float -2.000000e+00, float 3.000000e+00, float -4.000000e+00>
+; CHECK-NEXT: [[MUL:%.*]] = fmul fast <4 x float> [[NEG]], [[A]]
+; CHECK-NEXT: ret <4 x float> [[MUL]]
+;
+entry:
+ %b = fmul fast <4 x float> %a, <float 1.0, float 2.0, float -3.0, float 4.0>
+ %neg = fneg fast <4 x float> %a
+ %mul = fmul fast <4 x float> %neg, %b
+ ret <4 x float> %mul
+}
+
+define <4 x float> @vector_nnan(<4 x float> %a) {
+; CHECK-LABEL: @vector_nnan(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[NEG:%.*]] = fmul fast <4 x float> [[A:%.*]], <float -1.000000e+00, float -2.000000e+00, float 3.000000e+00, float -4.000000e+00>
+; CHECK-NEXT: [[MUL:%.*]] = fmul fast <4 x float> [[NEG]], [[A]]
+; CHECK-NEXT: ret <4 x float> [[MUL]]
+;
+entry:
+ %b = fmul fast nnan <4 x float> %a, <float 1.0, float 2.0, float -3.0, float 4.0>
+ %neg = fneg fast nnan <4 x float> %a
+ %mul = fmul fast <4 x float> %neg, %b
+ ret <4 x float> %mul
+}
>From 8fa285b6ce4c3ce79d04887fbaf3c65941e3405f Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Thu, 14 Mar 2024 11:43:14 -0400
Subject: [PATCH 2/2] [Transforms] Resolve FIXME: No Lowering of FNeg to FMul
unless it is safe or flags are specified
---
llvm/lib/Transforms/Scalar/Reassociate.cpp | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp
index d91320863e241d..971cf88c3394d7 100644
--- a/llvm/lib/Transforms/Scalar/Reassociate.cpp
+++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp
@@ -287,11 +287,15 @@ static Instruction *CreateNeg(Value *S1, const Twine &Name,
static BinaryOperator *LowerNegateToMultiply(Instruction *Neg) {
assert((isa<UnaryOperator>(Neg) || isa<BinaryOperator>(Neg)) &&
"Expected a Negate!");
- // FIXME: It's not safe to lower a unary FNeg into a FMul by -1.0.
unsigned OpNo = isa<BinaryOperator>(Neg) ? 1 : 0;
Type *Ty = Neg->getType();
- Constant *NegOne = Ty->isIntOrIntVectorTy() ?
- ConstantInt::getAllOnesValue(Ty) : ConstantFP::get(Ty, -1.0);
+ // Only lower to FMul if the operation is not a unary FNeg or Neg has the
+ // correct flags.
+ if (Ty->isFPOrFPVectorTy() && isa<UnaryOperator>(Neg) && !Neg->hasNoNaNs())
+ return nullptr;
+
+ Constant *NegOne = Ty->isIntOrIntVectorTy() ? ConstantInt::getAllOnesValue(Ty)
+ : ConstantFP::get(Ty, -1.0);
BinaryOperator *Res =
CreateMul(Neg->getOperand(OpNo), NegOne, "", Neg->getIterator(), Neg);
More information about the llvm-commits
mailing list