Skip to content

Commit a796f36

Browse files
rampitecDebadri Basak
authored andcommitted
[AMDGPU] Reset VGPR MSBs at the end of fallthrough basic block (llvm#164901)
By convention a basic block shall start with MSBs zero. We also need to know a previous mode in all cases as SWDEV-562450 asks to record the old mode in the high bits of the mode.
1 parent 95b250f commit a796f36

File tree

2 files changed

+39
-42
lines changed

2 files changed

+39
-42
lines changed

llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ class AMDGPULowerVGPREncoding {
8282
const SIInstrInfo *TII;
8383
const SIRegisterInfo *TRI;
8484

85+
// Current basic block.
86+
MachineBasicBlock *MBB;
87+
8588
/// Most recent s_set_* instruction.
8689
MachineInstr *MostRecentModeSet;
8790

88-
/// Whether the current mode is known.
89-
bool CurrentModeKnown;
90-
9191
/// Current mode bits.
9292
ModeTy CurrentMode;
9393

@@ -108,10 +108,13 @@ class AMDGPULowerVGPREncoding {
108108
MachineInstr *Clause;
109109

110110
/// Insert mode change before \p I. \returns true if mode was changed.
111-
bool setMode(ModeTy NewMode, ModeTy Mask, MachineInstr *I);
111+
bool setMode(ModeTy NewMode, ModeTy Mask,
112+
MachineBasicBlock::instr_iterator I);
112113

113114
/// Reset mode to default.
114-
void resetMode(MachineInstr *I) { setMode(ModeTy(), ModeTy::fullMask(), I); }
115+
void resetMode(MachineBasicBlock::instr_iterator I) {
116+
setMode(ModeTy(), ModeTy::fullMask(), I);
117+
}
115118

116119
/// If \p MO references VGPRs, return the MSBs. Otherwise, return nullopt.
117120
std::optional<unsigned> getMSBs(const MachineOperand &MO) const;
@@ -130,38 +133,35 @@ class AMDGPULowerVGPREncoding {
130133
/// Check if an instruction \p I is within a clause and returns a suitable
131134
/// iterator to insert mode change. It may also modify the S_CLAUSE
132135
/// instruction to extend it or drop the clause if it cannot be adjusted.
133-
MachineInstr *handleClause(MachineInstr *I);
136+
MachineBasicBlock::instr_iterator
137+
handleClause(MachineBasicBlock::instr_iterator I);
134138
};
135139

136140
bool AMDGPULowerVGPREncoding::setMode(ModeTy NewMode, ModeTy Mask,
137-
MachineInstr *I) {
141+
MachineBasicBlock::instr_iterator I) {
138142
assert((NewMode.raw_bits() & ~Mask.raw_bits()).none());
139143

140-
if (CurrentModeKnown) {
141-
auto Delta = NewMode.raw_bits() ^ CurrentMode.raw_bits();
144+
auto Delta = NewMode.raw_bits() ^ CurrentMode.raw_bits();
142145

143-
if ((Delta & Mask.raw_bits()).none()) {
144-
CurrentMask |= Mask;
145-
return false;
146-
}
146+
if ((Delta & Mask.raw_bits()).none()) {
147+
CurrentMask |= Mask;
148+
return false;
149+
}
147150

148-
if (MostRecentModeSet && (Delta & CurrentMask.raw_bits()).none()) {
149-
CurrentMode |= NewMode;
150-
CurrentMask |= Mask;
151+
if (MostRecentModeSet && (Delta & CurrentMask.raw_bits()).none()) {
152+
CurrentMode |= NewMode;
153+
CurrentMask |= Mask;
151154

152-
MostRecentModeSet->getOperand(0).setImm(CurrentMode);
153-
return true;
154-
}
155+
MostRecentModeSet->getOperand(0).setImm(CurrentMode);
156+
return true;
155157
}
156158

157159
I = handleClause(I);
158160
MostRecentModeSet =
159-
BuildMI(*I->getParent(), I, {}, TII->get(AMDGPU::S_SET_VGPR_MSB))
160-
.addImm(NewMode);
161+
BuildMI(*MBB, I, {}, TII->get(AMDGPU::S_SET_VGPR_MSB)).addImm(NewMode);
161162

162163
CurrentMode = NewMode;
163164
CurrentMask = Mask;
164-
CurrentModeKnown = true;
165165
return true;
166166
}
167167

@@ -233,21 +233,22 @@ bool AMDGPULowerVGPREncoding::runOnMachineInstr(MachineInstr &MI) {
233233
if (Ops.first) {
234234
ModeTy NewMode, Mask;
235235
computeMode(NewMode, Mask, MI, Ops.first, Ops.second);
236-
return setMode(NewMode, Mask, &MI);
236+
return setMode(NewMode, Mask, MI.getIterator());
237237
}
238238
assert(!TII->hasVGPRUses(MI) || MI.isMetaInstruction() || MI.isPseudo());
239239

240240
return false;
241241
}
242242

243-
MachineInstr *AMDGPULowerVGPREncoding::handleClause(MachineInstr *I) {
243+
MachineBasicBlock::instr_iterator
244+
AMDGPULowerVGPREncoding::handleClause(MachineBasicBlock::instr_iterator I) {
244245
if (!ClauseRemaining)
245246
return I;
246247

247248
// A clause cannot start with a special instruction, place it right before
248249
// the clause.
249250
if (ClauseRemaining == ClauseLen) {
250-
I = Clause->getPrevNode();
251+
I = Clause->getPrevNode()->getIterator();
251252
assert(I->isBundle());
252253
return I;
253254
}
@@ -284,27 +285,26 @@ bool AMDGPULowerVGPREncoding::run(MachineFunction &MF) {
284285
ClauseLen = ClauseRemaining = 0;
285286
CurrentMode.reset();
286287
CurrentMask.reset();
287-
CurrentModeKnown = true;
288288
for (auto &MBB : MF) {
289289
MostRecentModeSet = nullptr;
290+
this->MBB = &MBB;
290291

291292
for (auto &MI : llvm::make_early_inc_range(MBB.instrs())) {
292293
if (MI.isMetaInstruction())
293294
continue;
294295

295296
if (MI.isTerminator() || MI.isCall()) {
296297
if (MI.getOpcode() == AMDGPU::S_ENDPGM ||
297-
MI.getOpcode() == AMDGPU::S_ENDPGM_SAVED) {
298+
MI.getOpcode() == AMDGPU::S_ENDPGM_SAVED)
298299
CurrentMode.reset();
299-
CurrentModeKnown = true;
300-
} else
301-
resetMode(&MI);
300+
else
301+
resetMode(MI.getIterator());
302302
continue;
303303
}
304304

305305
if (MI.isInlineAsm()) {
306306
if (TII->hasVGPRUses(MI))
307-
resetMode(&MI);
307+
resetMode(MI.getIterator());
308308
continue;
309309
}
310310

@@ -323,14 +323,8 @@ bool AMDGPULowerVGPREncoding::run(MachineFunction &MF) {
323323
--ClauseRemaining;
324324
}
325325

326-
// If we're falling through to a block that has at least one other
327-
// predecessor, we no longer know the mode.
328-
MachineBasicBlock *Next = MBB.getNextNode();
329-
if (Next && Next->pred_size() >= 2 &&
330-
llvm::is_contained(Next->predecessors(), &MBB)) {
331-
if (CurrentMode.raw_bits().any())
332-
CurrentModeKnown = false;
333-
}
326+
// Reset the mode if we are falling through.
327+
resetMode(MBB.instr_end());
334328
}
335329

336330
return Changed;

llvm/test/CodeGen/AMDGPU/vgpr-lowering-gfx1250.mir

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -478,16 +478,18 @@ body: |
478478
; ASM: .LBB{{.*_1}}:
479479
; GCN-NEXT: s_set_vgpr_msb 64
480480
; GCN-NEXT: v_mov_b32_e32 v0 /*v256*/, v1
481+
; GCN-NEXT: s_set_vgpr_msb 0
481482
$vgpr256 = V_MOV_B32_e32 undef $vgpr1, implicit $exec
482483
483-
; No mode switch on fall through
484+
; Reset on fallthrough block end
484485
485486
bb.2:
486487
; ASM-NEXT: %bb.2:
487-
; GCN-NEXT: s_nop 0
488+
; GCN-NEXT: s_set_vgpr_msb 64
489+
; GCN-NEXT: v_mov_b32_e32 v0 /*v256*/, v1
488490
; GCN-NEXT: s_set_vgpr_msb 0
489491
; GCN-NEXT: s_branch
490-
S_NOP 0
492+
$vgpr256 = V_MOV_B32_e32 undef $vgpr1, implicit $exec
491493
S_BRANCH %bb.3
492494
493495
; Reset mode on terminator
@@ -574,6 +576,7 @@ body: |
574576
; ASM: %bb.0:
575577
; GCN-NEXT: s_set_vgpr_msb 64
576578
; GCN-NEXT: v_mov_b32_e32 v0 /*v256*/, v0
579+
; GCN-NEXT: s_set_vgpr_msb 0
577580
$vgpr256 = V_MOV_B32_e32 undef $vgpr0, implicit $exec
578581
579582
bb.1:

0 commit comments

Comments
 (0)