[llvm] [SLP][REVEC] Initial commits. (PR #98269)
Han-Kuan Chen via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 10 21:18:29 PDT 2024
https://github.com/HanKuanChen updated https://github.com/llvm/llvm-project/pull/98269
>From bb26a1031261cf29b1a15db591ffb0f4edd83797 Mon Sep 17 00:00:00 2001
From: Han-Kuan Chen <hankuan.chen at sifive.com>
Date: Thu, 13 Jun 2024 01:58:51 -0700
Subject: [PATCH 1/7] [SLP][REVEC] Add an option to control SLP
revectorization. NFC.
---
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 1e9dd8c1e2287..bb514ca646abb 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -113,6 +113,10 @@ static cl::opt<bool>
RunSLPVectorization("vectorize-slp", cl::init(true), cl::Hidden,
cl::desc("Run the SLP vectorization passes"));
+static cl::opt<bool>
+ SLPReVec("slp-revec", cl::init(false), cl::Hidden,
+ cl::desc("Enable vectorization for wider vector utilization"));
+
static cl::opt<int>
SLPCostThreshold("slp-threshold", cl::init(0), cl::Hidden,
cl::desc("Only vectorize if you gain more than this "
>From 42de8a8f393dcddd097f1d8b6a5cf2f4ab6153e7 Mon Sep 17 00:00:00 2001
From: Han-Kuan Chen <hankuan.chen at sifive.com>
Date: Thu, 27 Jun 2024 01:59:46 -0700
Subject: [PATCH 2/7] [SLP][REVEC] Pre-commit test.
---
llvm/test/Transforms/SLPVectorizer/revec.ll | 32 +++++++++++++++++++++
1 file changed, 32 insertions(+)
create mode 100644 llvm/test/Transforms/SLPVectorizer/revec.ll
diff --git a/llvm/test/Transforms/SLPVectorizer/revec.ll b/llvm/test/Transforms/SLPVectorizer/revec.ll
new file mode 100644
index 0000000000000..ac9e0fdcaf205
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/revec.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=slp-vectorizer -S -slp-revec -slp-max-reg-size=1024 -slp-threshold=-100 %s | FileCheck %s
+
+define void @test1(ptr %a, ptr %b, ptr %c) {
+entry:
+ %arrayidx3 = getelementptr inbounds i32, ptr %a, i64 4
+ %arrayidx7 = getelementptr inbounds i32, ptr %a, i64 8
+ %arrayidx11 = getelementptr inbounds i32, ptr %a, i64 12
+ %0 = load <4 x i32>, ptr %a, align 4
+ %1 = load <4 x i32>, ptr %arrayidx3, align 4
+ %2 = load <4 x i32>, ptr %arrayidx7, align 4
+ %3 = load <4 x i32>, ptr %arrayidx11, align 4
+ %arrayidx19 = getelementptr inbounds i32, ptr %b, i64 4
+ %arrayidx23 = getelementptr inbounds i32, ptr %b, i64 8
+ %arrayidx27 = getelementptr inbounds i32, ptr %b, i64 12
+ %4 = load <4 x i32>, ptr %b, align 4
+ %5 = load <4 x i32>, ptr %arrayidx19, align 4
+ %6 = load <4 x i32>, ptr %arrayidx23, align 4
+ %7 = load <4 x i32>, ptr %arrayidx27, align 4
+ %add.i = add <4 x i32> %4, %0
+ %add.i63 = add <4 x i32> %5, %1
+ %add.i64 = add <4 x i32> %6, %2
+ %add.i65 = add <4 x i32> %7, %3
+ %arrayidx36 = getelementptr inbounds i32, ptr %c, i64 4
+ %arrayidx39 = getelementptr inbounds i32, ptr %c, i64 8
+ %arrayidx42 = getelementptr inbounds i32, ptr %c, i64 12
+ store <4 x i32> %add.i, ptr %c, align 4
+ store <4 x i32> %add.i63, ptr %arrayidx36, align 4
+ store <4 x i32> %add.i64, ptr %arrayidx39, align 4
+ store <4 x i32> %add.i65, ptr %arrayidx42, align 4
+ ret void
+}
>From 9361e8b08d65b9f6394e78ec637b5af44861f5d5 Mon Sep 17 00:00:00 2001
From: Han-Kuan Chen <hankuan.chen at sifive.com>
Date: Thu, 13 Jun 2024 01:58:02 -0700
Subject: [PATCH 3/7] [SLP][REVEC] Apply RunSLPReVectorization to the existing
code.
---
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index bb514ca646abb..cf4f127b6075b 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -231,12 +231,18 @@ static const unsigned MaxPHINumOperands = 128;
/// avoids spending time checking the cost model and realizing that they will
/// be inevitably scalarized.
static bool isValidElementType(Type *Ty) {
+ // TODO: Support ScalableVectorType.
+ if (isa<FixedVectorType>(Ty))
+ Ty = Ty->getScalarType();
return VectorType::isValidElementType(Ty) && !Ty->isX86_FP80Ty() &&
!Ty->isPPC_FP128Ty();
}
/// \returns the vector type of ScalarTy based on vectorization factor.
static FixedVectorType *getWidenedType(Type *ScalarTy, unsigned VF) {
+ if (auto *VecTy = dyn_cast<FixedVectorType>(ScalarTy))
+ return FixedVectorType::get(VecTy->getElementType(),
+ VF * VecTy->getNumElements());
return FixedVectorType::get(ScalarTy, VF);
}
@@ -6784,7 +6790,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
}
// Don't handle vectors.
- if (S.OpValue->getType()->isVectorTy() &&
+ if (!SLPReVec && S.OpValue->getType()->isVectorTy() &&
!isa<InsertElementInst>(S.OpValue)) {
LLVM_DEBUG(dbgs() << "SLP: Gathering due to vector type.\n");
newTreeEntry(VL, std::nullopt /*not vectorized*/, S, UserTreeIdx);
@@ -6792,7 +6798,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
}
if (StoreInst *SI = dyn_cast<StoreInst>(S.OpValue))
- if (SI->getValueOperand()->getType()->isVectorTy()) {
+ if (!SLPReVec && SI->getValueOperand()->getType()->isVectorTy()) {
LLVM_DEBUG(dbgs() << "SLP: Gathering due to store vector type.\n");
newTreeEntry(VL, std::nullopt /*not vectorized*/, S, UserTreeIdx);
return;
>From 15138b0e3eae919297a274bb66139b7fa1e9ddf5 Mon Sep 17 00:00:00 2001
From: Han-Kuan Chen <hankuan.chen at sifive.com>
Date: Thu, 27 Jun 2024 02:22:59 -0700
Subject: [PATCH 4/7] [SLP][REVEC] Make castToScalarTyElem support vector
instructions.
---
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index cf4f127b6075b..253900f43a8c0 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -11817,10 +11817,10 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis {
Value *castToScalarTyElem(Value *V,
std::optional<bool> IsSigned = std::nullopt) {
auto *VecTy = cast<VectorType>(V->getType());
- if (VecTy->getElementType() == ScalarTy)
+ if (VecTy->getElementType() == ScalarTy->getScalarType())
return V;
return Builder.CreateIntCast(
- V, VectorType::get(ScalarTy, VecTy->getElementCount()),
+ V, VectorType::get(ScalarTy->getScalarType(), VecTy->getElementCount()),
IsSigned.value_or(!isKnownNonNegative(V, SimplifyQuery(*R.DL))));
}
>From 6f9d0b83e6d71c3f117f60867b49af828d764da7 Mon Sep 17 00:00:00 2001
From: Han-Kuan Chen <hankuan.chen at sifive.com>
Date: Thu, 27 Jun 2024 00:09:23 -0700
Subject: [PATCH 5/7] [SLP][REVEC] NFC. Provide an universal interface for
getNumElements.
---
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 253900f43a8c0..165d464b27f58 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -238,12 +238,19 @@ static bool isValidElementType(Type *Ty) {
!Ty->isPPC_FP128Ty();
}
+/// \returns the number of elements for Ty.
+static unsigned getNumElements(Type *Ty) {
+ assert(!isa<ScalableVectorType>(Ty) &&
+ "ScalableVectorType is not supported.");
+ if (auto *VecTy = dyn_cast<FixedVectorType>(Ty))
+ return VecTy->getNumElements();
+ return 1;
+}
+
/// \returns the vector type of ScalarTy based on vectorization factor.
static FixedVectorType *getWidenedType(Type *ScalarTy, unsigned VF) {
- if (auto *VecTy = dyn_cast<FixedVectorType>(ScalarTy))
- return FixedVectorType::get(VecTy->getElementType(),
- VF * VecTy->getNumElements());
- return FixedVectorType::get(ScalarTy, VF);
+ return FixedVectorType::get(ScalarTy->getScalarType(),
+ VF * getNumElements(ScalarTy));
}
/// \returns True if the value is a constant (but not globals/constant
>From b149c98b3f3995da90e6531be0827250032b0d60 Mon Sep 17 00:00:00 2001
From: Han-Kuan Chen <hankuan.chen at sifive.com>
Date: Thu, 27 Jun 2024 23:59:01 -0700
Subject: [PATCH 6/7] [SLP][REVEC] Make vectorizeOperand support vector
instructions.
---
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 165d464b27f58..ced69e2dbd219 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -12212,7 +12212,8 @@ Value *BoUpSLP::vectorizeOperand(TreeEntry *E, unsigned NodeIdx,
return ShuffleBuilder.finalize(std::nullopt);
};
Value *V = vectorizeTree(VE, PostponedPHIs);
- if (VF != cast<FixedVectorType>(V->getType())->getNumElements()) {
+ if (VF * getNumElements(VL[0]->getType()) !=
+ cast<FixedVectorType>(V->getType())->getNumElements()) {
if (!VE->ReuseShuffleIndices.empty()) {
// Reshuffle to get only unique values.
// If some of the scalars are duplicated in the vectorization
>From 595fce726ad09e5fbc33d8f3f867e0f2ce77da41 Mon Sep 17 00:00:00 2001
From: Han-Kuan Chen <hankuan.chen at sifive.com>
Date: Fri, 28 Jun 2024 01:42:20 -0700
Subject: [PATCH 7/7] [SLP][REVEC] Update test1.
---
llvm/test/Transforms/SLPVectorizer/revec.ll | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/llvm/test/Transforms/SLPVectorizer/revec.ll b/llvm/test/Transforms/SLPVectorizer/revec.ll
index ac9e0fdcaf205..4b37b100763a9 100644
--- a/llvm/test/Transforms/SLPVectorizer/revec.ll
+++ b/llvm/test/Transforms/SLPVectorizer/revec.ll
@@ -2,6 +2,14 @@
; RUN: opt -passes=slp-vectorizer -S -slp-revec -slp-max-reg-size=1024 -slp-threshold=-100 %s | FileCheck %s
define void @test1(ptr %a, ptr %b, ptr %c) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr [[A:%.*]], align 4
+; CHECK-NEXT: [[TMP1:%.*]] = load <16 x i32>, ptr [[B:%.*]], align 4
+; CHECK-NEXT: [[TMP2:%.*]] = add <16 x i32> [[TMP1]], [[TMP0]]
+; CHECK-NEXT: store <16 x i32> [[TMP2]], ptr [[C:%.*]], align 4
+; CHECK-NEXT: ret void
+;
entry:
%arrayidx3 = getelementptr inbounds i32, ptr %a, i64 4
%arrayidx7 = getelementptr inbounds i32, ptr %a, i64 8
More information about the llvm-commits
mailing list