[llvm] [PatternMatchHelpers] Introduce m_Unless (NFC) (PR #212454)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 30 07:26:39 PDT 2026
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/212454
>From 7aab2e6cfc30cd26213f0020497d7edddb74f96e Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Tue, 28 Jul 2026 11:07:38 +0100
Subject: [PATCH 1/3] [PatternMatchHelpers] Introduce variant of m_Unless (NFC)
Introduce a variant of the m_Unless pattern in PatternMatch, that
inverts a match on a non-null value, in PatternMatchHelpers: as such,
having a null value pass the m_Unless match is unhelpful. The patch has
necessitated renaming the m_Unless variant in SDPatternMatch to m_Invert
to avoid ambiguity.
---
llvm/include/llvm/CodeGen/SDPatternMatch.h | 4 ++--
llvm/include/llvm/IR/PatternMatch.h | 14 --------------
llvm/include/llvm/Support/PatternMatchHelpers.h | 12 ++++++++++++
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 6 +++---
llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp | 10 ++++------
5 files changed, 21 insertions(+), 25 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/SDPatternMatch.h b/llvm/include/llvm/CodeGen/SDPatternMatch.h
index e2e20b14bb7f7..20471efa097c2 100644
--- a/llvm/include/llvm/CodeGen/SDPatternMatch.h
+++ b/llvm/include/llvm/CodeGen/SDPatternMatch.h
@@ -208,7 +208,7 @@ template <typename Pred> struct Not {
template <typename Pred> Not(const Pred &P) -> Not<Pred>;
/// Match if the inner pattern does NOT match.
-template <typename Pred> inline Not<Pred> m_Unless(const Pred &P) {
+template <typename Pred> inline Not<Pred> m_Invert(const Pred &P) {
return Not{P};
}
@@ -221,7 +221,7 @@ template <typename... Preds> Or<Preds...> m_AnyOf(const Preds &...preds) {
}
template <typename... Preds> auto m_NoneOf(const Preds &...preds) {
- return m_Unless(m_AnyOf(preds...));
+ return m_Invert(m_AnyOf(preds...));
}
inline Opcode_match m_SpecificOpc(unsigned Opcode) {
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 70b9a72768ec7..88f3989352cf6 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -232,20 +232,6 @@ inline Splat_match<T> m_ConstantSplat(const T &SubPattern) {
/// Match an arbitrary basic block value and ignore it.
inline auto m_BasicBlock() { return m_Isa<BasicBlock>(); }
-/// Inverting matcher
-template <typename Ty> struct match_unless {
- Ty M;
-
- match_unless(const Ty &Matcher) : M(Matcher) {}
-
- template <typename ITy> bool match(ITy *V) const { return !M.match(V); }
-};
-
-/// Match if the inner matcher does *NOT* match.
-template <typename Ty> inline match_unless<Ty> m_Unless(const Ty &M) {
- return match_unless<Ty>(M);
-}
-
template <typename APTy> struct ap_match {
static_assert(std::is_same_v<APTy, APInt> || std::is_same_v<APTy, APFloat>);
using ConstantTy =
diff --git a/llvm/include/llvm/Support/PatternMatchHelpers.h b/llvm/include/llvm/Support/PatternMatchHelpers.h
index 4549a14b740cd..1aae62ce5eaac 100644
--- a/llvm/include/llvm/Support/PatternMatchHelpers.h
+++ b/llvm/include/llvm/Support/PatternMatchHelpers.h
@@ -100,6 +100,18 @@ template <typename Ty> struct match_bind { // NOLINT
return false;
}
};
+
+/// Inverting matcher that matches a non-null value not matching P.
+template <typename Ty> struct match_unless { // NOLINT
+ Ty P;
+ match_unless(const Ty &P) : P(P) {}
+ template <typename ITy> bool match(ITy *V) const { return V && !P.match(V); }
+};
+
+template <typename Pattern>
+inline match_unless<Pattern> m_Unless(const Pattern &P) { // NOLINT
+ return P;
+}
} // namespace llvm::PatternMatchHelpers
#endif // LLVM_SUPPORT_PATTERNMATCHHELPERS_H
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 06c9233d2f497..7acc44e2c1e37 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1376,11 +1376,11 @@ SDValue DAGCombiner::reassociateReduction(unsigned RedOpc, unsigned Opc,
if (sd_match(N0,
m_OneUse(m_c_BinOp(
Opc, m_Value(RedA, m_OneUse(m_UnaryOp(RedOpc, m_Value(A)))),
- m_Value(B, m_Unless(m_UnaryOp(RedOpc, m_Value())))))) &&
+ m_Value(B, m_Invert(m_UnaryOp(RedOpc, m_Value())))))) &&
sd_match(N1,
m_OneUse(m_c_BinOp(
Opc, m_Value(RedB, m_OneUse(m_UnaryOp(RedOpc, m_Value(C)))),
- m_Value(D, m_Unless(m_UnaryOp(RedOpc, m_Value())))))) &&
+ m_Value(D, m_Invert(m_UnaryOp(RedOpc, m_Value())))))) &&
A.getValueType() == C.getValueType() &&
hasOperation(Opc, A.getValueType()) &&
TLI.shouldReassociateReduction(RedOpc, VT)) {
@@ -1413,7 +1413,7 @@ SDValue DAGCombiner::reassociateReduction(unsigned RedOpc, unsigned Opc,
Chain,
m_OneUse(m_c_BinOp(
Opc, m_Value(RedY, m_OneUse(m_UnaryOp(RedOpc, m_Value(Y)))),
- m_Value(Z, m_Unless(m_UnaryOp(RedOpc, m_Value())))))) ||
+ m_Value(Z, m_Invert(m_UnaryOp(RedOpc, m_Value())))))) ||
X.getValueType() != Y.getValueType() ||
!hasOperation(Opc, X.getValueType()) ||
!TLI.shouldReassociateReduction(RedOpc, VT))
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 3311a9711cb3f..535ee20bf7e41 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -2781,10 +2781,8 @@ void VPlanTransforms::dropPoisonGeneratingRecipes(VPlan &Plan) {
// wrapped in a Reverse, which is just a permutation of the header mask, so
// peel it off before checking. The header mask is still the abstract region
// value at this point (materialization happens later).
- auto IsNotHeaderMask = [](VPValue *Mask) {
- return Mask &&
- !match(Mask, m_CombineOr(m_HeaderMask(), m_Reverse(m_HeaderMask())));
- };
+ auto m_UnlessHdrMask = m_Unless( // NOLINT
+ m_CombineOr(m_HeaderMask(), m_Reverse(m_HeaderMask())));
// Traverse all the recipes in the VPlan and collect the poison-generating
// recipes in the backward slice starting at the address of a VPWidenRecipe or
@@ -2796,11 +2794,11 @@ void VPlanTransforms::dropPoisonGeneratingRecipes(VPlan &Plan) {
if (auto *WidenRec = dyn_cast<VPWidenMemoryRecipe>(&Recipe)) {
VPRecipeBase *AddrDef = WidenRec->getAddr()->getDefiningRecipe();
if (AddrDef && WidenRec->isConsecutive() &&
- IsNotHeaderMask(WidenRec->getMask()))
+ match(WidenRec->getMask(), m_UnlessHdrMask))
CollectPoisonGeneratingInstrsInBackwardSlice(AddrDef);
} else if (auto *InterleaveRec = dyn_cast<VPInterleaveRecipe>(&Recipe)) {
VPRecipeBase *AddrDef = InterleaveRec->getAddr()->getDefiningRecipe();
- if (AddrDef && IsNotHeaderMask(InterleaveRec->getMask()))
+ if (AddrDef && match(InterleaveRec->getMask(), m_UnlessHdrMask))
CollectPoisonGeneratingInstrsInBackwardSlice(AddrDef);
}
}
>From 434ce8ee1c3d11e15400186b531f7b4b6dbc462d Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Wed, 29 Jul 2026 19:35:02 +0100
Subject: [PATCH 2/3] [PatternMatchHelpers] Strip non-null innovation
---
llvm/include/llvm/Support/PatternMatchHelpers.h | 4 ++--
llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp | 5 +++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/Support/PatternMatchHelpers.h b/llvm/include/llvm/Support/PatternMatchHelpers.h
index 1aae62ce5eaac..6c481b4bda672 100644
--- a/llvm/include/llvm/Support/PatternMatchHelpers.h
+++ b/llvm/include/llvm/Support/PatternMatchHelpers.h
@@ -101,11 +101,11 @@ template <typename Ty> struct match_bind { // NOLINT
}
};
-/// Inverting matcher that matches a non-null value not matching P.
+/// Inverting matcher that matches a value not matching P.
template <typename Ty> struct match_unless { // NOLINT
Ty P;
match_unless(const Ty &P) : P(P) {}
- template <typename ITy> bool match(ITy *V) const { return V && !P.match(V); }
+ template <typename ITy> bool match(ITy *V) const { return !P.match(V); }
};
template <typename Pattern>
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 535ee20bf7e41..601396c2e4e62 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -2793,12 +2793,13 @@ void VPlanTransforms::dropPoisonGeneratingRecipes(VPlan &Plan) {
for (VPRecipeBase &Recipe : *VPBB) {
if (auto *WidenRec = dyn_cast<VPWidenMemoryRecipe>(&Recipe)) {
VPRecipeBase *AddrDef = WidenRec->getAddr()->getDefiningRecipe();
- if (AddrDef && WidenRec->isConsecutive() &&
+ if (AddrDef && WidenRec->isConsecutive() && WidenRec->getMask() &&
match(WidenRec->getMask(), m_UnlessHdrMask))
CollectPoisonGeneratingInstrsInBackwardSlice(AddrDef);
} else if (auto *InterleaveRec = dyn_cast<VPInterleaveRecipe>(&Recipe)) {
VPRecipeBase *AddrDef = InterleaveRec->getAddr()->getDefiningRecipe();
- if (AddrDef && match(InterleaveRec->getMask(), m_UnlessHdrMask))
+ if (AddrDef && InterleaveRec->getMask() &&
+ match(InterleaveRec->getMask(), m_UnlessHdrMask))
CollectPoisonGeneratingInstrsInBackwardSlice(AddrDef);
}
}
>From f7d76e25d6aebf9bcfdfd57c015de451f6a557bf Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Thu, 30 Jul 2026 15:14:28 +0100
Subject: [PATCH 3/3] [DAGCombiner] Revert m_Invert rename, thanks Luke!
---
llvm/include/llvm/CodeGen/SDPatternMatch.h | 4 ++--
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/SDPatternMatch.h b/llvm/include/llvm/CodeGen/SDPatternMatch.h
index 20471efa097c2..e2e20b14bb7f7 100644
--- a/llvm/include/llvm/CodeGen/SDPatternMatch.h
+++ b/llvm/include/llvm/CodeGen/SDPatternMatch.h
@@ -208,7 +208,7 @@ template <typename Pred> struct Not {
template <typename Pred> Not(const Pred &P) -> Not<Pred>;
/// Match if the inner pattern does NOT match.
-template <typename Pred> inline Not<Pred> m_Invert(const Pred &P) {
+template <typename Pred> inline Not<Pred> m_Unless(const Pred &P) {
return Not{P};
}
@@ -221,7 +221,7 @@ template <typename... Preds> Or<Preds...> m_AnyOf(const Preds &...preds) {
}
template <typename... Preds> auto m_NoneOf(const Preds &...preds) {
- return m_Invert(m_AnyOf(preds...));
+ return m_Unless(m_AnyOf(preds...));
}
inline Opcode_match m_SpecificOpc(unsigned Opcode) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 7acc44e2c1e37..06c9233d2f497 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1376,11 +1376,11 @@ SDValue DAGCombiner::reassociateReduction(unsigned RedOpc, unsigned Opc,
if (sd_match(N0,
m_OneUse(m_c_BinOp(
Opc, m_Value(RedA, m_OneUse(m_UnaryOp(RedOpc, m_Value(A)))),
- m_Value(B, m_Invert(m_UnaryOp(RedOpc, m_Value())))))) &&
+ m_Value(B, m_Unless(m_UnaryOp(RedOpc, m_Value())))))) &&
sd_match(N1,
m_OneUse(m_c_BinOp(
Opc, m_Value(RedB, m_OneUse(m_UnaryOp(RedOpc, m_Value(C)))),
- m_Value(D, m_Invert(m_UnaryOp(RedOpc, m_Value())))))) &&
+ m_Value(D, m_Unless(m_UnaryOp(RedOpc, m_Value())))))) &&
A.getValueType() == C.getValueType() &&
hasOperation(Opc, A.getValueType()) &&
TLI.shouldReassociateReduction(RedOpc, VT)) {
@@ -1413,7 +1413,7 @@ SDValue DAGCombiner::reassociateReduction(unsigned RedOpc, unsigned Opc,
Chain,
m_OneUse(m_c_BinOp(
Opc, m_Value(RedY, m_OneUse(m_UnaryOp(RedOpc, m_Value(Y)))),
- m_Value(Z, m_Invert(m_UnaryOp(RedOpc, m_Value())))))) ||
+ m_Value(Z, m_Unless(m_UnaryOp(RedOpc, m_Value())))))) ||
X.getValueType() != Y.getValueType() ||
!hasOperation(Opc, X.getValueType()) ||
!TLI.shouldReassociateReduction(RedOpc, VT))
More information about the llvm-commits
mailing list