[llvm] [VPlan] Introduce m_Cmp; match more compares (PR #154771)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 21 07:20:05 PDT 2025


================
@@ -395,24 +395,30 @@ m_c_BinaryOr(const Op0_t &Op0, const Op1_t &Op1) {
   return m_c_Binary<Instruction::Or, Op0_t, Op1_t>(Op0, Op1);
 }
 
-/// ICmp_match is a variant of BinaryRecipe_match that also binds the comparison
-/// predicate.
-template <typename Op0_t, typename Op1_t> struct ICmp_match {
+/// Cmp_match is a variant of BinaryRecipe_match that also binds the comparison
+/// predicate. Opcodes must be within Instruction::ICmp or Instruction::FCmp.
+template <typename Op0_t, typename Op1_t, unsigned... Opcodes>
+struct Cmp_match {
+  static_assert(sizeof...(Opcodes) == 1 || sizeof...(Opcodes) == 2);
+  static_assert((((Opcodes == Instruction::ICmp) ||
+                  (Opcodes == Instruction::FCmp)) ||
+                 ...));
+
   CmpPredicate *Predicate = nullptr;
   Op0_t Op0;
   Op1_t Op1;
 
-  ICmp_match(CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1)
+  Cmp_match(CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1)
       : Predicate(&Pred), Op0(Op0), Op1(Op1) {}
-  ICmp_match(const Op0_t &Op0, const Op1_t &Op1) : Op0(Op0), Op1(Op1) {}
+  Cmp_match(const Op0_t &Op0, const Op1_t &Op1) : Op0(Op0), Op1(Op1) {}
----------------
lukel97 wrote:

You might find this amusing but my attempt at this is almost line for line the same, I also decided to use parameter packs:

```diff
diff --git a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
index 9f036fbd569b..f360b3b8fa5b 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
@@ -391,14 +391,17 @@ m_c_BinaryOr(const Op0_t &Op0, const Op1_t &Op1) {
 
 /// ICmp_match is a variant of BinaryRecipe_match that also binds the comparison
 /// predicate.
-template <typename Op0_t, typename Op1_t> struct ICmp_match {
+template <typename Op0_t, typename Op1_t, unsigned... Opcode> struct Cmp_match {
   CmpPredicate *Predicate = nullptr;
   Op0_t Op0;
   Op1_t Op1;
 
-  ICmp_match(CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1)
+  static_assert(((Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) &&
+                 ...));
+
+  Cmp_match(CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1)
       : Predicate(&Pred), Op0(Op0), Op1(Op1) {}
-  ICmp_match(const Op0_t &Op0, const Op1_t &Op1) : Op0(Op0), Op1(Op1) {}
+  Cmp_match(const Op0_t &Op0, const Op1_t &Op1) : Op0(Op0), Op1(Op1) {}
 
   bool match(const VPValue *V) const {
     auto *DefR = V->getDefiningRecipe();
@@ -406,7 +409,7 @@ template <typename Op0_t, typename Op1_t> struct ICmp_match {
   }
 
   bool match(const VPRecipeBase *V) const {
-    if (m_Binary<Instruction::ICmp>(Op0, Op1).match(V)) {
+    if ((m_Binary<Opcode>(Op0, Op1).match(V) || ...)) {
```

Great minds think alike :)

https://github.com/llvm/llvm-project/pull/154771


More information about the llvm-commits mailing list