[llvm] [IR] Add icmp like matcher (NFC) (PR #192746)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 18 02:14:36 PDT 2026
https://github.com/andjo403 updated https://github.com/llvm/llvm-project/pull/192746
>From c5200cbb74ed27a27f512e937c09bcc91d4cdcda Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Fri, 17 Apr 2026 23:38:49 +0200
Subject: [PATCH 1/2] [IR] Add icmp like matcher (NFC)
matches icmp and trunc nuw x to i1 (icmp ne x,0)
---
llvm/include/llvm/IR/PatternMatch.h | 29 ++++++++++++++++++++
llvm/lib/Analysis/InstructionSimplify.cpp | 8 ++----
llvm/lib/Analysis/ValueTracking.cpp | 32 +++++++----------------
3 files changed, 41 insertions(+), 28 deletions(-)
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 8399c252f1c2d..00cab199262cf 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..efd1f3dc32c82 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..e872979c53b11 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 d40e477d3c2ac5ece4984c7ac09ea4611352587a Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Sat, 18 Apr 2026 10:03:14 +0200
Subject: [PATCH 2/2] fixup! [IR] Add icmp like matcher (NFC)
---
llvm/include/llvm/IR/PatternMatch.h | 8 ++++----
llvm/lib/Analysis/InstructionSimplify.cpp | 2 +-
llvm/lib/Analysis/ValueTracking.cpp | 4 ++--
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 00cab199262cf..798667c12e44f 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -2314,12 +2314,12 @@ 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 {
+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)
+ 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 {
@@ -2338,9 +2338,9 @@ template <typename LHS_t, typename RHS_t> struct IcmpLike_match {
};
template <typename LHS, typename RHS>
-inline IcmpLike_match<LHS, RHS> m_IcmpLike(CmpPredicate &Pred, const LHS &L,
+inline ICmpLike_match<LHS, RHS> m_ICmpLike(CmpPredicate &Pred, const LHS &L,
const RHS &R) {
- return IcmpLike_match<LHS, RHS>(Pred, L, R);
+ return ICmpLike_match<LHS, RHS>(Pred, L, R);
}
template <typename CondTy, typename LTy, typename RTy> struct SelectLike_match {
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index efd1f3dc32c82..e925f7bdc5df7 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1950,7 +1950,7 @@ 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))) ||
+ if (!match(Op0, m_ICmpLike(Pred, m_Value(A), m_Value(B))) ||
!ICmpInst::isEquality(Pred))
return nullptr;
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e872979c53b11..3227708f9c26f 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -9862,7 +9862,7 @@ llvm::isImpliedCondition(const Value *LHS, CmpPredicate RHSPred,
if (RHSOp0->getType()->getScalarType()->isIntOrPtrTy()) {
CmpPredicate LHSPred;
Value *LHSOp0, *LHSOp1;
- if (match(LHS, m_IcmpLike(LHSPred, m_Value(LHSOp0), m_Value(LHSOp1))))
+ if (match(LHS, m_ICmpLike(LHSPred, m_Value(LHSOp0), m_Value(LHSOp1))))
return isImpliedCondICmps(LHSPred, LHSOp0, LHSOp1, RHSPred, RHSOp0,
RHSOp1, DL, LHSIsTrue);
} else {
@@ -9904,7 +9904,7 @@ std::optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
CmpPredicate RHSPred;
Value *RHSOp0, *RHSOp1;
- if (match(RHS, m_IcmpLike(RHSPred, m_Value(RHSOp0), m_Value(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;
More information about the llvm-commits
mailing list