[llvm] [ValueTracking] Fix incorrect inferrence about the signbit of sqrt (PR #92510)
via llvm-commits
llvm-commits at lists.llvm.org
Fri May 17 01:03:02 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
@llvm/pr-subscribers-llvm-analysis
Author: Yingwei Zheng (dtcxzyw)
<details>
<summary>Changes</summary>
According to IEEE Std 754-2019, `sqrt` returns nan when the input is negative (except for -0). In this case, we cannot make assumptions about sign bit of the result.
BTW, alive2 seems to treat it as poison :( See https://github.com/AliveToolkit/alive2/issues/1037
Fixes https://github.com/llvm/llvm-project/issues/92217
---
Full diff: https://github.com/llvm/llvm-project/pull/92510.diff
3 Files Affected:
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+1-4)
- (modified) llvm/test/Transforms/InstCombine/known-bits.ll (+15)
- (modified) llvm/unittests/Analysis/ValueTrackingTest.cpp (+1-1)
``````````diff
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e8c5f9b3dc25d..0f754523ba351 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4940,11 +4940,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
// subnormal input could produce a negative zero output.
const Function *F = II->getFunction();
if (Q.IIQ.hasNoSignedZeros(II) ||
- (F && KnownSrc.isKnownNeverLogicalNegZero(*F, II->getType()))) {
+ (F && KnownSrc.isKnownNeverLogicalNegZero(*F, II->getType())))
Known.knownNot(fcNegZero);
- if (KnownSrc.isKnownNeverNaN())
- Known.signBitMustBeZero();
- }
break;
}
diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll
index 82cd24027e4e1..b4e79282f7012 100644
--- a/llvm/test/Transforms/InstCombine/known-bits.ll
+++ b/llvm/test/Transforms/InstCombine/known-bits.ll
@@ -1698,6 +1698,21 @@ define i32 @test_none(float nofpclass(all) %x) {
ret i32 %and
}
+; We cannot make assumptions about the sign of result of sqrt
+; when the input is a negative value (except for -0).
+define i1 @pr92217() {
+; CHECK-LABEL: @pr92217(
+; CHECK-NEXT: [[X:%.*]] = call float @llvm.sqrt.f32(float 0xC6DEBE9E60000000)
+; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X]] to i32
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %x = call float @llvm.sqrt.f32(float 0xC6DEBE9E60000000)
+ %y = bitcast float %x to i32
+ %cmp = icmp slt i32 %y, 0
+ ret i1 %cmp
+}
+
define i8 @test_icmp_add(i8 %n, i8 %n2, i8 %other) {
; CHECK-LABEL: @test_icmp_add(
; CHECK-NEXT: entry:
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index 8738af91b652b..a30db468c7729 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -2005,7 +2005,7 @@ TEST_F(ComputeKnownFPClassTest, SqrtNszSignBit) {
computeKnownFPClass(A4, M->getDataLayout(), fcAllFlags, 0, nullptr,
nullptr, nullptr, nullptr, /*UseInstrInfo=*/true);
EXPECT_EQ(fcPositive | fcQNan, UseInstrInfoNSZNoNan.KnownFPClasses);
- EXPECT_EQ(false, UseInstrInfoNSZNoNan.SignBit);
+ EXPECT_EQ(std::nullopt, UseInstrInfoNSZNoNan.SignBit);
KnownFPClass NoUseInstrInfoNSZNoNan =
computeKnownFPClass(A4, M->getDataLayout(), fcAllFlags, 0, nullptr,
``````````
</details>
https://github.com/llvm/llvm-project/pull/92510
More information about the llvm-commits
mailing list