Skip to content

Commit 7c51c31

Browse files
authored
[SandboxVec][BottomUpVec] Clean up dead address instrs (#122536)
When we vectorize loads or stores we only keep the address of the first lane. The rest may become dead. This patch adds the address operands of vectorized loads or stores to the dead candidates set, such that they get erased if dead.
1 parent 5870815 commit 7c51c31

File tree

5 files changed

+35
-21
lines changed

5 files changed

+35
-21
lines changed

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

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

3030
/// Creates and returns a vector instruction that replaces the instructions in
3131
/// \p Bndl. \p Operands are the already vectorized operands.
@@ -35,6 +35,7 @@ class BottomUpVec final : public FunctionPass {
3535
void tryEraseDeadInstrs();
3636
/// Packs all elements of \p ToPack into a vector and returns that vector.
3737
Value *createPack(ArrayRef<Value *> ToPack);
38+
void collectPotentiallyDeadInstrs(ArrayRef<Value *> Bndl);
3839
/// Recursively try to vectorize \p Bndl and its operands.
3940
Value *vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth);
4041
/// Entry point for vectorization starting from \p Seeds.

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

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,11 @@ Value *BottomUpVec::createVectorInstr(ArrayRef<Value *> Bndl,
157157

158158
void BottomUpVec::tryEraseDeadInstrs() {
159159
// Visiting the dead instructions bottom-to-top.
160-
sort(DeadInstrCandidates,
160+
SmallVector<Instruction *> SortedDeadInstrCandidates(
161+
DeadInstrCandidates.begin(), DeadInstrCandidates.end());
162+
sort(SortedDeadInstrCandidates,
161163
[](Instruction *I1, Instruction *I2) { return I1->comesBefore(I2); });
162-
for (Instruction *I : reverse(DeadInstrCandidates)) {
164+
for (Instruction *I : reverse(SortedDeadInstrCandidates)) {
163165
if (I->hasNUses(0))
164166
I->eraseFromParent();
165167
}
@@ -218,6 +220,31 @@ Value *BottomUpVec::createPack(ArrayRef<Value *> ToPack) {
218220
return LastInsert;
219221
}
220222

223+
void BottomUpVec::collectPotentiallyDeadInstrs(ArrayRef<Value *> Bndl) {
224+
for (Value *V : Bndl)
225+
DeadInstrCandidates.insert(cast<Instruction>(V));
226+
// Also collect the GEPs of vectorized loads and stores.
227+
auto Opcode = cast<Instruction>(Bndl[0])->getOpcode();
228+
switch (Opcode) {
229+
case Instruction::Opcode::Load: {
230+
for (Value *V : drop_begin(Bndl))
231+
if (auto *Ptr =
232+
dyn_cast<Instruction>(cast<LoadInst>(V)->getPointerOperand()))
233+
DeadInstrCandidates.insert(Ptr);
234+
break;
235+
}
236+
case Instruction::Opcode::Store: {
237+
for (Value *V : drop_begin(Bndl))
238+
if (auto *Ptr =
239+
dyn_cast<Instruction>(cast<StoreInst>(V)->getPointerOperand()))
240+
DeadInstrCandidates.insert(Ptr);
241+
break;
242+
}
243+
default:
244+
break;
245+
}
246+
}
247+
221248
Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
222249
Value *NewVec = nullptr;
223250
const auto &LegalityRes = Legality->canVectorize(Bndl);
@@ -247,11 +274,10 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
247274
}
248275
NewVec = createVectorInstr(Bndl, VecOperands);
249276

250-
// Collect the original scalar instructions as they may be dead.
251-
if (NewVec != nullptr) {
252-
for (Value *V : Bndl)
253-
DeadInstrCandidates.push_back(cast<Instruction>(V));
254-
}
277+
// Collect any potentially dead scalar instructions, including the original
278+
// scalars and pointer operands of loads/stores.
279+
if (NewVec != nullptr)
280+
collectPotentiallyDeadInstrs(Bndl);
255281
break;
256282
}
257283
case LegalityResultID::Pack: {

llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ define void @store_load(ptr %ptr) {
55
; CHECK-LABEL: define void @store_load(
66
; CHECK-SAME: ptr [[PTR:%.*]]) {
77
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
8-
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
98
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
109
; CHECK-NEXT: store <2 x float> [[VECL]], ptr [[PTR0]], align 4
1110
; CHECK-NEXT: ret void
@@ -24,9 +23,7 @@ define void @store_fpext_load(ptr %ptr) {
2423
; CHECK-LABEL: define void @store_fpext_load(
2524
; CHECK-SAME: ptr [[PTR:%.*]]) {
2625
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
27-
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
2826
; CHECK-NEXT: [[PTRD0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
29-
; CHECK-NEXT: [[PTRD1:%.*]] = getelementptr double, ptr [[PTR]], i32 1
3027
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
3128
; CHECK-NEXT: [[VCAST:%.*]] = fpext <2 x float> [[VECL]] to <2 x double>
3229
; CHECK-NEXT: store <2 x double> [[VCAST]], ptr [[PTRD0]], align 8
@@ -49,9 +46,7 @@ define void @store_fcmp_zext_load(ptr %ptr) {
4946
; CHECK-LABEL: define void @store_fcmp_zext_load(
5047
; CHECK-SAME: ptr [[PTR:%.*]]) {
5148
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
52-
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
5349
; CHECK-NEXT: [[PTRB0:%.*]] = getelementptr i32, ptr [[PTR]], i32 0
54-
; CHECK-NEXT: [[PTRB1:%.*]] = getelementptr i32, ptr [[PTR]], i32 1
5550
; CHECK-NEXT: [[VECL1:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
5651
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
5752
; CHECK-NEXT: [[VCMP:%.*]] = fcmp ogt <2 x float> [[VECL]], [[VECL1]]
@@ -80,7 +75,6 @@ define void @store_fadd_load(ptr %ptr) {
8075
; CHECK-LABEL: define void @store_fadd_load(
8176
; CHECK-SAME: ptr [[PTR:%.*]]) {
8277
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
83-
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
8478
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
8579
; CHECK-NEXT: [[VECL1:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
8680
; CHECK-NEXT: [[VEC:%.*]] = fadd <2 x float> [[VECL]], [[VECL1]]
@@ -104,7 +98,6 @@ define void @store_fneg_load(ptr %ptr) {
10498
; CHECK-LABEL: define void @store_fneg_load(
10599
; CHECK-SAME: ptr [[PTR:%.*]]) {
106100
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
107-
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
108101
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
109102
; CHECK-NEXT: [[VEC:%.*]] = fneg <2 x float> [[VECL]]
110103
; CHECK-NEXT: store <2 x float> [[VEC]], ptr [[PTR0]], align 4
@@ -147,7 +140,6 @@ define void @pack_scalars(ptr %ptr, ptr %ptr2) {
147140
; CHECK-LABEL: define void @pack_scalars(
148141
; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTR2:%.*]]) {
149142
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
150-
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
151143
; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
152144
; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR2]], align 4
153145
; CHECK-NEXT: [[PACK:%.*]] = insertelement <2 x float> poison, float [[LD0]], i32 0
@@ -191,7 +183,6 @@ define void @pack_vectors(ptr %ptr, ptr %ptr2) {
191183
; CHECK-LABEL: define void @pack_vectors(
192184
; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTR2:%.*]]) {
193185
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
194-
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 2
195186
; CHECK-NEXT: [[LD0:%.*]] = load <2 x float>, ptr [[PTR0]], align 8
196187
; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR2]], align 4
197188
; CHECK-NEXT: [[VPACK:%.*]] = extractelement <2 x float> [[LD0]], i32 0

llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ define void @slice_seeds(ptr %ptr, float %val) {
77
; CHECK-LABEL: define void @slice_seeds(
88
; CHECK-SAME: ptr [[PTR:%.*]], float [[VAL:%.*]]) {
99
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
10-
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
1110
; CHECK-NEXT: [[PTR2:%.*]] = getelementptr float, ptr [[PTR]], i32 2
1211
; CHECK-NEXT: [[LD2:%.*]] = load float, ptr [[PTR2]], align 4
1312
; CHECK-NEXT: store float [[LD2]], ptr [[PTR2]], align 4

llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice_pow2.ll

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ define void @pow2(ptr %ptr, float %val) {
66
; POW2-LABEL: define void @pow2(
77
; POW2-SAME: ptr [[PTR:%.*]], float [[VAL:%.*]]) {
88
; POW2-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
9-
; POW2-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
109
; POW2-NEXT: [[PTR2:%.*]] = getelementptr float, ptr [[PTR]], i32 2
1110
; POW2-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
1211
; POW2-NEXT: [[LD2:%.*]] = load float, ptr [[PTR2]], align 4
@@ -17,8 +16,6 @@ define void @pow2(ptr %ptr, float %val) {
1716
; NON-POW2-LABEL: define void @pow2(
1817
; NON-POW2-SAME: ptr [[PTR:%.*]], float [[VAL:%.*]]) {
1918
; NON-POW2-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
20-
; NON-POW2-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
21-
; NON-POW2-NEXT: [[PTR2:%.*]] = getelementptr float, ptr [[PTR]], i32 2
2219
; NON-POW2-NEXT: [[PACK2:%.*]] = load <3 x float>, ptr [[PTR0]], align 4
2320
; NON-POW2-NEXT: store <3 x float> [[PACK2]], ptr [[PTR0]], align 4
2421
; NON-POW2-NEXT: ret void

0 commit comments

Comments
 (0)