Skip to content

Commit ea59be5

Browse files
authored
[ValueTracking] Don't take sign bit from NaN operands (#157250)
Closes #157238.
1 parent 18507a7 commit ea59be5

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5070,6 +5070,11 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
50705070
KnownRHS.isKnownNeverPosZero()) &&
50715071
(KnownLHS.isKnownNeverPosZero() ||
50725072
KnownRHS.isKnownNeverNegZero()))) {
5073+
// Don't take sign bit from NaN operands.
5074+
if (!KnownLHS.isKnownNeverNaN())
5075+
KnownLHS.SignBit = std::nullopt;
5076+
if (!KnownRHS.isKnownNeverNaN())
5077+
KnownRHS.SignBit = std::nullopt;
50735078
if ((IID == Intrinsic::maximum || IID == Intrinsic::maximumnum ||
50745079
IID == Intrinsic::maxnum) &&
50755080
(KnownLHS.SignBit == false || KnownRHS.SignBit == false))

llvm/test/Transforms/InstCombine/is_fpclass.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3922,6 +3922,38 @@ define i1 @test_class_is_not_psub_pnorm_pinf__dynamic(float %arg) #3 {
39223922
ret i1 %class
39233923
}
39243924

3925+
; Make sure we don't take sign bit from NaN operands.
3926+
3927+
define i1 @minnum_qnan(i32 %x) {
3928+
; CHECK-LABEL: @minnum_qnan(
3929+
; CHECK-NEXT: entry:
3930+
; CHECK-NEXT: ret i1 true
3931+
;
3932+
entry:
3933+
%qnan_bits = or i32 %x, -5938
3934+
%qnan = bitcast i32 %qnan_bits to float
3935+
%min = call float @llvm.minnum.f32(float %qnan, float 0.000000e+00)
3936+
%test = call i1 @llvm.is.fpclass.f32(float %min, i32 64)
3937+
ret i1 %test
3938+
}
3939+
3940+
define i1 @minnum_qnan_commuted(i32 %x, float nofpclass(nnorm nsub nzero ninf nan) %y) {
3941+
; CHECK-LABEL: @minnum_qnan_commuted(
3942+
; CHECK-NEXT: entry:
3943+
; CHECK-NEXT: [[QNAN_BITS:%.*]] = or i32 [[X:%.*]], -5938
3944+
; CHECK-NEXT: [[QNAN:%.*]] = bitcast i32 [[QNAN_BITS]] to float
3945+
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[Y:%.*]], float [[QNAN]])
3946+
; CHECK-NEXT: [[TEST:%.*]] = call i1 @llvm.is.fpclass.f32(float [[MIN]], i32 64)
3947+
; CHECK-NEXT: ret i1 [[TEST]]
3948+
;
3949+
entry:
3950+
%qnan_bits = or i32 %x, -5938
3951+
%qnan = bitcast i32 %qnan_bits to float
3952+
%min = call float @llvm.minnum.f32(float %y, float %qnan)
3953+
%test = call i1 @llvm.is.fpclass.f32(float %min, i32 64)
3954+
ret i1 %test
3955+
}
3956+
39253957
declare i1 @llvm.is.fpclass.f32(float, i32 immarg)
39263958
declare i1 @llvm.is.fpclass.f64(double, i32 immarg)
39273959
declare <2 x i1> @llvm.is.fpclass.v2f32(<2 x float>, i32 immarg)

0 commit comments

Comments
 (0)