Skip to content

Commit 04ae6e6

Browse files
authored
[ValueTracking] Fix incorrect inferrence about the signbit of sqrt (#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. Fixes #92217
1 parent 36899d6 commit 04ae6e6

File tree

3 files changed

+40
-5
lines changed

3 files changed

+40
-5
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4940,11 +4940,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
49404940
// subnormal input could produce a negative zero output.
49414941
const Function *F = II->getFunction();
49424942
if (Q.IIQ.hasNoSignedZeros(II) ||
4943-
(F && KnownSrc.isKnownNeverLogicalNegZero(*F, II->getType()))) {
4943+
(F && KnownSrc.isKnownNeverLogicalNegZero(*F, II->getType())))
49444944
Known.knownNot(fcNegZero);
4945-
if (KnownSrc.isKnownNeverNaN())
4946-
Known.signBitMustBeZero();
4947-
}
49484945

49494946
break;
49504947
}

llvm/test/Transforms/InstCombine/known-bits.ll

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,6 +1698,44 @@ define i32 @test_none(float nofpclass(all) %x) {
16981698
ret i32 %and
16991699
}
17001700

1701+
; We cannot make assumptions about the sign of result of sqrt
1702+
; when the input is a negative value (except for -0).
1703+
define i1 @pr92217() {
1704+
; CHECK-LABEL: @pr92217(
1705+
; CHECK-NEXT: [[X:%.*]] = call float @llvm.sqrt.f32(float 0xC6DEBE9E60000000)
1706+
; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X]] to i32
1707+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 0
1708+
; CHECK-NEXT: ret i1 [[CMP]]
1709+
;
1710+
%x = call float @llvm.sqrt.f32(float 0xC6DEBE9E60000000)
1711+
%y = bitcast float %x to i32
1712+
%cmp = icmp slt i32 %y, 0
1713+
ret i1 %cmp
1714+
}
1715+
1716+
define i1 @sqrt_negative_input(float nofpclass(nan zero pnorm psub pinf) %a) {
1717+
; CHECK-LABEL: @sqrt_negative_input(
1718+
; CHECK-NEXT: [[X:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]])
1719+
; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X]] to i32
1720+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 0
1721+
; CHECK-NEXT: ret i1 [[CMP]]
1722+
;
1723+
%x = call float @llvm.sqrt.f32(float %a)
1724+
%y = bitcast float %x to i32
1725+
%cmp = icmp slt i32 %y, 0
1726+
ret i1 %cmp
1727+
}
1728+
1729+
define i1 @sqrt_negative_input_nnan(float nofpclass(nan zero pnorm psub pinf) %a) {
1730+
; CHECK-LABEL: @sqrt_negative_input_nnan(
1731+
; CHECK-NEXT: ret i1 false
1732+
;
1733+
%x = call nnan float @llvm.sqrt.f32(float %a)
1734+
%y = bitcast float %x to i32
1735+
%cmp = icmp slt i32 %y, 0
1736+
ret i1 %cmp
1737+
}
1738+
17011739
define i8 @test_icmp_add(i8 %n, i8 %n2, i8 %other) {
17021740
; CHECK-LABEL: @test_icmp_add(
17031741
; CHECK-NEXT: entry:

llvm/unittests/Analysis/ValueTrackingTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2005,7 +2005,7 @@ TEST_F(ComputeKnownFPClassTest, SqrtNszSignBit) {
20052005
computeKnownFPClass(A4, M->getDataLayout(), fcAllFlags, 0, nullptr,
20062006
nullptr, nullptr, nullptr, /*UseInstrInfo=*/true);
20072007
EXPECT_EQ(fcPositive | fcQNan, UseInstrInfoNSZNoNan.KnownFPClasses);
2008-
EXPECT_EQ(false, UseInstrInfoNSZNoNan.SignBit);
2008+
EXPECT_EQ(std::nullopt, UseInstrInfoNSZNoNan.SignBit);
20092009

20102010
KnownFPClass NoUseInstrInfoNSZNoNan =
20112011
computeKnownFPClass(A4, M->getDataLayout(), fcAllFlags, 0, nullptr,

0 commit comments

Comments
 (0)