[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