[llvm] [PatternMatch] match splats from an all-zeroes shufflevector (PR #228016)

Graham Hunter via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 05:49:37 PDT 2026


https://github.com/huntergr-arm updated https://github.com/llvm/llvm-project/pull/228016

>From 93849a49fa1b7727d7606479c272dac184ea2851 Mon Sep 17 00:00:00 2001
From: Graham Hunter <graham.hunter at arm.com>
Date: Wed, 23 Sep 2026 16:34:29 +0000
Subject: [PATCH 1/4] PatternMatch splats from an all-zeroes shufflevector

---
 llvm/include/llvm/IR/PatternMatch.h           | 25 +++++++++++++++----
 .../InstCombine/InstructionCombining.cpp      |  2 +-
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 32d5e45320463..97082702f7cd3 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -218,14 +218,29 @@ template <typename SubPattern_t> struct Splat_match {
       auto *Splat = C->getSplatValue();
       return Splat ? SubPattern.match(Splat) : false;
     }
-    // TODO: Extend to other cases (e.g. shufflevectors).
-    return false;
+
+    auto *Shuffle = dyn_cast<ShuffleVectorInst>(V);
+    if (!Shuffle || !Shuffle->isZeroEltSplat())
+      return false;
+
+    // Look for an insertelement.
+    auto *Insert = dyn_cast<InsertElementInst>(Shuffle->getOperand(0));
+    if (!Insert)
+      return false;
+
+    Value *SplatElt = Insert->getOperand(1);
+    ConstantInt *Idx = dyn_cast<ConstantInt>(Insert->getOperand(2));
+    if (!Idx || Idx->getZExtValue() != 0)
+      return false;
+
+    return SubPattern.match(SplatElt);
+    // TODO: Handle other splat patterns.
   }
 };
 
-/// Match a constant splat. TODO: Extend this to non-constant splats.
-template <typename T>
-inline Splat_match<T> m_ConstantSplat(const T &SubPattern) {
+/// Match a vector splat. May be a constant splat or a shufflevector of the
+/// first element.
+template <typename T> inline Splat_match<T> m_Splat(const T &SubPattern) {
   return SubPattern;
 }
 
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 72adf311850a3..140953ccdcd94 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2470,7 +2470,7 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
           bool SplatLHS) -> Instruction * {
     Value *Idx;
     Constant *Splat, *SubVector, *Dest;
-    if (!match(MaybeSplat, m_ConstantSplat(m_Constant(Splat))) ||
+    if (!match(MaybeSplat, m_Splat(m_Constant(Splat))) ||
         !match(MaybeSubVector,
                m_VectorInsert(m_Constant(Dest), m_Constant(SubVector),
                               m_Value(Idx))))

>From 13b45a135e89e41f2a5e5f3e81e9bd2039ac076c Mon Sep 17 00:00:00 2001
From: Graham Hunter <graham.hunter at arm.com>
Date: Fri, 25 Sep 2026 13:09:08 +0000
Subject: [PATCH 2/4] Add gtest coverage, matching the existing m_Shuffle cases

---
 llvm/unittests/IR/PatternMatch.cpp | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp
index 64ccd1fdc47dd..7bf92f7761a51 100644
--- a/llvm/unittests/IR/PatternMatch.cpp
+++ b/llvm/unittests/IR/PatternMatch.cpp
@@ -1532,6 +1532,17 @@ TEST_F(PatternMatchTest, VectorOps) {
       SP2, m_Shuffle(m_InsertElt(m_Undef(), m_Value(A), m_Zero()),
                      m_Undef(), m_ZeroMask())));
   EXPECT_TRUE(A == Val);
+
+  // Repeat the above with m_Splat.
+  EXPECT_TRUE(match(SI1, m_Splat(m_SpecificInt(1))));
+  EXPECT_FALSE(match(SI2, m_Splat(m_Value())));
+  EXPECT_FALSE(match(SI3, m_Splat(m_Value())));
+  EXPECT_FALSE(match(SI4, m_Splat(m_Value())));
+
+  A = nullptr;
+  EXPECT_TRUE(match(SP1, m_Splat(m_SpecificInt(2))));
+  EXPECT_TRUE(match(SP2, m_Splat(m_Value(A))));
+  EXPECT_TRUE(A == Val);
 }
 
 TEST_F(PatternMatchTest, UndefPoisonMix) {

>From cdcd21787c824ccfcf28aae1b6183f3517bfb02f Mon Sep 17 00:00:00 2001
From: Graham Hunter <graham.hunter at arm.com>
Date: Tue, 29 Sep 2026 10:31:12 +0000
Subject: [PATCH 3/4] Remove TODO

---
 llvm/include/llvm/IR/PatternMatch.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 97082702f7cd3..98aaf66c027c5 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -234,7 +234,6 @@ template <typename SubPattern_t> struct Splat_match {
       return false;
 
     return SubPattern.match(SplatElt);
-    // TODO: Handle other splat patterns.
   }
 };
 

>From 4d62796e5ccee8912570956120513fed65d2ce63 Mon Sep 17 00:00:00 2001
From: Graham Hunter <graham.hunter at arm.com>
Date: Wed, 30 Sep 2026 12:37:27 +0000
Subject: [PATCH 4/4] Use isZero()

---
 llvm/include/llvm/IR/PatternMatch.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 98aaf66c027c5..a279d65cd15bb 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -230,7 +230,7 @@ template <typename SubPattern_t> struct Splat_match {
 
     Value *SplatElt = Insert->getOperand(1);
     ConstantInt *Idx = dyn_cast<ConstantInt>(Insert->getOperand(2));
-    if (!Idx || Idx->getZExtValue() != 0)
+    if (!Idx || !Idx->isZero())
       return false;
 
     return SubPattern.match(SplatElt);



More information about the llvm-commits mailing list