diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 07950f5341d6c..ff9b9f4f8d121 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -5058,6 +5058,11 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, KnownRHS.isKnownNeverPosZero()) && (KnownLHS.isKnownNeverPosZero() || KnownRHS.isKnownNeverNegZero()))) { + // Don't take sign bit from NaN operands. + if (!KnownLHS.isKnownNeverNaN()) + KnownLHS.SignBit = std::nullopt; + if (!KnownRHS.isKnownNeverNaN()) + KnownRHS.SignBit = std::nullopt; if ((IID == Intrinsic::maximum || IID == Intrinsic::maximumnum || IID == Intrinsic::maxnum) && (KnownLHS.SignBit == false || KnownRHS.SignBit == false)) diff --git a/llvm/test/Transforms/InstCombine/is_fpclass.ll b/llvm/test/Transforms/InstCombine/is_fpclass.ll index c1809b8bec61c..b86b307e4c7fd 100644 --- a/llvm/test/Transforms/InstCombine/is_fpclass.ll +++ b/llvm/test/Transforms/InstCombine/is_fpclass.ll @@ -3922,6 +3922,38 @@ define i1 @test_class_is_not_psub_pnorm_pinf__dynamic(float %arg) #3 { ret i1 %class } +; Make sure we don't take sign bit from NaN operands. + +define i1 @minnum_qnan(i32 %x) { +; CHECK-LABEL: @minnum_qnan( +; CHECK-NEXT: entry: +; CHECK-NEXT: ret i1 true +; +entry: + %qnan_bits = or i32 %x, -5938 + %qnan = bitcast i32 %qnan_bits to float + %min = call float @llvm.minnum.f32(float %qnan, float 0.000000e+00) + %test = call i1 @llvm.is.fpclass.f32(float %min, i32 64) + ret i1 %test +} + +define i1 @minnum_qnan_commuted(i32 %x, float nofpclass(nnorm nsub nzero ninf nan) %y) { +; CHECK-LABEL: @minnum_qnan_commuted( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[QNAN_BITS:%.*]] = or i32 [[X:%.*]], -5938 +; CHECK-NEXT: [[QNAN:%.*]] = bitcast i32 [[QNAN_BITS]] to float +; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[Y:%.*]], float [[QNAN]]) +; CHECK-NEXT: [[TEST:%.*]] = call i1 @llvm.is.fpclass.f32(float [[MIN]], i32 64) +; CHECK-NEXT: ret i1 [[TEST]] +; +entry: + %qnan_bits = or i32 %x, -5938 + %qnan = bitcast i32 %qnan_bits to float + %min = call float @llvm.minnum.f32(float %y, float %qnan) + %test = call i1 @llvm.is.fpclass.f32(float %min, i32 64) + ret i1 %test +} + declare i1 @llvm.is.fpclass.f32(float, i32 immarg) declare i1 @llvm.is.fpclass.f64(double, i32 immarg) declare <2 x i1> @llvm.is.fpclass.v2f32(<2 x float>, i32 immarg)