[llvm-branch-commits] [llvm] ADT: Add utility functions for comparing FPClassTest (PR #175380)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Jan 10 11:37:10 PST 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/175380
Add utility functions for checking if less and greater queries
are known to not evaluate to true. This will permit more precise
folding of min/max intrinsics. The test is kind of a mess.
>From 2a832b58bc96fcdbd1a376d9c7594fc299f8207e Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 9 Jan 2026 08:39:23 +0100
Subject: [PATCH] ADT: Add utility functions for comparing FPClassTest
Add utility functions for checking if less and greater queries
are known to not evaluate to true. This will permit more precise
folding of min/max intrinsics. The test is kind of a mess.
---
llvm/include/llvm/ADT/FloatingPointMode.h | 34 ++
llvm/lib/Support/FloatingPointMode.cpp | 61 +++
llvm/unittests/ADT/FloatingPointMode.cpp | 561 ++++++++++++++++++++++
3 files changed, 656 insertions(+)
diff --git a/llvm/include/llvm/ADT/FloatingPointMode.h b/llvm/include/llvm/ADT/FloatingPointMode.h
index 0605e0b4f4cf9..a462dc1dd6ce4 100644
--- a/llvm/include/llvm/ADT/FloatingPointMode.h
+++ b/llvm/include/llvm/ADT/FloatingPointMode.h
@@ -285,6 +285,40 @@ LLVM_ABI FPClassTest unknown_sign(FPClassTest Mask);
/// Write a human readable form of \p Mask to \p OS
LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, FPClassTest Mask);
+/// Returns true if all values in \p LHS must be less than or equal to those in
+/// \p RHS. That is, the comparison `fcmp ogt LHS, RHS` will always return
+/// false.
+///
+/// If \p OrderedZeroSign is true, -0 will be treated as ordered less than +0,
+/// unlike fcmp.
+LLVM_ABI bool cannotOrderStrictlyGreater(FPClassTest LHS, FPClassTest RHS,
+ bool OrderedZeroSign = false);
+
+/// Returns true if all values in \p LHS must be less than those in \p RHS. That
+/// is, the comparison `fcmp oge LHS, RHS` will always return false.
+//
+// If \p OrderedZeroSign is true, -0 will be treated as ordered less than +0,
+// unlike fcmp.
+LLVM_ABI bool cannotOrderStrictlyGreaterEq(FPClassTest LHS, FPClassTest RHS,
+ bool OrderedZeroSign = false);
+
+/// Returns true if all values in \p LHS must be greater than or equal to those
+/// in \p RHS. That is, the comparison `fcmp olt LHS, RHS` will always return
+/// false.
+///
+/// If \p OrderedZeroSign is true, -0 will be treated as ordered less than +0,
+/// unlike fcmp.
+LLVM_ABI bool cannotOrderStrictlyLess(FPClassTest LHS, FPClassTest RHS,
+ bool OrderedZeroSign = false);
+
+/// Returns true if all values in \p LHS must be greater than to those in \p
+/// RHS. That is, the comparison `fcmp ole LHS, RHS` will always return false.
+///
+/// If \p OrderedZeroSign is true, -0 will be treated as ordered less than +0,
+/// unlike fcmp.
+LLVM_ABI bool cannotOrderStrictlyLessEq(FPClassTest LHS, FPClassTest RHS,
+ bool OrderedZeroSign = false);
+
} // namespace llvm
#endif // LLVM_ADT_FLOATINGPOINTMODE_H
diff --git a/llvm/lib/Support/FloatingPointMode.cpp b/llvm/lib/Support/FloatingPointMode.cpp
index 5a2836eb82434..a4059f9ad3083 100644
--- a/llvm/lib/Support/FloatingPointMode.cpp
+++ b/llvm/lib/Support/FloatingPointMode.cpp
@@ -106,3 +106,64 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, FPClassTest Mask) {
OS << ')';
return OS;
}
+
+static bool cannotOrderStrictlyGreaterImpl(FPClassTest LHS, FPClassTest RHS,
+ bool OrEqual, bool OrderedZero) {
+ LHS &= ~fcNan;
+ RHS &= ~fcNan;
+
+ if (LHS == fcNone || RHS == fcNone)
+ return true;
+
+ FPClassTest Intersect = LHS & RHS;
+ FPClassTest LowestBitRHS = static_cast<FPClassTest>(RHS & -RHS);
+ FPClassTest HighestBitLHS = static_cast<FPClassTest>(1 << Log2_32(LHS));
+
+ if (!OrderedZero) {
+ // Introduce conflict in zero bits if we're treating them as equal.
+ if (LowestBitRHS == fcNegZero)
+ LowestBitRHS = fcPosZero;
+ if (HighestBitLHS == fcNegZero)
+ HighestBitLHS = fcPosZero;
+ }
+
+ if (LowestBitRHS > HighestBitLHS) {
+ assert(Intersect == fcNone);
+ return true;
+ }
+
+ if (LowestBitRHS < HighestBitLHS)
+ return false;
+
+ constexpr FPClassTest ExactValuesMask = fcZero | fcInf;
+
+ if ((LowestBitRHS & ExactValuesMask) == fcNone)
+ return false;
+
+ if (OrEqual) {
+
+ return (LowestBitRHS & ExactValuesMask) == fcNone;
+ }
+
+ return (LowestBitRHS & ExactValuesMask) != fcNone;
+}
+
+bool llvm::cannotOrderStrictlyGreater(FPClassTest LHS, FPClassTest RHS,
+ bool OrderedZeroSign) {
+ return cannotOrderStrictlyGreaterImpl(LHS, RHS, false, OrderedZeroSign);
+}
+
+bool llvm::cannotOrderStrictlyGreaterEq(FPClassTest LHS, FPClassTest RHS,
+ bool OrderedZeroSign) {
+ return cannotOrderStrictlyGreaterImpl(LHS, RHS, true, OrderedZeroSign);
+}
+
+bool llvm::cannotOrderStrictlyLess(FPClassTest LHS, FPClassTest RHS,
+ bool OrderedZeroSign) {
+ return cannotOrderStrictlyGreaterImpl(RHS, LHS, false, OrderedZeroSign);
+}
+
+bool llvm::cannotOrderStrictlyLessEq(FPClassTest LHS, FPClassTest RHS,
+ bool OrderedZeroSign) {
+ return cannotOrderStrictlyGreaterImpl(RHS, LHS, true, OrderedZeroSign);
+}
diff --git a/llvm/unittests/ADT/FloatingPointMode.cpp b/llvm/unittests/ADT/FloatingPointMode.cpp
index b87507625542e..870a080cabcb7 100644
--- a/llvm/unittests/ADT/FloatingPointMode.cpp
+++ b/llvm/unittests/ADT/FloatingPointMode.cpp
@@ -13,6 +13,11 @@ using namespace llvm;
namespace {
+static constexpr FPClassTest OrderedLessThanZeroMask =
+ fcNegSubnormal | fcNegNormal | fcNegInf;
+static constexpr FPClassTest OrderedGreaterThanZeroMask =
+ fcPosSubnormal | fcPosNormal | fcPosInf;
+
TEST(FloatingPointModeTest, ParseDenormalFPAttributeComponent) {
EXPECT_EQ(DenormalMode::IEEE, parseDenormalFPAttributeComponent("ieee"));
EXPECT_EQ(DenormalMode::IEEE, parseDenormalFPAttributeComponent(""));
@@ -226,4 +231,560 @@ TEST(FloatingPointModeTest, DenormalModePredicates) {
EXPECT_FALSE(DenormalMode::getIEEE().inputsAreZero());
EXPECT_FALSE(DenormalMode::getDynamic().inputsAreZero());
}
+
+#define TEST_ORDERED_LT(a, b) \
+ EXPECT_TRUE(cannotOrderStrictlyGreater(a, b)); \
+ EXPECT_FALSE(cannotOrderStrictlyGreater(b, a));
+
+TEST(FloatingPointModeTest, cannotOrderStrictlyGreater) {
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNone, fcNone));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcAllFlags, fcAllFlags));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNan, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcQNan, fcQNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcSNan, fcSNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcSNan, fcQNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcQNan, fcSNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcQNan, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcSNan, fcNan));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegInf, fcSNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegInf, fcQNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegInf, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcSNan, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcQNan, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNan, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegInf, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegZero, fcPosZero));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegZero, fcPosZero, true));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcPosZero, fcNegZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcPosZero, fcNegZero, true));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcPosZero, fcPosZero));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcPosZero, fcPosZero, true));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegZero, fcNegZero));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegZero, fcNegZero, true));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegSubnormal, fcNegZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcNegZero, fcNegSubnormal));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegZero, fcPosSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcPosSubnormal, fcNegZero));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcNegZero, fcSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcSubnormal, fcNegZero));
+
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcPosZero, fcPosSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcPosSubnormal, fcPosZero));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcPosZero, fcNegSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcPosZero, fcNegSubnormal, true));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcZero, fcSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcZero, fcSubnormal, true));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcZero, fcNegSubnormal));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcZero, fcPosSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcPosSubnormal, fcZero));
+
+ TEST_ORDERED_LT(fcNegInf, fcNegNormal);
+ TEST_ORDERED_LT(fcNegInf, fcNegSubnormal);
+ TEST_ORDERED_LT(fcNegInf, fcNegZero);
+ TEST_ORDERED_LT(fcNegInf, fcPosZero);
+ TEST_ORDERED_LT(fcNegInf, fcPosSubnormal);
+ TEST_ORDERED_LT(fcNegInf, fcPosNormal);
+ TEST_ORDERED_LT(fcNegInf, fcPosInf);
+
+ TEST_ORDERED_LT(fcNegNormal, fcPosNormal);
+ TEST_ORDERED_LT(fcNegNormal, fcPositive);
+ TEST_ORDERED_LT(fcNegNormal, fcPositive | fcNan);
+ TEST_ORDERED_LT(fcNegNormal | fcNan, fcPositive | fcNan);
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegNormal, fcPosNormal | fcNan));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcPosNormal | fcNan, fcNegNormal));
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreater(fcPosNormal | fcNan, fcNegNormal | fcNan));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcNegNormal | fcNan, fcNegNormal));
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreater(fcNegNormal | fcNan, fcNegNormal | fcNan));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegInf, ~fcNegInf));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(~fcNegInf, fcNegInf));
+
+ TEST_ORDERED_LT(fcNegInf, ~(fcNegInf | fcNan));
+ TEST_ORDERED_LT(fcNegative, fcPositive);
+ TEST_ORDERED_LT(fcNegFinite, fcPosFinite);
+ TEST_ORDERED_LT(fcNegZero, fcPosInf);
+ TEST_ORDERED_LT(fcPosZero, fcPosInf);
+ TEST_ORDERED_LT(fcZero, fcPosInf);
+
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcNegZero, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegInf, fcNegZero));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcZero, fcInf));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcInf, fcZero));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcZero, fcInf | fcNan));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcInf | fcNan, fcZero));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegInf | fcNan, fcZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcPosInf | fcNan, fcZero));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcZero | fcNan, fcInf));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcInf, fcZero | fcNan));
+
+ TEST_ORDERED_LT(OrderedLessThanZeroMask, OrderedGreaterThanZeroMask);
+ TEST_ORDERED_LT(OrderedLessThanZeroMask, OrderedGreaterThanZeroMask | fcNan);
+
+ TEST_ORDERED_LT(OrderedLessThanZeroMask | fcNegZero,
+ OrderedGreaterThanZeroMask);
+ TEST_ORDERED_LT(OrderedLessThanZeroMask | fcPosZero,
+ OrderedGreaterThanZeroMask);
+ TEST_ORDERED_LT(OrderedLessThanZeroMask | fcZero, OrderedGreaterThanZeroMask);
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegZero, fcPosZero));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegZero, fcPosZero, true));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcPosZero, fcNegZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcPosZero, fcNegZero, true));
+
+ TEST_ORDERED_LT(fcNegZero, fcPosSubnormal);
+ TEST_ORDERED_LT(fcNegZero, fcPosZero | fcPosSubnormal);
+ TEST_ORDERED_LT(fcNegZero, OrderedGreaterThanZeroMask);
+
+ EXPECT_FALSE(cannotOrderStrictlyGreater(OrderedLessThanZeroMask,
+ OrderedLessThanZeroMask | fcNan));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(OrderedLessThanZeroMask | fcNan,
+ OrderedLessThanZeroMask | fcNan));
+
+ TEST_ORDERED_LT(fcZero, fcPosInf);
+ TEST_ORDERED_LT(fcZero, fcPosInf | fcNan);
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcZero | fcNan, fcPosInf));
+
+ TEST_ORDERED_LT(fcPosNormal, fcPosInf);
+ TEST_ORDERED_LT(fcPosNormal, fcPosInf | fcNan);
+
+ TEST_ORDERED_LT(fcNegInf, fcPosInf);
+ TEST_ORDERED_LT(fcNegInf | fcNegZero, fcPosInf);
+
+ EXPECT_TRUE(
+ cannotOrderStrictlyGreater(fcNegInf | fcNegZero, fcZero | fcPosInf));
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreater(fcZero | fcPosInf, fcNegInf | fcNegZero));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegInf | fcNegZero,
+ fcZero | fcPosInf, true));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcZero | fcPosInf,
+ fcNegInf | fcNegZero, true));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegInf | fcNegZero,
+ fcZero | fcPosInf | fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegInf | fcNegZero,
+ fcPosZero | fcPosInf | fcNan));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcPosInf, fcPosInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegInf, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcPosZero, fcPosZero));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegZero, fcNegZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcNegSubnormal, fcNegSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcPosSubnormal, fcPosSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcNegNormal, fcNegNormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcPosNormal, fcPosNormal));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcFinite, fcFinite));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcFinite, fcInf));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcInf, fcInf));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreater(fcPosInf, ~fcPosInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreater(~fcPosInf, fcPosInf));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreater(fcNegInf, ~fcNegInf));
+ EXPECT_FALSE(cannotOrderStrictlyGreater(~fcNegInf, fcNegInf));
+}
+
+TEST(FloatingPointModeTest, cannotOrderStrictlyGreaterEq) {
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNone, fcNone));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcAllFlags, fcAllFlags));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNan, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcQNan, fcQNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcSNan, fcSNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcSNan, fcQNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcQNan, fcSNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcQNan, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcSNan, fcNan));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegInf, fcSNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegInf, fcQNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegInf, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcSNan, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcQNan, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNan, fcNegInf));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegInf, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegZero, fcPosZero,
+ /*OrderedZeroSign=*/true));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegZero, fcPosZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosZero, fcNegZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosZero, fcNegZero,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosZero, fcPosZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosZero, fcPosZero,
+ /*OrderedZeroSign=*/true));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegZero, fcNegZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegZero, fcNegZero,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(OrderedLessThanZeroMask,
+ OrderedLessThanZeroMask));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(OrderedLessThanZeroMask,
+ OrderedLessThanZeroMask | fcNan));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(OrderedLessThanZeroMask,
+ OrderedGreaterThanZeroMask));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(OrderedLessThanZeroMask,
+ OrderedGreaterThanZeroMask | fcNan));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(OrderedLessThanZeroMask | fcNan,
+ OrderedGreaterThanZeroMask));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegZero, fcNegZero | fcNan));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegZero | fcNan, fcNegZero));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegZero, fcPosZero));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegZero, fcPosZero,
+ /*OrderedZeroSign=*/true));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosZero, fcNegZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegZero | fcNan, fcPosZero));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegZero | fcNan, fcPosZero,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosZero | fcNan, fcNegZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegZero, fcPosZero | fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegZero, fcPosZero | fcNan,
+ /*OrderedZeroSign=*/true));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosZero, fcNegZero | fcNan));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegZero, fcZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcZero, fcNegZero,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcZero, fcPosZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcZero, fcPosZero,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosInf, fcPosInf));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosInf, fcPosInf | fcNan));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosInf | fcNan, fcPosInf));
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcPosInf | fcNan, fcPosInf | fcNan));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegSubnormal, fcPosZero));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegSubnormal, fcNegZero));
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcNegSubnormal | fcNegZero, fcNegZero));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosSubnormal, fcZero));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegSubnormal, fcZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcSubnormal, fcZero));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcZero, fcPosInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcZero, fcPosInf | fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcZero | fcNan, fcPosInf));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosNormal, fcPosNormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosSubnormal, fcPosSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegNormal, fcNegNormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegSubnormal, fcNegSubnormal));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosNormal | fcPosSubnormal,
+ fcPosNormal | fcPosSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegNormal | fcNegSubnormal,
+ fcNegNormal | fcNegSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNormal, fcNormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcSubnormal, fcSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcSubnormal | fcNormal,
+ fcSubnormal | fcNormal));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegInf, fcNegInf | fcNan));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegInf | fcNan, fcNegInf));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegSubnormal, fcNegNormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosSubnormal, fcNegNormal));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcPosSubnormal, fcPosNormal));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegSubnormal, fcPosNormal));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegSubnormal, fcNegInf));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcNegInf | fcNegZero, fcZero | fcPosInf));
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcZero | fcPosInf, fcNegInf | fcNegZero));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegInf | fcNegZero,
+ fcZero | fcPosInf | fcNan));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegInf | fcNegZero,
+ fcPosZero | fcPosInf | fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegInf | fcNegZero,
+ fcPosZero | fcPosInf | fcNan,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcPosInf | fcPosNormal, fcPosNormal));
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcPosNormal, fcPosInf | fcPosNormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(
+ fcPosInf | fcPosNormal | fcSubnormal, fcPosNormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(
+ fcPosNormal, fcPosInf | fcPosNormal | fcSubnormal));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcPosSubnormal | fcPosZero, fcPosZero));
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcPosZero, fcPosSubnormal | fcPosZero));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcSubnormal | fcPosZero, fcPosZero));
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcPosZero, fcSubnormal | fcPosZero));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcSubnormal | fcPosZero, fcNegZero));
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcNegZero, fcSubnormal | fcPosZero));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegative, fcPositive));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegative, fcPositive,
+ /*OrderedZeroSign=*/true));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPositive, fcNegative));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcNegative | fcNan, fcPositive | fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(
+ fcNegative | fcNan, fcPositive | fcNan, /*OrderedZeroSign=*/true));
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcPositive | fcNan, fcNegative | fcNan));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcZero, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNan, fcZero));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcZero, fcSubnormal));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcSubnormal, fcZero));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcFinite, fcFinite));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcFinite, fcInf));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcInf, fcInf));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcNegFinite, fcPosFinite));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegFinite, fcPosFinite,
+ /*OrderedZeroSign=*/true));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosFinite, fcNegFinite));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcNegFinite, fcPosFinite | fcNegZero));
+ EXPECT_FALSE(
+ cannotOrderStrictlyGreaterEq(fcPosFinite | fcNegZero, fcNegFinite));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcZero | fcInf, fcZero | fcInf));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcZero, fcZero | fcInf));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcZero | fcInf, fcZero));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcZero | fcInf | fcNormal, fcZero));
+
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(fcPosInf, ~fcPosInf));
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(~fcPosInf, fcPosInf));
+
+ EXPECT_TRUE(cannotOrderStrictlyGreaterEq(fcNegInf, ~fcNegInf));
+ EXPECT_FALSE(cannotOrderStrictlyGreaterEq(~fcNegInf, fcNegInf));
+}
+
+TEST(FloatingPointModeTest, cannotOrderStrictlyLess) {
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcNone, fcNone));
+ EXPECT_FALSE(cannotOrderStrictlyLess(fcAllFlags, fcAllFlags));
+
+ EXPECT_FALSE(cannotOrderStrictlyLess(OrderedLessThanZeroMask,
+ OrderedLessThanZeroMask));
+ EXPECT_FALSE(cannotOrderStrictlyLess(OrderedLessThanZeroMask,
+ OrderedGreaterThanZeroMask));
+
+ EXPECT_TRUE(cannotOrderStrictlyLess(OrderedGreaterThanZeroMask,
+ OrderedLessThanZeroMask));
+
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPositive, fcNegative));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPositive, fcNegative,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(cannotOrderStrictlyLess(fcNegative, fcPositive));
+ EXPECT_FALSE(cannotOrderStrictlyLess(fcNegative, fcPositive,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPositive | fcNan, fcNegative));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPositive | fcNan, fcNegative,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPositive, fcNegative | fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPositive, fcNegative | fcNan,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_TRUE(cannotOrderStrictlyLess(OrderedGreaterThanZeroMask | fcNan,
+ OrderedLessThanZeroMask));
+ EXPECT_TRUE(cannotOrderStrictlyLess(OrderedGreaterThanZeroMask,
+ OrderedLessThanZeroMask | fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyLess(OrderedGreaterThanZeroMask | fcNan,
+ OrderedLessThanZeroMask | fcNan));
+
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcNan, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcQNan, fcQNan));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcSNan, fcSNan));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcSNan, fcQNan));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcQNan, fcSNan));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcQNan, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcSNan, fcNan));
+
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcNegInf, fcSNan));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcNegInf, fcQNan));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcNegInf, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcSNan, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcQNan, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcNan, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcNegInf, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcNegZero, fcPosZero));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPosZero, fcNegZero));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPosZero, fcPosZero));
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcPosZero, fcPosZero));
+
+ EXPECT_TRUE(
+ cannotOrderStrictlyLess(fcPosZero, fcNegZero, /*OrderedZeroSign=*/true));
+
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcZero, fcPosZero));
+ EXPECT_FALSE(cannotOrderStrictlyLess(fcZero, fcPosZero, true));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPosZero, fcZero));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPosZero, fcZero, true));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcZero, fcNegZero));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcZero, fcNegZero, true));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcNegZero, fcZero));
+ EXPECT_FALSE(cannotOrderStrictlyLess(fcNegZero, fcZero, true));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcZero, fcZero));
+ EXPECT_FALSE(cannotOrderStrictlyLess(fcZero, fcZero, true));
+
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcInf, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcNan, fcInf));
+
+ EXPECT_TRUE(
+ cannotOrderStrictlyLess(fcPosInf | fcPosZero, fcNegZero | fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyLess(
+ fcPosInf | fcPosZero, fcNegZero | fcNegInf, /*OrderedZeroSign=*/true));
+
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPosInf | fcPosZero, fcZero | fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPosInf | fcPosZero, fcZero | fcNegInf,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyLess(fcZero | fcNegInf, fcPosInf | fcPosZero));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyLess(fcNegInf | fcNegZero, fcZero | fcPosInf));
+ EXPECT_FALSE(
+ cannotOrderStrictlyLess(fcNegInf | fcNegZero, fcZero | fcPosInf, true));
+
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcZero | fcPosInf, fcNegInf | fcNegZero));
+ EXPECT_TRUE(
+ cannotOrderStrictlyLess(fcZero | fcPosInf, fcNegInf | fcNegZero, true));
+
+ EXPECT_TRUE(cannotOrderStrictlyLess(fcPosInf, ~fcPosInf));
+ EXPECT_FALSE(cannotOrderStrictlyLess(~fcPosInf, fcPosInf));
+
+ EXPECT_FALSE(cannotOrderStrictlyLess(fcNegInf, ~fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyLess(~fcNegInf, fcNegInf));
+}
+
+TEST(FloatingPointModeTest, cannotOrderStrictlyLessEq) {
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcNone, fcNone));
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcAllFlags, fcAllFlags));
+
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(OrderedLessThanZeroMask,
+ OrderedLessThanZeroMask));
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(OrderedLessThanZeroMask,
+ OrderedGreaterThanZeroMask));
+
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(OrderedGreaterThanZeroMask,
+ OrderedLessThanZeroMask));
+
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcPositive, fcNegative));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcPositive, fcNegative,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcNegative, fcPositive));
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcNegative, fcPositive,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcPositive | fcNan, fcNegative));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcPositive | fcNan, fcNegative,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcPositive, fcNegative | fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcPositive, fcNegative | fcNan,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(OrderedGreaterThanZeroMask | fcNan,
+ OrderedLessThanZeroMask));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(OrderedGreaterThanZeroMask,
+ OrderedLessThanZeroMask | fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(OrderedGreaterThanZeroMask | fcNan,
+ OrderedLessThanZeroMask | fcNan));
+
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcNan, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcQNan, fcQNan));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcSNan, fcSNan));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcSNan, fcQNan));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcQNan, fcSNan));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcQNan, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcSNan, fcNan));
+
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcNegInf, fcSNan));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcNegInf, fcQNan));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcNegInf, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcSNan, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcQNan, fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcNan, fcNegInf));
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcNegInf, fcNegInf));
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcNegZero, fcPosZero));
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcPosZero, fcNegZero));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcPosZero, fcNegZero,
+ /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcZero, fcPosZero));
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcPosZero, fcZero));
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcZero, fcNegZero));
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcNegZero, fcZero));
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcZero, fcZero));
+
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcInf, fcNan));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcNan, fcInf));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyLessEq(fcPosInf | fcPosZero, fcNegZero | fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(
+ fcPosInf | fcPosZero, fcNegZero | fcNegInf, /*OrderedZeroSign=*/true));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyLessEq(fcPosInf | fcPosZero, fcZero | fcNegInf));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyLessEq(fcZero | fcNegInf, fcPosInf | fcPosZero));
+
+ EXPECT_FALSE(
+ cannotOrderStrictlyLessEq(fcNegInf | fcNegZero, fcZero | fcPosInf));
+ EXPECT_FALSE(
+ cannotOrderStrictlyLessEq(fcZero | fcPosInf, fcNegInf | fcNegZero));
+
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(fcPosInf, ~fcPosInf));
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(~fcPosInf, fcPosInf));
+
+ EXPECT_FALSE(cannotOrderStrictlyLessEq(fcNegInf, ~fcNegInf));
+ EXPECT_TRUE(cannotOrderStrictlyLessEq(~fcNegInf, fcNegInf));
+}
}
More information about the llvm-branch-commits
mailing list