[llvm] 8e9d50c - [InstSimplify] fold uno/ord comparison if fpclass is always NaN (#97763)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 9 14:44:51 PDT 2024
Author: Alex MacLean
Date: 2024-07-09T14:44:48-07:00
New Revision: 8e9d50cdd14b366249bbb61cb3a1d4586289bfee
URL: https://github.com/llvm/llvm-project/commit/8e9d50cdd14b366249bbb61cb3a1d4586289bfee
DIFF: https://github.com/llvm/llvm-project/commit/8e9d50cdd14b366249bbb61cb3a1d4586289bfee.diff
LOG: [InstSimplify] fold uno/ord comparison if fpclass is always NaN (#97763)
In InstSimplify we already fold `fcmp ord/uno` to a constant when both
operands are known to be non-NaN. This change slightly generalizes this
to also handle the case where either of the operands is known to always
be NaN.
Proof: https://alive2.llvm.org/ce/z/AhCmJN
Added:
Modified:
llvm/include/llvm/Analysis/ValueTracking.h
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/floating-point-compare.ll
llvm/test/Transforms/InstSimplify/known-never-nan.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index b7b78cb9edab3..354ad5bc95317 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -276,6 +276,8 @@ struct KnownFPClass {
return (KnownFPClasses & Mask) == fcNone;
}
+ bool isKnownAlways(FPClassTest Mask) const { return isKnownNever(~Mask); }
+
bool isUnknown() const {
return KnownFPClasses == fcAllFlags && !SignBit;
}
@@ -285,6 +287,9 @@ struct KnownFPClass {
return isKnownNever(fcNan);
}
+ /// Return true if it's known this must always be a nan.
+ bool isKnownAlwaysNaN() const { return isKnownAlways(fcNan); }
+
/// Return true if it's known this can never be an infinity.
bool isKnownNeverInfinity() const {
return isKnownNever(fcInf);
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 1b72f151e3692..868a7bf828700 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4117,9 +4117,17 @@ static Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
// This catches the 2 variable input case, constants are handled below as a
// class-like compare.
if (Pred == FCmpInst::FCMP_ORD || Pred == FCmpInst::FCMP_UNO) {
- if (FMF.noNaNs() || (isKnownNeverNaN(RHS, /*Depth=*/0, Q) &&
- isKnownNeverNaN(LHS, /*Depth=*/0, Q)))
+ KnownFPClass RHSClass =
+ computeKnownFPClass(RHS, fcAllFlags, /*Depth=*/0, Q);
+ KnownFPClass LHSClass =
+ computeKnownFPClass(LHS, fcAllFlags, /*Depth=*/0, Q);
+
+ if (FMF.noNaNs() ||
+ (RHSClass.isKnownNeverNaN() && LHSClass.isKnownNeverNaN()))
return ConstantInt::get(RetTy, Pred == FCmpInst::FCMP_ORD);
+
+ if (RHSClass.isKnownAlwaysNaN() || LHSClass.isKnownAlwaysNaN())
+ return ConstantInt::get(RetTy, Pred == CmpInst::FCMP_UNO);
}
const APFloat *C = nullptr;
diff --git a/llvm/test/Transforms/InstSimplify/floating-point-compare.ll b/llvm/test/Transforms/InstSimplify/floating-point-compare.ll
index 70f0321039ea9..e9d5c353cbccf 100644
--- a/llvm/test/Transforms/InstSimplify/floating-point-compare.ll
+++ b/llvm/test/Transforms/InstSimplify/floating-point-compare.ll
@@ -672,6 +672,38 @@ define i1 @assume_nonnan_x2_ord(float %x, float %y) {
ret i1 %cmp
}
+define i1 @assume_nan_x2_uno(float %x, float %y) {
+; CHECK-LABEL: @assume_nan_x2_uno(
+; CHECK-NEXT: [[UNO_X:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT: call void @llvm.assume(i1 [[UNO_X]])
+; CHECK-NEXT: [[UNO_Y:%.*]] = fcmp uno float [[Y:%.*]], 0.000000e+00
+; CHECK-NEXT: call void @llvm.assume(i1 [[UNO_Y]])
+; CHECK-NEXT: ret i1 true
+;
+ %uno.x = fcmp uno float %x, 0.0
+ call void @llvm.assume(i1 %uno.x)
+ %uno.y = fcmp uno float %y, 0.0
+ call void @llvm.assume(i1 %uno.y)
+ %cmp = fcmp uno float %x, %y
+ ret i1 %cmp
+}
+
+define i1 @assume_nan_x2_ord(float %x, float %y) {
+; CHECK-LABEL: @assume_nan_x2_ord(
+; CHECK-NEXT: [[UNO_X:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT: call void @llvm.assume(i1 [[UNO_X]])
+; CHECK-NEXT: [[UNO_Y:%.*]] = fcmp uno float [[Y:%.*]], 0.000000e+00
+; CHECK-NEXT: call void @llvm.assume(i1 [[UNO_Y]])
+; CHECK-NEXT: ret i1 false
+;
+ %uno.x = fcmp uno float %x, 0.0
+ call void @llvm.assume(i1 %uno.x)
+ %uno.y = fcmp uno float %y, 0.0
+ call void @llvm.assume(i1 %uno.y)
+ %cmp = fcmp ord float %x, %y
+ ret i1 %cmp
+}
+
define i1 @assume_nonan_x2_uno(float %x, float %y) {
; CHECK-LABEL: @assume_nonan_x2_uno(
; CHECK-NEXT: [[ORD_X:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
diff --git a/llvm/test/Transforms/InstSimplify/known-never-nan.ll b/llvm/test/Transforms/InstSimplify/known-never-nan.ll
index 49a48ae42d064..907eca0a856a8 100644
--- a/llvm/test/Transforms/InstSimplify/known-never-nan.ll
+++ b/llvm/test/Transforms/InstSimplify/known-never-nan.ll
@@ -512,12 +512,10 @@ define i1 @isKnownNeverNaN_nofpclass_callsite() {
declare nofpclass(sub norm zero inf) double @only_nans()
-; TODO: Could simplify to false
define i1 @isKnownNeverNaN_only_nans() {
; CHECK-LABEL: @isKnownNeverNaN_only_nans(
; CHECK-NEXT: [[CALL:%.*]] = call double @only_nans()
-; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[CALL]], [[CALL]]
-; CHECK-NEXT: ret i1 [[TMP]]
+; CHECK-NEXT: ret i1 false
;
%call = call double @only_nans()
%tmp = fcmp ord double %call, %call
More information about the llvm-commits
mailing list