Skip to content

Commit 7dffc96

Browse files
authored
[SandboxVec][BottomUpVec] Clean up dead instructions (#115267)
When scalars get replaced by vectors the original scalars may become dead. In that case erase them.
1 parent 6fb36f0 commit 7dffc96

File tree

3 files changed

+42
-35
lines changed

3 files changed

+42
-35
lines changed

llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ namespace llvm::sandboxir {
2525
class BottomUpVec final : public FunctionPass {
2626
bool Change = false;
2727
std::unique_ptr<LegalityAnalysis> Legality;
28+
SmallVector<Instruction *> DeadInstrCandidates;
2829

2930
/// Creates and returns a vector instruction that replaces the instructions in
3031
/// \p Bndl. \p Operands are the already vectorized operands.
3132
Value *createVectorInstr(ArrayRef<Value *> Bndl, ArrayRef<Value *> Operands);
33+
void tryEraseDeadInstrs();
3234
Value *vectorizeRec(ArrayRef<Value *> Bndl);
3335
bool tryVectorize(ArrayRef<Value *> Seeds);
3436

llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,17 @@ Value *BottomUpVec::createVectorInstr(ArrayRef<Value *> Bndl,
153153
// TODO: Propagate debug info.
154154
}
155155

156+
void BottomUpVec::tryEraseDeadInstrs() {
157+
// Visiting the dead instructions bottom-to-top.
158+
sort(DeadInstrCandidates,
159+
[](Instruction *I1, Instruction *I2) { return I1->comesBefore(I2); });
160+
for (Instruction *I : reverse(DeadInstrCandidates)) {
161+
if (I->hasNUses(0))
162+
I->eraseFromParent();
163+
}
164+
DeadInstrCandidates.clear();
165+
}
166+
156167
Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl) {
157168
Value *NewVec = nullptr;
158169
const auto &LegalityRes = Legality->canVectorize(Bndl);
@@ -182,7 +193,11 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl) {
182193
}
183194
NewVec = createVectorInstr(Bndl, VecOperands);
184195

185-
// TODO: Collect potentially dead instructions.
196+
// Collect the original scalar instructions as they may be dead.
197+
if (NewVec != nullptr) {
198+
for (Value *V : Bndl)
199+
DeadInstrCandidates.push_back(cast<Instruction>(V));
200+
}
186201
break;
187202
}
188203
case LegalityResultID::Pack: {
@@ -194,7 +209,9 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl) {
194209
}
195210

196211
bool BottomUpVec::tryVectorize(ArrayRef<Value *> Bndl) {
212+
DeadInstrCandidates.clear();
197213
vectorizeRec(Bndl);
214+
tryEraseDeadInstrs();
198215
return Change;
199216
}
200217

llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,7 @@ define void @store_load(ptr %ptr) {
66
; CHECK-SAME: ptr [[PTR:%.*]]) {
77
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
88
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
9-
; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
10-
; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
119
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
12-
; CHECK-NEXT: store float [[LD0]], ptr [[PTR0]], align 4
13-
; CHECK-NEXT: store float [[LD1]], ptr [[PTR1]], align 4
1410
; CHECK-NEXT: store <2 x float> [[VECL]], ptr [[PTR0]], align 4
1511
; CHECK-NEXT: ret void
1612
;
@@ -31,14 +27,8 @@ define void @store_fpext_load(ptr %ptr) {
3127
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
3228
; CHECK-NEXT: [[PTRD0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
3329
; CHECK-NEXT: [[PTRD1:%.*]] = getelementptr double, ptr [[PTR]], i32 1
34-
; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
35-
; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
3630
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
37-
; CHECK-NEXT: [[FPEXT0:%.*]] = fpext float [[LD0]] to double
38-
; CHECK-NEXT: [[FPEXT1:%.*]] = fpext float [[LD1]] to double
3931
; CHECK-NEXT: [[VCAST:%.*]] = fpext <2 x float> [[VECL]] to <2 x double>
40-
; CHECK-NEXT: store double [[FPEXT0]], ptr [[PTRD0]], align 8
41-
; CHECK-NEXT: store double [[FPEXT1]], ptr [[PTRD1]], align 8
4232
; CHECK-NEXT: store <2 x double> [[VCAST]], ptr [[PTRD0]], align 8
4333
; CHECK-NEXT: ret void
4434
;
@@ -62,20 +52,10 @@ define void @store_fcmp_zext_load(ptr %ptr) {
6252
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
6353
; CHECK-NEXT: [[PTRB0:%.*]] = getelementptr i32, ptr [[PTR]], i32 0
6454
; CHECK-NEXT: [[PTRB1:%.*]] = getelementptr i32, ptr [[PTR]], i32 1
65-
; CHECK-NEXT: [[LDB0:%.*]] = load float, ptr [[PTR0]], align 4
66-
; CHECK-NEXT: [[LDB1:%.*]] = load float, ptr [[PTR1]], align 4
6755
; CHECK-NEXT: [[VECL1:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
68-
; CHECK-NEXT: [[LDA0:%.*]] = load float, ptr [[PTR0]], align 4
69-
; CHECK-NEXT: [[LDA1:%.*]] = load float, ptr [[PTR1]], align 4
7056
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
71-
; CHECK-NEXT: [[FCMP0:%.*]] = fcmp ogt float [[LDA0]], [[LDB0]]
72-
; CHECK-NEXT: [[FCMP1:%.*]] = fcmp ogt float [[LDA1]], [[LDB1]]
7357
; CHECK-NEXT: [[VCMP:%.*]] = fcmp ogt <2 x float> [[VECL]], [[VECL1]]
74-
; CHECK-NEXT: [[ZEXT0:%.*]] = zext i1 [[FCMP0]] to i32
75-
; CHECK-NEXT: [[ZEXT1:%.*]] = zext i1 [[FCMP1]] to i32
7658
; CHECK-NEXT: [[VCAST:%.*]] = zext <2 x i1> [[VCMP]] to <2 x i32>
77-
; CHECK-NEXT: store i32 [[ZEXT0]], ptr [[PTRB0]], align 4
78-
; CHECK-NEXT: store i32 [[ZEXT1]], ptr [[PTRB1]], align 4
7959
; CHECK-NEXT: store <2 x i32> [[VCAST]], ptr [[PTRB0]], align 4
8060
; CHECK-NEXT: ret void
8161
;
@@ -101,17 +81,9 @@ define void @store_fadd_load(ptr %ptr) {
10181
; CHECK-SAME: ptr [[PTR:%.*]]) {
10282
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
10383
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
104-
; CHECK-NEXT: [[LDA0:%.*]] = load float, ptr [[PTR0]], align 4
105-
; CHECK-NEXT: [[LDA1:%.*]] = load float, ptr [[PTR1]], align 4
10684
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
107-
; CHECK-NEXT: [[LDB0:%.*]] = load float, ptr [[PTR0]], align 4
108-
; CHECK-NEXT: [[LDB1:%.*]] = load float, ptr [[PTR1]], align 4
10985
; CHECK-NEXT: [[VECL1:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
110-
; CHECK-NEXT: [[FADD0:%.*]] = fadd float [[LDA0]], [[LDB0]]
111-
; CHECK-NEXT: [[FADD1:%.*]] = fadd float [[LDA1]], [[LDB1]]
11286
; CHECK-NEXT: [[VEC:%.*]] = fadd <2 x float> [[VECL]], [[VECL1]]
113-
; CHECK-NEXT: store float [[FADD0]], ptr [[PTR0]], align 4
114-
; CHECK-NEXT: store float [[FADD1]], ptr [[PTR1]], align 4
11587
; CHECK-NEXT: store <2 x float> [[VEC]], ptr [[PTR0]], align 4
11688
; CHECK-NEXT: ret void
11789
;
@@ -133,14 +105,8 @@ define void @store_fneg_load(ptr %ptr) {
133105
; CHECK-SAME: ptr [[PTR:%.*]]) {
134106
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
135107
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
136-
; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
137-
; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
138108
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
139-
; CHECK-NEXT: [[FNEG0:%.*]] = fneg float [[LD0]]
140-
; CHECK-NEXT: [[FNEG1:%.*]] = fneg float [[LD1]]
141109
; CHECK-NEXT: [[VEC:%.*]] = fneg <2 x float> [[VECL]]
142-
; CHECK-NEXT: store float [[FNEG0]], ptr [[PTR0]], align 4
143-
; CHECK-NEXT: store float [[FNEG1]], ptr [[PTR1]], align 4
144110
; CHECK-NEXT: store <2 x float> [[VEC]], ptr [[PTR0]], align 4
145111
; CHECK-NEXT: ret void
146112
;
@@ -155,3 +121,25 @@ define void @store_fneg_load(ptr %ptr) {
155121
ret void
156122
}
157123

124+
define float @scalars_with_external_uses_not_dead(ptr %ptr) {
125+
; CHECK-LABEL: define float @scalars_with_external_uses_not_dead(
126+
; CHECK-SAME: ptr [[PTR:%.*]]) {
127+
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
128+
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
129+
; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
130+
; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
131+
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
132+
; CHECK-NEXT: store <2 x float> [[VECL]], ptr [[PTR0]], align 4
133+
; CHECK-NEXT: [[USER:%.*]] = fneg float [[LD1]]
134+
; CHECK-NEXT: ret float [[LD0]]
135+
;
136+
%ptr0 = getelementptr float, ptr %ptr, i32 0
137+
%ptr1 = getelementptr float, ptr %ptr, i32 1
138+
%ld0 = load float, ptr %ptr0
139+
%ld1 = load float, ptr %ptr1
140+
store float %ld0, ptr %ptr0
141+
store float %ld1, ptr %ptr1
142+
%user = fneg float %ld1
143+
ret float %ld0
144+
}
145+

0 commit comments

Comments
 (0)