[llvm] [SLP][modularisation][NFC] Move reduction match helpers to SLPReductionUtils (PR #222052)
Madhur Amilkanthwar via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 8 19:54:33 PDT 2026
https://github.com/madhur13490 updated https://github.com/llvm/llvm-project/pull/222052
>From 4fd28a77bd44bfcc79b8c90a8cc73e35ae63efba Mon Sep 17 00:00:00 2001
From: Madhur Amilkanthwar <madhura at nvidia.com>
Date: Tue, 8 Sep 2026 09:32:38 -0700
Subject: [PATCH 1/2] [SLP][modularisation][NFC] Move reduction match helpers
to SLPReductionUtils
Move the following BoUpSLP-independent reduction pattern-match helpers out
of SLPVectorizer.cpp into a new SLPVectorizer/SLPReductionUtils.{h,cpp}:
getNonPhiOperand
isReductionCandidate
matchRdxBop, used only by these two, moves alongside them and stays
file-local. Behavior is unchanged.
Part of the SLPVectorizer.cpp modularization effort:
https://discourse.llvm.org/t/modularizing-slpvectorizer-cpp/90922
---
llvm/lib/Transforms/Vectorize/CMakeLists.txt | 1 +
.../Transforms/Vectorize/SLPVectorizer.cpp | 41 +------------
.../SLPVectorizer/SLPReductionUtils.cpp | 57 +++++++++++++++++++
.../SLPVectorizer/SLPReductionUtils.h | 35 ++++++++++++
.../llvm/lib/Transforms/Vectorize/BUILD.gn | 1 +
5 files changed, 95 insertions(+), 40 deletions(-)
create mode 100644 llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.cpp
create mode 100644 llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h
diff --git a/llvm/lib/Transforms/Vectorize/CMakeLists.txt b/llvm/lib/Transforms/Vectorize/CMakeLists.txt
index 7334830c422f8..9073211280886 100644
--- a/llvm/lib/Transforms/Vectorize/CMakeLists.txt
+++ b/llvm/lib/Transforms/Vectorize/CMakeLists.txt
@@ -26,6 +26,7 @@ add_llvm_component_library(LLVMVectorize
SLPVectorizer/SLPCompatibilityAnalysis.cpp
SLPVectorizer/SLPCostAnalysis.cpp
SLPVectorizer/SLPMemoryUtils.cpp
+ SLPVectorizer/SLPReductionUtils.cpp
SLPVectorizer/SLPTypeUtils.cpp
SLPVectorizer/SLPUtils.cpp
SLPVectorizer.cpp
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 950297eb31cc4..881033817b74a 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -20,6 +20,7 @@
#include "SLPVectorizer/SLPCompatibilityAnalysis.h"
#include "SLPVectorizer/SLPCostAnalysis.h"
#include "SLPVectorizer/SLPMemoryUtils.h"
+#include "SLPVectorizer/SLPReductionUtils.h"
#include "SLPVectorizer/SLPTypeUtils.h"
#include "SLPVectorizer/SLPUtils.h"
#include "llvm/ADT/DenseMap.h"
@@ -33060,28 +33061,6 @@ static Instruction *getReductionInstr(const DominatorTree *DT, PHINode *P,
return nullptr;
}
-static bool matchRdxBop(Instruction *I, Value *&V0, Value *&V1) {
- if (match(I, m_BinOp(m_Value(V0), m_Value(V1))))
- return true;
- if (match(I, m_FMaxNum(m_Value(V0), m_Value(V1))))
- return true;
- if (match(I, m_FMinNum(m_Value(V0), m_Value(V1))))
- return true;
- if (match(I, m_FMaximum(m_Value(V0), m_Value(V1))))
- return true;
- if (match(I, m_FMinimum(m_Value(V0), m_Value(V1))))
- return true;
- if (match(I, m_Intrinsic<Intrinsic::smax>(m_Value(V0), m_Value(V1))))
- return true;
- if (match(I, m_Intrinsic<Intrinsic::smin>(m_Value(V0), m_Value(V1))))
- return true;
- if (match(I, m_Intrinsic<Intrinsic::umax>(m_Value(V0), m_Value(V1))))
- return true;
- if (match(I, m_Intrinsic<Intrinsic::umin>(m_Value(V0), m_Value(V1))))
- return true;
- return false;
-}
-
/// We could have an initial reduction that is not an add.
/// r *= v1 + v2 + v3 + v4
/// In such a case start looking for a tree rooted in the first '+'.
@@ -33102,24 +33081,6 @@ static Instruction *tryGetSecondaryReductionRoot(PHINode *Phi,
return nullptr;
}
-/// \p Returns the first operand of \p I that does not match \p Phi. If
-/// operand is not an instruction it returns nullptr.
-static Instruction *getNonPhiOperand(Instruction *I, PHINode *Phi) {
- Value *Op0 = nullptr;
- Value *Op1 = nullptr;
- if (!matchRdxBop(I, Op0, Op1))
- return nullptr;
- return dyn_cast<Instruction>(Op0 == Phi ? Op1 : Op0);
-}
-
-/// \Returns true if \p I is a candidate instruction for reduction vectorization.
-static bool isReductionCandidate(Instruction *I) {
- bool IsSelect = match(I, m_Select(m_Value(), m_Value(), m_Value()));
- Value *B0 = nullptr, *B1 = nullptr;
- bool IsBinop = matchRdxBop(I, B0, B1);
- return IsBinop || IsSelect;
-}
-
bool SLPVectorizerPass::vectorizeHorReduction(
PHINode *P, Instruction *Root, BasicBlock *BB, BoUpSLP &R,
SmallVectorImpl<WeakTrackingVH> &PostponedInsts) {
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.cpp
new file mode 100644
index 0000000000000..94080e4e28ebb
--- /dev/null
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.cpp
@@ -0,0 +1,57 @@
+//===- SLPReductionUtils.cpp - SLP reduction match helpers ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "SLPReductionUtils.h"
+
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/PatternMatch.h"
+
+using namespace llvm;
+using namespace llvm::PatternMatch;
+
+namespace llvm::slpvectorizer {
+
+static bool matchRdxBop(Instruction *I, Value *&V0, Value *&V1) {
+ if (match(I, m_BinOp(m_Value(V0), m_Value(V1))))
+ return true;
+ if (match(I, m_FMaxNum(m_Value(V0), m_Value(V1))))
+ return true;
+ if (match(I, m_FMinNum(m_Value(V0), m_Value(V1))))
+ return true;
+ if (match(I, m_FMaximum(m_Value(V0), m_Value(V1))))
+ return true;
+ if (match(I, m_FMinimum(m_Value(V0), m_Value(V1))))
+ return true;
+ if (match(I, m_Intrinsic<Intrinsic::smax>(m_Value(V0), m_Value(V1))))
+ return true;
+ if (match(I, m_Intrinsic<Intrinsic::smin>(m_Value(V0), m_Value(V1))))
+ return true;
+ if (match(I, m_Intrinsic<Intrinsic::umax>(m_Value(V0), m_Value(V1))))
+ return true;
+ if (match(I, m_Intrinsic<Intrinsic::umin>(m_Value(V0), m_Value(V1))))
+ return true;
+ return false;
+}
+
+Instruction *getNonPhiOperand(Instruction *I, PHINode *Phi) {
+ Value *Op0 = nullptr;
+ Value *Op1 = nullptr;
+ if (!matchRdxBop(I, Op0, Op1))
+ return nullptr;
+ return dyn_cast<Instruction>(Op0 == Phi ? Op1 : Op0);
+}
+
+bool isReductionCandidate(Instruction *I) {
+ bool IsSelect = match(I, m_Select(m_Value(), m_Value(), m_Value()));
+ Value *B0 = nullptr, *B1 = nullptr;
+ bool IsBinop = matchRdxBop(I, B0, B1);
+ return IsBinop || IsSelect;
+}
+
+} // namespace llvm::slpvectorizer
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h
new file mode 100644
index 0000000000000..21e02b4143da8
--- /dev/null
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h
@@ -0,0 +1,35 @@
+//===- SLPReductionUtils.h - SLP reduction match helpers -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Internal header used by SLPVectorizer.cpp. It declares free reduction
+// pattern-match helpers that do not depend on BoUpSLP or any other SLP-private
+// type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPREDUCTIONUTILS_H
+#define LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPREDUCTIONUTILS_H
+
+namespace llvm {
+class Instruction;
+class PHINode;
+} // namespace llvm
+
+namespace llvm::slpvectorizer {
+
+/// \p Returns the first operand of \p I that does not match \p Phi. If
+/// operand is not an instruction it returns nullptr.
+Instruction *getNonPhiOperand(Instruction *I, PHINode *Phi);
+
+/// \Returns true if \p I is a candidate instruction for reduction
+/// vectorization.
+bool isReductionCandidate(Instruction *I);
+
+} // namespace llvm::slpvectorizer
+
+#endif // LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPREDUCTIONUTILS_H
diff --git a/llvm/utils/gn/secondary/llvm/lib/Transforms/Vectorize/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Transforms/Vectorize/BUILD.gn
index 3a6fce2c029e9..0ffc24ec855f7 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Transforms/Vectorize/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Transforms/Vectorize/BUILD.gn
@@ -17,6 +17,7 @@ static_library("Vectorize") {
"SLPVectorizer/SLPCompatibilityAnalysis.cpp",
"SLPVectorizer/SLPCostAnalysis.cpp",
"SLPVectorizer/SLPMemoryUtils.cpp",
+ "SLPVectorizer/SLPReductionUtils.cpp",
"SLPVectorizer/SLPTypeUtils.cpp",
"SLPVectorizer/SLPUtils.cpp",
"SandboxVectorizer/DependencyGraph.cpp",
>From c9a0d23ddb4242645c34765ec9a2d6b28cea0f62 Mon Sep 17 00:00:00 2001
From: Madhur Amilkanthwar <madhura at nvidia.com>
Date: Tue, 8 Sep 2026 19:52:41 -0700
Subject: [PATCH 2/2] fixup! fix comments
---
.../Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h
index 21e02b4143da8..1ba4af797b628 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h
@@ -22,11 +22,11 @@ class PHINode;
namespace llvm::slpvectorizer {
-/// \p Returns the first operand of \p I that does not match \p Phi. If
-/// operand is not an instruction it returns nullptr.
+/// \returns the first operand of \p I that does not match \p Phi. If
+/// the operand is not an instruction, returns nullptr.
Instruction *getNonPhiOperand(Instruction *I, PHINode *Phi);
-/// \Returns true if \p I is a candidate instruction for reduction
+/// \returns true if \p I is a candidate instruction for reduction
/// vectorization.
bool isReductionCandidate(Instruction *I);
More information about the llvm-commits
mailing list