[llvm] [ValueTracking] Fix incorrect inferrence about the signbit of sqrt (PR #92510)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Fri May 17 01:02:29 PDT 2024
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/92510
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
>From 638fee4c6e56e1997eaf252d5f1d29532b186d8b Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 17 May 2024 15:09:12 +0800
Subject: [PATCH 1/2] [ValueTracking] Add pre-commit tests. NFC.
---
llvm/test/Transforms/InstCombine/known-bits.ll | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll
index 82cd24027e4e1..99da05d184ae6 100644
--- a/llvm/test/Transforms/InstCombine/known-bits.ll
+++ b/llvm/test/Transforms/InstCombine/known-bits.ll
@@ -1698,6 +1698,18 @@ 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: ret i1 false
+;
+ %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:
>From 6476a5525c7f8f5cfa0515c899da4f472df7e2c3 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 17 May 2024 15:54:11 +0800
Subject: [PATCH 2/2] [ValueTracking] Fix incorrect inferrence about the
signbit of sqrt
---
llvm/lib/Analysis/ValueTracking.cpp | 5 +----
llvm/test/Transforms/InstCombine/known-bits.ll | 5 ++++-
llvm/unittests/Analysis/ValueTrackingTest.cpp | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
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 99da05d184ae6..b4e79282f7012 100644
--- a/llvm/test/Transforms/InstCombine/known-bits.ll
+++ b/llvm/test/Transforms/InstCombine/known-bits.ll
@@ -1702,7 +1702,10 @@ define i32 @test_none(float nofpclass(all) %x) {
; when the input is a negative value (except for -0).
define i1 @pr92217() {
; CHECK-LABEL: @pr92217(
-; CHECK-NEXT: ret i1 false
+; 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
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,
More information about the llvm-commits
mailing list