diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2023-04-25 19:03:18 -0400 |
---|---|---|
committer | Matt Arsenault <arsenm2@gmail.com> | 2023-06-20 21:30:09 -0400 |
commit | 06f942016b6b1e376334937a3b132232e311104f (patch) | |
tree | a46e72e9533418b41376aed84587330c20a4540d | |
parent | 7d6b8249faba3c761de5de66f3dafb96a3fd9047 (diff) | |
download | llvm-06f942016b6b1e376334937a3b132232e311104f.zip llvm-06f942016b6b1e376334937a3b132232e311104f.tar.gz llvm-06f942016b6b1e376334937a3b132232e311104f.tar.bz2 |
ValueTracking: Ignore -0 for nsz sqrt with UseInstrInfo in computeKnownFPClass
This avoids a regression when SignBitMustBeZero is moved to computeKnownFPClass.
-rw-r--r-- | llvm/include/llvm/Analysis/InstructionSimplify.h | 6 | ||||
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 3 | ||||
-rw-r--r-- | llvm/unittests/Analysis/ValueTrackingTest.cpp | 74 |
3 files changed, 82 insertions, 1 deletions
diff --git a/llvm/include/llvm/Analysis/InstructionSimplify.h b/llvm/include/llvm/Analysis/InstructionSimplify.h index c3a9c20..df07846 100644 --- a/llvm/include/llvm/Analysis/InstructionSimplify.h +++ b/llvm/include/llvm/Analysis/InstructionSimplify.h @@ -83,6 +83,12 @@ struct InstrInfoQuery { return cast<PossiblyExactOperator>(Op)->isExact(); return false; } + + template <class InstT> bool hasNoSignedZeros(const InstT *Op) const { + if (UseInstrInfo) + return Op->hasNoSignedZeros(); + return false; + } }; struct SimplifyQuery { diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 88ed92e..66e810c 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4469,7 +4469,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, // If the input denormal mode could be PreserveSign, a negative // subnormal input could produce a negative zero output. const Function *F = II->getFunction(); - if (F && KnownSrc.isKnownNeverLogicalNegZero(*F, II->getType())) { + if (Q.IIQ.hasNoSignedZeros(II) || + (F && KnownSrc.isKnownNeverLogicalNegZero(*F, II->getType()))) { Known.knownNot(fcNegZero); if (KnownSrc.isKnownNeverNaN()) Known.SignBit = false; diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index f8910ea..5cc76e2 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -1890,6 +1890,80 @@ TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_PInf) { EXPECT_EQ(fcNone, UgtClass); } +TEST_F(ComputeKnownFPClassTest, SqrtNszSignBit) { + parseAssembly( + "declare float @llvm.sqrt.f32(float)\n" + "define float @test(float %arg, float nofpclass(nan) %arg.nnan) {\n" + " %A = call float @llvm.sqrt.f32(float %arg)\n" + " %A2 = call nsz float @llvm.sqrt.f32(float %arg)\n" + " %A3 = call float @llvm.sqrt.f32(float %arg.nnan)\n" + " %A4 = call nsz float @llvm.sqrt.f32(float %arg.nnan)\n" + " ret float %A\n" + "}\n"); + + const FPClassTest SqrtMask = fcPositive | fcNegZero | fcNan; + const FPClassTest NszSqrtMask = fcPositive | fcNan; + + { + KnownFPClass UseInstrInfo = + computeKnownFPClass(A, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/true); + EXPECT_EQ(SqrtMask, UseInstrInfo.KnownFPClasses); + EXPECT_EQ(std::nullopt, UseInstrInfo.SignBit); + + KnownFPClass NoUseInstrInfo = + computeKnownFPClass(A, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/false); + EXPECT_EQ(SqrtMask, NoUseInstrInfo.KnownFPClasses); + EXPECT_EQ(std::nullopt, NoUseInstrInfo.SignBit); + } + + { + KnownFPClass UseInstrInfoNSZ = + computeKnownFPClass(A2, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/true); + EXPECT_EQ(NszSqrtMask, UseInstrInfoNSZ.KnownFPClasses); + EXPECT_EQ(std::nullopt, UseInstrInfoNSZ.SignBit); + + KnownFPClass NoUseInstrInfoNSZ = + computeKnownFPClass(A2, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/false); + EXPECT_EQ(SqrtMask, NoUseInstrInfoNSZ.KnownFPClasses); + EXPECT_EQ(std::nullopt, NoUseInstrInfoNSZ.SignBit); + } + + { + KnownFPClass UseInstrInfoNoNan = + computeKnownFPClass(A3, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/true); + EXPECT_EQ(fcPositive | fcNegZero | fcQNan, + UseInstrInfoNoNan.KnownFPClasses); + EXPECT_EQ(std::nullopt, UseInstrInfoNoNan.SignBit); + + KnownFPClass NoUseInstrInfoNoNan = + computeKnownFPClass(A3, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/false); + EXPECT_EQ(fcPositive | fcNegZero | fcQNan, + NoUseInstrInfoNoNan.KnownFPClasses); + EXPECT_EQ(std::nullopt, NoUseInstrInfoNoNan.SignBit); + } + + { + KnownFPClass UseInstrInfoNSZNoNan = + computeKnownFPClass(A4, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/true); + EXPECT_EQ(fcPositive | fcQNan, UseInstrInfoNSZNoNan.KnownFPClasses); + EXPECT_EQ(false, UseInstrInfoNSZNoNan.SignBit); + + KnownFPClass NoUseInstrInfoNSZNoNan = + computeKnownFPClass(A4, M->getDataLayout(), fcAllFlags, 0, nullptr, + nullptr, nullptr, nullptr, /*UseInstrInfo=*/false); + EXPECT_EQ(fcPositive | fcNegZero | fcQNan, + NoUseInstrInfoNSZNoNan.KnownFPClasses); + EXPECT_EQ(std::nullopt, NoUseInstrInfoNSZNoNan.SignBit); + } +} + TEST_F(ValueTrackingTest, isNonZeroRecurrence) { parseAssembly(R"( define i1 @test(i8 %n, i8 %r) { |