[llvm] ea59be5 - [ValueTracking] Don't take sign bit from NaN operands (#157250)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 16 05:59:46 PDT 2025
Author: Yingwei Zheng
Date: 2025-09-16T20:59:42+08:00
New Revision: ea59be552f1db4f8f2e8a3edd909f17802339970
URL: https://github.com/llvm/llvm-project/commit/ea59be552f1db4f8f2e8a3edd909f17802339970
DIFF: https://github.com/llvm/llvm-project/commit/ea59be552f1db4f8f2e8a3edd909f17802339970.diff
LOG: [ValueTracking] Don't take sign bit from NaN operands (#157250)
Closes https://github.com/llvm/llvm-project/issues/157238.
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/InstCombine/is_fpclass.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 129823e0e98a3..73192a75fa507 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5070,6 +5070,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)
More information about the llvm-commits
mailing list