[llvm] [SandboxVec][BottomUpVec] Clean up dead instructions (PR #115267)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 6 21:33:23 PST 2024
https://github.com/vporpo created https://github.com/llvm/llvm-project/pull/115267
When scalars get replaced by vectors the original scalars may become dead. In that case erase them.
>From 4f84a5b896e79fe52105eaa9a1de78b7df7db56e Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Tue, 5 Nov 2024 08:48:43 -0800
Subject: [PATCH] [SandboxVec][BottomUpVec] Clean up dead instructions
When scalars get replaced by vectors the original scalars may
become dead. In that case erase them.
---
.../SandboxVectorizer/Passes/BottomUpVec.h | 2 +
.../SandboxVectorizer/Passes/BottomUpVec.cpp | 22 +++++++-
.../SandboxVectorizer/bottomup_basic.ll | 56 ++++++++-----------
3 files changed, 45 insertions(+), 35 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h
index 18e34bcec81b06..af27477f2ce303 100644
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h
@@ -25,10 +25,12 @@ namespace llvm::sandboxir {
class BottomUpVec final : public FunctionPass {
bool Change = false;
std::unique_ptr<LegalityAnalysis> Legality;
+ DenseSet<Instruction *> DeadInstrCandidates;
/// Creates and returns a vector instruction that replaces the instructions in
/// \p Bndl. \p Operands are the already vectorized operands.
Value *createVectorInstr(ArrayRef<Value *> Bndl, ArrayRef<Value *> Operands);
+ void tryEraseDeadInstrs();
Value *vectorizeRec(ArrayRef<Value *> Bndl);
bool tryVectorize(ArrayRef<Value *> Seeds);
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
index 0a930d30aeab58..ac2565816ff7d1 100644
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
@@ -153,6 +153,20 @@ Value *BottomUpVec::createVectorInstr(ArrayRef<Value *> Bndl,
// TODO: Propagate debug info.
}
+void BottomUpVec::tryEraseDeadInstrs() {
+ bool Change = true;
+ while (Change) {
+ Change = false;
+ for (Instruction *I : make_early_inc_range(DeadInstrCandidates)) {
+ if (I->hasNUses(0)) {
+ Change = true;
+ I->eraseFromParent();
+ DeadInstrCandidates.erase(I);
+ }
+ }
+ }
+}
+
Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl) {
Value *NewVec = nullptr;
const auto &LegalityRes = Legality->canVectorize(Bndl);
@@ -182,7 +196,11 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl) {
}
NewVec = createVectorInstr(Bndl, VecOperands);
- // TODO: Collect potentially dead instructions.
+ // Collect the original scalar instructions as they may be dead.
+ if (NewVec != nullptr) {
+ for (Value *V : Bndl)
+ DeadInstrCandidates.insert(cast<Instruction>(V));
+ }
break;
}
case LegalityResultID::Pack: {
@@ -194,7 +212,9 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl) {
}
bool BottomUpVec::tryVectorize(ArrayRef<Value *> Bndl) {
+ DeadInstrCandidates.clear();
vectorizeRec(Bndl);
+ tryEraseDeadInstrs();
return Change;
}
diff --git a/llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll b/llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll
index e56dbd75963f7a..4f8d821c7ed581 100644
--- a/llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll
@@ -6,11 +6,7 @@ define void @store_load(ptr %ptr) {
; CHECK-SAME: ptr [[PTR:%.*]]) {
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
-; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
-; CHECK-NEXT: store float [[LD0]], ptr [[PTR0]], align 4
-; CHECK-NEXT: store float [[LD1]], ptr [[PTR1]], align 4
; CHECK-NEXT: store <2 x float> [[VECL]], ptr [[PTR0]], align 4
; CHECK-NEXT: ret void
;
@@ -31,14 +27,8 @@ define void @store_fpext_load(ptr %ptr) {
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
; CHECK-NEXT: [[PTRD0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
; CHECK-NEXT: [[PTRD1:%.*]] = getelementptr double, ptr [[PTR]], i32 1
-; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[FPEXT0:%.*]] = fpext float [[LD0]] to double
-; CHECK-NEXT: [[FPEXT1:%.*]] = fpext float [[LD1]] to double
; CHECK-NEXT: [[VCAST:%.*]] = fpext <2 x float> [[VECL]] to <2 x double>
-; CHECK-NEXT: store double [[FPEXT0]], ptr [[PTRD0]], align 8
-; CHECK-NEXT: store double [[FPEXT1]], ptr [[PTRD1]], align 8
; CHECK-NEXT: store <2 x double> [[VCAST]], ptr [[PTRD0]], align 8
; CHECK-NEXT: ret void
;
@@ -62,20 +52,10 @@ define void @store_fcmp_zext_load(ptr %ptr) {
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
; CHECK-NEXT: [[PTRB0:%.*]] = getelementptr i32, ptr [[PTR]], i32 0
; CHECK-NEXT: [[PTRB1:%.*]] = getelementptr i32, ptr [[PTR]], i32 1
-; CHECK-NEXT: [[LDB0:%.*]] = load float, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[LDB1:%.*]] = load float, ptr [[PTR1]], align 4
; CHECK-NEXT: [[VECL1:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[LDA0:%.*]] = load float, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[LDA1:%.*]] = load float, ptr [[PTR1]], align 4
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[FCMP0:%.*]] = fcmp ogt float [[LDA0]], [[LDB0]]
-; CHECK-NEXT: [[FCMP1:%.*]] = fcmp ogt float [[LDA1]], [[LDB1]]
; CHECK-NEXT: [[VCMP:%.*]] = fcmp ogt <2 x float> [[VECL]], [[VECL1]]
-; CHECK-NEXT: [[ZEXT0:%.*]] = zext i1 [[FCMP0]] to i32
-; CHECK-NEXT: [[ZEXT1:%.*]] = zext i1 [[FCMP1]] to i32
; CHECK-NEXT: [[VCAST:%.*]] = zext <2 x i1> [[VCMP]] to <2 x i32>
-; CHECK-NEXT: store i32 [[ZEXT0]], ptr [[PTRB0]], align 4
-; CHECK-NEXT: store i32 [[ZEXT1]], ptr [[PTRB1]], align 4
; CHECK-NEXT: store <2 x i32> [[VCAST]], ptr [[PTRB0]], align 4
; CHECK-NEXT: ret void
;
@@ -101,17 +81,9 @@ define void @store_fadd_load(ptr %ptr) {
; CHECK-SAME: ptr [[PTR:%.*]]) {
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
-; CHECK-NEXT: [[LDA0:%.*]] = load float, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[LDA1:%.*]] = load float, ptr [[PTR1]], align 4
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[LDB0:%.*]] = load float, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[LDB1:%.*]] = load float, ptr [[PTR1]], align 4
; CHECK-NEXT: [[VECL1:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[FADD0:%.*]] = fadd float [[LDA0]], [[LDB0]]
-; CHECK-NEXT: [[FADD1:%.*]] = fadd float [[LDA1]], [[LDB1]]
; CHECK-NEXT: [[VEC:%.*]] = fadd <2 x float> [[VECL]], [[VECL1]]
-; CHECK-NEXT: store float [[FADD0]], ptr [[PTR0]], align 4
-; CHECK-NEXT: store float [[FADD1]], ptr [[PTR1]], align 4
; CHECK-NEXT: store <2 x float> [[VEC]], ptr [[PTR0]], align 4
; CHECK-NEXT: ret void
;
@@ -133,14 +105,8 @@ define void @store_fneg_load(ptr %ptr) {
; CHECK-SAME: ptr [[PTR:%.*]]) {
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
-; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
-; CHECK-NEXT: [[FNEG0:%.*]] = fneg float [[LD0]]
-; CHECK-NEXT: [[FNEG1:%.*]] = fneg float [[LD1]]
; CHECK-NEXT: [[VEC:%.*]] = fneg <2 x float> [[VECL]]
-; CHECK-NEXT: store float [[FNEG0]], ptr [[PTR0]], align 4
-; CHECK-NEXT: store float [[FNEG1]], ptr [[PTR1]], align 4
; CHECK-NEXT: store <2 x float> [[VEC]], ptr [[PTR0]], align 4
; CHECK-NEXT: ret void
;
@@ -155,3 +121,25 @@ define void @store_fneg_load(ptr %ptr) {
ret void
}
+define float @sclars_with_external_uses_not_dead(ptr %ptr) {
+; CHECK-LABEL: define float @sclars_with_external_uses_not_dead(
+; CHECK-SAME: ptr [[PTR:%.*]]) {
+; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
+; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
+; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
+; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
+; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
+; CHECK-NEXT: store <2 x float> [[VECL]], ptr [[PTR0]], align 4
+; CHECK-NEXT: [[USER:%.*]] = fneg float [[LD1]]
+; CHECK-NEXT: ret float [[LD0]]
+;
+ %ptr0 = getelementptr float, ptr %ptr, i32 0
+ %ptr1 = getelementptr float, ptr %ptr, i32 1
+ %ld0 = load float, ptr %ptr0
+ %ld1 = load float, ptr %ptr1
+ store float %ld0, ptr %ptr0
+ store float %ld1, ptr %ptr1
+ %user = fneg float %ld1
+ ret float %ld0
+}
+
More information about the llvm-commits
mailing list