[libc-commits] [libc] [llvm] [libc][math] Qualify floor functions to constexpr (PR #192791)
Kiriti Ponduri via libc-commits
libc-commits at lists.llvm.org
Sat Apr 18 13:22:27 PDT 2026
https://github.com/udaykiriti updated https://github.com/llvm/llvm-project/pull/192791
>From 75ae60cc5fe69e9caaf31b9292bcbd5cee31eade Mon Sep 17 00:00:00 2001
From: udaykiriti <udaykiriti624 at gmail.com>
Date: Sat, 18 Apr 2026 19:59:13 +0530
Subject: [PATCH 1/3] [libc][math] Qualify floor functions to constexpr
Signed-off-by: udaykiriti <udaykiriti624 at gmail.com>
---
libc/src/__support/math/floor.h | 5 +++--
libc/src/__support/math/floorbf16.h | 2 +-
libc/src/__support/math/floorf.h | 5 +++--
libc/src/__support/math/floorf128.h | 2 +-
libc/src/__support/math/floorf16.h | 5 +++--
.../test/shared/shared_math_constexpr_test.cpp | 18 ++++++++++++++++++
6 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/libc/src/__support/math/floor.h b/libc/src/__support/math/floor.h
index 2f7ac5841087f..52603f6e0671a 100644
--- a/libc/src/__support/math/floor.h
+++ b/libc/src/__support/math/floor.h
@@ -15,8 +15,9 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE double floor(double x) {
-#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
+LIBC_INLINE LIBC_CONSTEXPR double floor(double x) {
+#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
+ !defined(LIBC_HAS_CONSTANT_EVALUATION)
return __builtin_floor(x);
#else
return fputil::floor(x);
diff --git a/libc/src/__support/math/floorbf16.h b/libc/src/__support/math/floorbf16.h
index 72ed6cc3f2b97..a69389722361b 100644
--- a/libc/src/__support/math/floorbf16.h
+++ b/libc/src/__support/math/floorbf16.h
@@ -16,7 +16,7 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE bfloat16 floorbf16(bfloat16 x) { return fputil::floor(x); }
+LIBC_INLINE constexpr bfloat16 floorbf16(bfloat16 x) { return fputil::floor(x); }
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/math/floorf.h b/libc/src/__support/math/floorf.h
index 693b17441245b..82ff9ad51de49 100644
--- a/libc/src/__support/math/floorf.h
+++ b/libc/src/__support/math/floorf.h
@@ -15,8 +15,9 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE float floorf(float x) {
-#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
+LIBC_INLINE LIBC_CONSTEXPR float floorf(float x) {
+#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
+ !defined(LIBC_HAS_CONSTANT_EVALUATION)
return __builtin_floorf(x);
#else
return fputil::floor(x);
diff --git a/libc/src/__support/math/floorf128.h b/libc/src/__support/math/floorf128.h
index b2ef990b6d2b7..06b264d93e87a 100644
--- a/libc/src/__support/math/floorf128.h
+++ b/libc/src/__support/math/floorf128.h
@@ -19,7 +19,7 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE float128 floorf128(float128 x) { return fputil::floor(x); }
+LIBC_INLINE constexpr float128 floorf128(float128 x) { return fputil::floor(x); }
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/math/floorf16.h b/libc/src/__support/math/floorf16.h
index 82015b6a9f597..80489530a45c7 100644
--- a/libc/src/__support/math/floorf16.h
+++ b/libc/src/__support/math/floorf16.h
@@ -21,9 +21,10 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE float16 floorf16(float16 x) {
+LIBC_INLINE LIBC_CONSTEXPR float16 floorf16(float16 x) {
#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
- defined(LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS)
+ defined(LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS) && \
+ !defined(LIBC_HAS_CONSTANT_EVALUATION)
return fputil::cast<float16>(__builtin_floorf(x));
#else
return fputil::floor(x);
diff --git a/libc/test/shared/shared_math_constexpr_test.cpp b/libc/test/shared/shared_math_constexpr_test.cpp
index 6fb1318e5a4ea..c59b2fee00db7 100644
--- a/libc/test/shared/shared_math_constexpr_test.cpp
+++ b/libc/test/shared/shared_math_constexpr_test.cpp
@@ -19,13 +19,18 @@ static_assert(0.0 == LIBC_NAMESPACE::shared::ceil(0.0));
static_assert(0.0 == LIBC_NAMESPACE::shared::log(1.0));
static_assert(0.0 == LIBC_NAMESPACE::shared::copysign(0.0, 0.0));
+static_assert(1.0 == LIBC_NAMESPACE::shared::floor(1.2));
+
//===----------------------------------------------------------------------===//
// Float Tests
//===----------------------------------------------------------------------===//
static_assert(0.0f == LIBC_NAMESPACE::shared::ceilf(0.0f));
+static_assert(0.0f == LIBC_NAMESPACE::shared::floorf(0.0f));
static_assert(0.0f == LIBC_NAMESPACE::shared::copysignf(0.0f, 0.0f));
+static_assert(2.0f == LIBC_NAMESPACE::shared::floorf(2.9f));
+
//===----------------------------------------------------------------------===//
// Float16 Tests
//===----------------------------------------------------------------------===//
@@ -35,6 +40,8 @@ static_assert(0.0f == LIBC_NAMESPACE::shared::copysignf(0.0f, 0.0f));
static_assert(0.0f16 == LIBC_NAMESPACE::shared::ceilf16(0.0f16));
static_assert(0.0f16 == LIBC_NAMESPACE::shared::copysignf16(0.0f16, 0.0f16));
+
+static_assert(3.0f16 == LIBC_NAMESPACE::shared::floorf16(3.7f16));
#endif // LIBC_TYPES_HAS_FLOAT16
//===----------------------------------------------------------------------===//
@@ -47,6 +54,8 @@ static_assert(0.0f16 == LIBC_NAMESPACE::shared::copysignf16(0.0f16, 0.0f16));
static_assert(0.0L == LIBC_NAMESPACE::shared::ceill(0.0L));
static_assert(0.0L == LIBC_NAMESPACE::shared::copysignl(0.0L, 0.0L));
+static_assert(0.0L == LIBC_NAMESPACE::shared::floorl(0.0L));
+
#endif
//===----------------------------------------------------------------------===//
@@ -60,6 +69,9 @@ static_assert(float128(0.0) ==
LIBC_NAMESPACE::shared::copysignf128(float128(0.0),
float128(0.0)));
+static_assert(float128(0.0) ==
+ LIBC_NAMESPACE::shared::floorf128(float128(0.0)));
+
#endif // LIBC_TYPES_HAS_FLOAT128
//===----------------------------------------------------------------------===//
@@ -72,4 +84,10 @@ static_assert(bfloat16(0.0) ==
LIBC_NAMESPACE::shared::copysignbf16(bfloat16(0.0),
bfloat16(0.0)));
+static_assert(bfloat16(0.0f) ==
+ LIBC_NAMESPACE::shared::floorbf16(bfloat16(0.0f)));
+
+static_assert(bfloat16(4.0f) ==
+ LIBC_NAMESPACE::shared::floorbf16(bfloat16(4.8f)));
+
TEST(LlvmLibcSharedMathTest, ConstantEvaluation) {}
>From 8bd2929007adf7c33309b6421cd5cb5b9da02457 Mon Sep 17 00:00:00 2001
From: udaykiriti <udaykiriti624 at gmail.com>
Date: Sat, 18 Apr 2026 22:33:20 +0530
Subject: [PATCH 2/3] [libc][math] Ordering, formatting, removing duplicate
test cases.
Signed-off-by: udaykiriti <udaykiriti624 at gmail.com>
[IR] Add icmp like matcher (NFC) (#192746)
matches icmp and trunc nuw x to i1 (icmp ne x,0)
---
libc/src/__support/math/floorl.h | 2 +-
.../shared/shared_math_constexpr_test.cpp | 14 ++------
llvm/include/llvm/IR/PatternMatch.h | 29 +++++++++++++++++
llvm/lib/Analysis/InstructionSimplify.cpp | 8 ++---
llvm/lib/Analysis/ValueTracking.cpp | 32 ++++++-------------
5 files changed, 45 insertions(+), 40 deletions(-)
diff --git a/libc/src/__support/math/floorl.h b/libc/src/__support/math/floorl.h
index d5977b784da7f..445582ecfa070 100644
--- a/libc/src/__support/math/floorl.h
+++ b/libc/src/__support/math/floorl.h
@@ -15,7 +15,7 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE long double floorl(long double x) { return fputil::floor(x); }
+LIBC_INLINE constexpr long double floorl(long double x) { return fputil::floor(x); }
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/shared/shared_math_constexpr_test.cpp b/libc/test/shared/shared_math_constexpr_test.cpp
index c59b2fee00db7..fc6bfc01043e9 100644
--- a/libc/test/shared/shared_math_constexpr_test.cpp
+++ b/libc/test/shared/shared_math_constexpr_test.cpp
@@ -16,20 +16,17 @@
//===----------------------------------------------------------------------===//
static_assert(0.0 == LIBC_NAMESPACE::shared::ceil(0.0));
-static_assert(0.0 == LIBC_NAMESPACE::shared::log(1.0));
static_assert(0.0 == LIBC_NAMESPACE::shared::copysign(0.0, 0.0));
-
static_assert(1.0 == LIBC_NAMESPACE::shared::floor(1.2));
+static_assert(0.0 == LIBC_NAMESPACE::shared::log(1.0));
//===----------------------------------------------------------------------===//
// Float Tests
//===----------------------------------------------------------------------===//
static_assert(0.0f == LIBC_NAMESPACE::shared::ceilf(0.0f));
-static_assert(0.0f == LIBC_NAMESPACE::shared::floorf(0.0f));
static_assert(0.0f == LIBC_NAMESPACE::shared::copysignf(0.0f, 0.0f));
-
-static_assert(2.0f == LIBC_NAMESPACE::shared::floorf(2.9f));
+static_assert(0.0f == LIBC_NAMESPACE::shared::floorf(0.0f));
//===----------------------------------------------------------------------===//
// Float16 Tests
@@ -39,9 +36,8 @@ static_assert(2.0f == LIBC_NAMESPACE::shared::floorf(2.9f));
static_assert(0.0f16 == LIBC_NAMESPACE::shared::ceilf16(0.0f16));
static_assert(0.0f16 == LIBC_NAMESPACE::shared::copysignf16(0.0f16, 0.0f16));
-
-
static_assert(3.0f16 == LIBC_NAMESPACE::shared::floorf16(3.7f16));
+
#endif // LIBC_TYPES_HAS_FLOAT16
//===----------------------------------------------------------------------===//
@@ -53,7 +49,6 @@ static_assert(3.0f16 == LIBC_NAMESPACE::shared::floorf16(3.7f16));
static_assert(0.0L == LIBC_NAMESPACE::shared::ceill(0.0L));
static_assert(0.0L == LIBC_NAMESPACE::shared::copysignl(0.0L, 0.0L));
-
static_assert(0.0L == LIBC_NAMESPACE::shared::floorl(0.0L));
#endif
@@ -87,7 +82,4 @@ static_assert(bfloat16(0.0) ==
static_assert(bfloat16(0.0f) ==
LIBC_NAMESPACE::shared::floorbf16(bfloat16(0.0f)));
-static_assert(bfloat16(4.0f) ==
- LIBC_NAMESPACE::shared::floorbf16(bfloat16(4.8f)));
-
TEST(LlvmLibcSharedMathTest, ConstantEvaluation) {}
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 8399c252f1c2d..798667c12e44f 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -2314,6 +2314,35 @@ template <typename OpTy> inline auto m_ZExtOrTruncOrSelf(const OpTy &Op) {
return m_CombineOr(m_ZExt(Op), m_Trunc(Op), Op);
}
+template <typename LHS_t, typename RHS_t> struct ICmpLike_match {
+ CmpPredicate &Pred;
+ LHS_t L;
+ RHS_t R;
+
+ ICmpLike_match(CmpPredicate &P, const LHS_t &Left, const RHS_t &Right)
+ : Pred(P), L(Left), R(Right) {}
+
+ template <typename OpTy> bool match(OpTy *V) const {
+ if (PatternMatch::match(V, m_ICmp(Pred, L, R)))
+ return true;
+ Value *A;
+ // trunc nuw x to i1 is equivalent to icmp ne x, 0
+ if (V->getType()->isIntOrIntVectorTy(1) &&
+ PatternMatch::match(V, m_NUWTrunc(m_Value(A))) && L.match(A) &&
+ R.match(ConstantInt::getNullValue(A->getType()))) {
+ Pred = ICmpInst::ICMP_NE;
+ return true;
+ }
+ return false;
+ }
+};
+
+template <typename LHS, typename RHS>
+inline ICmpLike_match<LHS, RHS> m_ICmpLike(CmpPredicate &Pred, const LHS &L,
+ const RHS &R) {
+ return ICmpLike_match<LHS, RHS>(Pred, L, R);
+}
+
template <typename CondTy, typename LTy, typename RTy> struct SelectLike_match {
CondTy Cond;
LTy TrueC;
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 4b7e23d3025aa..e925f7bdc5df7 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1950,12 +1950,8 @@ static Value *simplifyAndOrWithICmpEq(unsigned Opcode, Value *Op0, Value *Op1,
"Must be and/or");
CmpPredicate Pred;
Value *A, *B;
- if (Op0->getType()->isIntOrIntVectorTy(1) &&
- match(Op0, m_NUWTrunc(m_Value(A)))) {
- B = ConstantInt::getNullValue(A->getType());
- Pred = ICmpInst::ICMP_NE;
- } else if (!match(Op0, m_ICmp(Pred, m_Value(A), m_Value(B))) ||
- !ICmpInst::isEquality(Pred))
+ if (!match(Op0, m_ICmpLike(Pred, m_Value(A), m_Value(B))) ||
+ !ICmpInst::isEquality(Pred))
return nullptr;
auto Simplify = [&](Value *Res) -> Value * {
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 54e04eccc6613..3227708f9c26f 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -9860,15 +9860,11 @@ llvm::isImpliedCondition(const Value *LHS, CmpPredicate RHSPred,
// Both LHS and RHS are icmps.
if (RHSOp0->getType()->getScalarType()->isIntOrPtrTy()) {
- if (const auto *LHSCmp = dyn_cast<ICmpInst>(LHS))
- return isImpliedCondICmps(LHSCmp->getCmpPredicate(),
- LHSCmp->getOperand(0), LHSCmp->getOperand(1),
- RHSPred, RHSOp0, RHSOp1, DL, LHSIsTrue);
- const Value *V;
- if (match(LHS, m_NUWTrunc(m_Value(V))))
- return isImpliedCondICmps(CmpInst::ICMP_NE, V,
- ConstantInt::get(V->getType(), 0), RHSPred,
- RHSOp0, RHSOp1, DL, LHSIsTrue);
+ CmpPredicate LHSPred;
+ Value *LHSOp0, *LHSOp1;
+ if (match(LHS, m_ICmpLike(LHSPred, m_Value(LHSOp0), m_Value(LHSOp1))))
+ return isImpliedCondICmps(LHSPred, LHSOp0, LHSOp1, RHSPred, RHSOp0,
+ RHSOp1, DL, LHSIsTrue);
} else {
assert(RHSOp0->getType()->isFPOrFPVectorTy() &&
"Expected floating point type only!");
@@ -9906,10 +9902,11 @@ std::optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
InvertRHS = true;
}
- if (const ICmpInst *RHSCmp = dyn_cast<ICmpInst>(RHS)) {
- if (auto Implied = isImpliedCondition(
- LHS, RHSCmp->getCmpPredicate(), RHSCmp->getOperand(0),
- RHSCmp->getOperand(1), DL, LHSIsTrue, Depth))
+ CmpPredicate RHSPred;
+ Value *RHSOp0, *RHSOp1;
+ if (match(RHS, m_ICmpLike(RHSPred, m_Value(RHSOp0), m_Value(RHSOp1)))) {
+ if (auto Implied = isImpliedCondition(LHS, RHSPred, RHSOp0, RHSOp1, DL,
+ LHSIsTrue, Depth))
return InvertRHS ? !*Implied : *Implied;
return std::nullopt;
}
@@ -9921,15 +9918,6 @@ std::optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
return std::nullopt;
}
- const Value *V;
- if (match(RHS, m_NUWTrunc(m_Value(V)))) {
- if (auto Implied = isImpliedCondition(LHS, CmpInst::ICMP_NE, V,
- ConstantInt::get(V->getType(), 0), DL,
- LHSIsTrue, Depth))
- return InvertRHS ? !*Implied : *Implied;
- return std::nullopt;
- }
-
if (Depth == MaxAnalysisRecursionDepth)
return std::nullopt;
>From 6428b8bc7f1c4fb78e597b29329eeb9c6cabbf74 Mon Sep 17 00:00:00 2001
From: udaykiriti <udaykiriti624 at gmail.com>
Date: Sat, 18 Apr 2026 23:33:40 +0530
Subject: [PATCH 3/3] [libc][math] Cmake depends for floor-constexp
Signed-off-by: udaykiriti <udaykiriti624 at gmail.com>
---
libc/src/__support/math/floor.h | 2 +-
libc/src/__support/math/floorbf16.h | 4 ++-
libc/src/__support/math/floorf.h | 2 +-
libc/src/__support/math/floorf128.h | 4 ++-
libc/src/__support/math/floorl.h | 4 ++-
libc/test/shared/CMakeLists.txt | 6 ++++
.../shared/shared_math_constexpr_test.cpp | 1 -
llvm/include/llvm/IR/PatternMatch.h | 29 -----------------
llvm/lib/Analysis/InstructionSimplify.cpp | 8 +++--
llvm/lib/Analysis/ValueTracking.cpp | 32 +++++++++++++------
10 files changed, 45 insertions(+), 47 deletions(-)
diff --git a/libc/src/__support/math/floor.h b/libc/src/__support/math/floor.h
index 52603f6e0671a..01177b0701f7d 100644
--- a/libc/src/__support/math/floor.h
+++ b/libc/src/__support/math/floor.h
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
LIBC_INLINE LIBC_CONSTEXPR double floor(double x) {
-#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
+#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
!defined(LIBC_HAS_CONSTANT_EVALUATION)
return __builtin_floor(x);
#else
diff --git a/libc/src/__support/math/floorbf16.h b/libc/src/__support/math/floorbf16.h
index a69389722361b..7e4373c2ca741 100644
--- a/libc/src/__support/math/floorbf16.h
+++ b/libc/src/__support/math/floorbf16.h
@@ -16,7 +16,9 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr bfloat16 floorbf16(bfloat16 x) { return fputil::floor(x); }
+LIBC_INLINE constexpr bfloat16 floorbf16(bfloat16 x) {
+ return fputil::floor(x);
+}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/math/floorf.h b/libc/src/__support/math/floorf.h
index 82ff9ad51de49..10e298b8c8d46 100644
--- a/libc/src/__support/math/floorf.h
+++ b/libc/src/__support/math/floorf.h
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
LIBC_INLINE LIBC_CONSTEXPR float floorf(float x) {
-#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
+#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
!defined(LIBC_HAS_CONSTANT_EVALUATION)
return __builtin_floorf(x);
#else
diff --git a/libc/src/__support/math/floorf128.h b/libc/src/__support/math/floorf128.h
index 06b264d93e87a..85f92ee77fc69 100644
--- a/libc/src/__support/math/floorf128.h
+++ b/libc/src/__support/math/floorf128.h
@@ -19,7 +19,9 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 floorf128(float128 x) { return fputil::floor(x); }
+LIBC_INLINE constexpr float128 floorf128(float128 x) {
+ return fputil::floor(x);
+}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/math/floorl.h b/libc/src/__support/math/floorl.h
index 445582ecfa070..a43ebabb528e5 100644
--- a/libc/src/__support/math/floorl.h
+++ b/libc/src/__support/math/floorl.h
@@ -15,7 +15,9 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr long double floorl(long double x) { return fputil::floor(x); }
+LIBC_INLINE constexpr long double floorl(long double x) {
+ return fputil::floor(x);
+}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index 3289321f25dd4..d31b5a7839738 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -289,6 +289,12 @@ add_fp_unittest(
libc.src.__support.math.copysignf128
libc.src.__support.math.copysignf16
libc.src.__support.math.copysignl
+ libc.src.__support.math.floor
+ libc.src.__support.math.floorbf16
+ libc.src.__support.math.floorf
+ libc.src.__support.math.floorf128
+ libc.src.__support.math.floorf16
+ libc.src.__support.math.floorl
libc.src.__support.math.log
)
diff --git a/libc/test/shared/shared_math_constexpr_test.cpp b/libc/test/shared/shared_math_constexpr_test.cpp
index fc6bfc01043e9..1a013396bcf5e 100644
--- a/libc/test/shared/shared_math_constexpr_test.cpp
+++ b/libc/test/shared/shared_math_constexpr_test.cpp
@@ -78,7 +78,6 @@ static_assert(bfloat16(0.0) == LIBC_NAMESPACE::shared::ceilbf16(bfloat16(0.0)));
static_assert(bfloat16(0.0) ==
LIBC_NAMESPACE::shared::copysignbf16(bfloat16(0.0),
bfloat16(0.0)));
-
static_assert(bfloat16(0.0f) ==
LIBC_NAMESPACE::shared::floorbf16(bfloat16(0.0f)));
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 798667c12e44f..8399c252f1c2d 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -2314,35 +2314,6 @@ template <typename OpTy> inline auto m_ZExtOrTruncOrSelf(const OpTy &Op) {
return m_CombineOr(m_ZExt(Op), m_Trunc(Op), Op);
}
-template <typename LHS_t, typename RHS_t> struct ICmpLike_match {
- CmpPredicate &Pred;
- LHS_t L;
- RHS_t R;
-
- ICmpLike_match(CmpPredicate &P, const LHS_t &Left, const RHS_t &Right)
- : Pred(P), L(Left), R(Right) {}
-
- template <typename OpTy> bool match(OpTy *V) const {
- if (PatternMatch::match(V, m_ICmp(Pred, L, R)))
- return true;
- Value *A;
- // trunc nuw x to i1 is equivalent to icmp ne x, 0
- if (V->getType()->isIntOrIntVectorTy(1) &&
- PatternMatch::match(V, m_NUWTrunc(m_Value(A))) && L.match(A) &&
- R.match(ConstantInt::getNullValue(A->getType()))) {
- Pred = ICmpInst::ICMP_NE;
- return true;
- }
- return false;
- }
-};
-
-template <typename LHS, typename RHS>
-inline ICmpLike_match<LHS, RHS> m_ICmpLike(CmpPredicate &Pred, const LHS &L,
- const RHS &R) {
- return ICmpLike_match<LHS, RHS>(Pred, L, R);
-}
-
template <typename CondTy, typename LTy, typename RTy> struct SelectLike_match {
CondTy Cond;
LTy TrueC;
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index e925f7bdc5df7..4b7e23d3025aa 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1950,8 +1950,12 @@ static Value *simplifyAndOrWithICmpEq(unsigned Opcode, Value *Op0, Value *Op1,
"Must be and/or");
CmpPredicate Pred;
Value *A, *B;
- if (!match(Op0, m_ICmpLike(Pred, m_Value(A), m_Value(B))) ||
- !ICmpInst::isEquality(Pred))
+ if (Op0->getType()->isIntOrIntVectorTy(1) &&
+ match(Op0, m_NUWTrunc(m_Value(A)))) {
+ B = ConstantInt::getNullValue(A->getType());
+ Pred = ICmpInst::ICMP_NE;
+ } else if (!match(Op0, m_ICmp(Pred, m_Value(A), m_Value(B))) ||
+ !ICmpInst::isEquality(Pred))
return nullptr;
auto Simplify = [&](Value *Res) -> Value * {
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3227708f9c26f..54e04eccc6613 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -9860,11 +9860,15 @@ llvm::isImpliedCondition(const Value *LHS, CmpPredicate RHSPred,
// Both LHS and RHS are icmps.
if (RHSOp0->getType()->getScalarType()->isIntOrPtrTy()) {
- CmpPredicate LHSPred;
- Value *LHSOp0, *LHSOp1;
- if (match(LHS, m_ICmpLike(LHSPred, m_Value(LHSOp0), m_Value(LHSOp1))))
- return isImpliedCondICmps(LHSPred, LHSOp0, LHSOp1, RHSPred, RHSOp0,
- RHSOp1, DL, LHSIsTrue);
+ if (const auto *LHSCmp = dyn_cast<ICmpInst>(LHS))
+ return isImpliedCondICmps(LHSCmp->getCmpPredicate(),
+ LHSCmp->getOperand(0), LHSCmp->getOperand(1),
+ RHSPred, RHSOp0, RHSOp1, DL, LHSIsTrue);
+ const Value *V;
+ if (match(LHS, m_NUWTrunc(m_Value(V))))
+ return isImpliedCondICmps(CmpInst::ICMP_NE, V,
+ ConstantInt::get(V->getType(), 0), RHSPred,
+ RHSOp0, RHSOp1, DL, LHSIsTrue);
} else {
assert(RHSOp0->getType()->isFPOrFPVectorTy() &&
"Expected floating point type only!");
@@ -9902,11 +9906,10 @@ std::optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
InvertRHS = true;
}
- CmpPredicate RHSPred;
- Value *RHSOp0, *RHSOp1;
- if (match(RHS, m_ICmpLike(RHSPred, m_Value(RHSOp0), m_Value(RHSOp1)))) {
- if (auto Implied = isImpliedCondition(LHS, RHSPred, RHSOp0, RHSOp1, DL,
- LHSIsTrue, Depth))
+ if (const ICmpInst *RHSCmp = dyn_cast<ICmpInst>(RHS)) {
+ if (auto Implied = isImpliedCondition(
+ LHS, RHSCmp->getCmpPredicate(), RHSCmp->getOperand(0),
+ RHSCmp->getOperand(1), DL, LHSIsTrue, Depth))
return InvertRHS ? !*Implied : *Implied;
return std::nullopt;
}
@@ -9918,6 +9921,15 @@ std::optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
return std::nullopt;
}
+ const Value *V;
+ if (match(RHS, m_NUWTrunc(m_Value(V)))) {
+ if (auto Implied = isImpliedCondition(LHS, CmpInst::ICMP_NE, V,
+ ConstantInt::get(V->getType(), 0), DL,
+ LHSIsTrue, Depth))
+ return InvertRHS ? !*Implied : *Implied;
+ return std::nullopt;
+ }
+
if (Depth == MaxAnalysisRecursionDepth)
return std::nullopt;
More information about the libc-commits
mailing list