Skip to content

Commit a85954e

Browse files
lucas-ramigithub-actions[bot]
authored andcommitted
Automerge: [AMDGPU][CodeGen] Place S_NOP after S_SETREG_IMM32_B32 in predecessor MBB (#209620)
When placing a `S_SET_VGPR_MSB` at the beginning of a block, check whether there exists a `S_SETREG_IMM32_B32(MODE)` in the predecessor block that falls-through into it; if there is one a `S_NOP` has to be inserted in between them.
2 parents 3b411f7 + 4279d52 commit a85954e

2 files changed

Lines changed: 195 additions & 11 deletions

File tree

llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "SIDefines.h"
4747
#include "SIInstrInfo.h"
4848
#include "llvm/ADT/bit.h"
49+
#include "llvm/CodeGen/MachineBasicBlock.h"
4950
#include "llvm/Support/Debug.h"
5051
#include "llvm/Support/MathExtras.h"
5152

@@ -432,23 +433,41 @@ AMDGPULowerVGPREncoding::handleCoissue(MachineBasicBlock::instr_iterator I) {
432433
return I;
433434
}
434435

436+
/// Returns whether \p MI is a S_SETREG_IMM32_B32(MODE).
437+
static bool isSetregMode(const MachineInstr &MI, const SIInstrInfo &TII) {
438+
if (MI.getOpcode() != AMDGPU::S_SETREG_IMM32_B32)
439+
return false;
440+
441+
const MachineOperand *SIMM16Op =
442+
TII.getNamedOperand(MI, AMDGPU::OpName::simm16);
443+
auto [HwRegId, _Offset, _Size] =
444+
AMDGPU::Hwreg::HwregEncoding::decode(SIMM16Op->getImm());
445+
return HwRegId == AMDGPU::Hwreg::ID_MODE;
446+
}
447+
435448
bool AMDGPULowerVGPREncoding::needNopBeforeSetVGPRMSB(
436449
MachineBasicBlock::instr_iterator I) {
437-
while (I != MBB->begin()) {
438-
I = std::prev(I);
439-
if (I->getOpcode() == AMDGPU::S_SETREG_IMM32_B32) {
440-
MachineOperand *SIMM16Op =
441-
TII->getNamedOperand(*I, AMDGPU::OpName::simm16);
442-
auto [HwRegId, Offset, Size] =
443-
AMDGPU::Hwreg::HwregEncoding::decode(SIMM16Op->getImm());
444-
if (HwRegId == AMDGPU::Hwreg::ID_MODE)
450+
MachineBasicBlock *CurrentMBB = MBB;
451+
while (true) {
452+
// Walk the block backward until we hit a non-meta instruction or the
453+
// beginning of the block.
454+
while (I != CurrentMBB->instr_begin()) {
455+
I = std::prev(I);
456+
if (isSetregMode(*I, *TII))
445457
return true;
458+
if (!I->isMetaInstruction())
459+
return false;
446460
}
447-
if (!I->isMetaInstruction())
461+
462+
// Look for a potential fallthrough predecessor block. When it ends with a
463+
// S_SETREG_IMM32_B32(MODE) we need to insert a S_NOP too. We assume that an
464+
// explicit jump to the current block from the block that would otherwise
465+
// have naturally fallen through to it will remain in the final assembly.
466+
CurrentMBB = CurrentMBB->getPrevNode();
467+
if (!CurrentMBB || !CurrentMBB->canFallThrough())
448468
return false;
469+
I = CurrentMBB->instr_end();
449470
}
450-
// FIXME: Return true if the previous MBB falls through and ends with
451-
// S_SETREG_IMM32_B32.
452471
return false;
453472
}
454473

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
2+
# RUN: llc -mtriple=amdgcn -mcpu=gfx1250 -run-pass=amdgpu-lower-vgpr-encoding -o - %s | FileCheck %s
3+
4+
# All S_SETREG_IMM32_B32(MODE) in the file have size=4(<12) and imm32[12:19]=0.
5+
# This ensures they do not cause the insertion of a S_NOP by default. All
6+
# V_MOV_B32_e32 use src0/dst VGPRs with MSB=1 which triggers the check for a
7+
# S_SETREG_IMM32_B32(MODE) in their block predecessors.
8+
9+
---
10+
name: implicit_fallthrough_insert_nop
11+
tracksRegLiveness: true
12+
body: |
13+
; CHECK-LABEL: name: implicit_fallthrough_insert_nop
14+
; CHECK: bb.0:
15+
; CHECK-NEXT: successors: %bb.1(0x80000000)
16+
; CHECK-NEXT: {{ $}}
17+
; CHECK-NEXT: S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
18+
; CHECK-NEXT: {{ $}}
19+
; CHECK-NEXT: bb.1:
20+
; CHECK-NEXT: S_NOP 0
21+
; CHECK-NEXT: S_SET_VGPR_MSB 65, implicit-def $mode
22+
; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
23+
; CHECK-NEXT: S_ENDPGM 0
24+
bb.0:
25+
S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
26+
27+
bb.1:
28+
$vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
29+
S_ENDPGM 0
30+
...
31+
32+
---
33+
name: explicit_fallthrough_dont_insert_nop
34+
tracksRegLiveness: true
35+
body: |
36+
; CHECK-LABEL: name: explicit_fallthrough_dont_insert_nop
37+
; CHECK: bb.0:
38+
; CHECK-NEXT: successors: %bb.1(0x80000000)
39+
; CHECK-NEXT: {{ $}}
40+
; CHECK-NEXT: S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
41+
; CHECK-NEXT: S_BRANCH %bb.1
42+
; CHECK-NEXT: {{ $}}
43+
; CHECK-NEXT: bb.1:
44+
; CHECK-NEXT: S_SET_VGPR_MSB 65, implicit-def $mode
45+
; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
46+
; CHECK-NEXT: S_ENDPGM 0
47+
bb.0:
48+
S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
49+
S_BRANCH %bb.1
50+
51+
bb.1:
52+
$vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
53+
S_ENDPGM 0
54+
...
55+
56+
---
57+
name: vgpr_instr_in_second_position_dont_insert_nop
58+
tracksRegLiveness: true
59+
body: |
60+
; CHECK-LABEL: name: vgpr_instr_in_second_position_dont_insert_nop
61+
; CHECK: bb.0:
62+
; CHECK-NEXT: successors: %bb.1(0x80000000)
63+
; CHECK-NEXT: {{ $}}
64+
; CHECK-NEXT: S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
65+
; CHECK-NEXT: {{ $}}
66+
; CHECK-NEXT: bb.1:
67+
; CHECK-NEXT: $sgpr0 = S_MOV_B32 0
68+
; CHECK-NEXT: S_SET_VGPR_MSB 65, implicit-def $mode
69+
; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
70+
; CHECK-NEXT: S_ENDPGM 0
71+
bb.0:
72+
S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
73+
74+
bb.1:
75+
$sgpr0 = S_MOV_B32 0
76+
$vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
77+
S_ENDPGM 0
78+
...
79+
80+
---
81+
name: empty_pred_block_insert_nop
82+
tracksRegLiveness: true
83+
body: |
84+
; CHECK-LABEL: name: empty_pred_block_insert_nop
85+
; CHECK: bb.0:
86+
; CHECK-NEXT: successors: %bb.1(0x80000000)
87+
; CHECK-NEXT: {{ $}}
88+
; CHECK-NEXT: S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
89+
; CHECK-NEXT: {{ $}}
90+
; CHECK-NEXT: bb.1:
91+
; CHECK-NEXT: successors: %bb.2(0x80000000)
92+
; CHECK-NEXT: {{ $}}
93+
; CHECK-NEXT: DBG_VALUE $noreg
94+
; CHECK-NEXT: {{ $}}
95+
; CHECK-NEXT: bb.2:
96+
; CHECK-NEXT: S_NOP 0
97+
; CHECK-NEXT: S_SET_VGPR_MSB 65, implicit-def $mode
98+
; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
99+
; CHECK-NEXT: S_ENDPGM 0
100+
bb.0:
101+
S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
102+
103+
bb.1:
104+
DBG_VALUE $noreg
105+
106+
bb.2:
107+
$vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
108+
S_ENDPGM 0
109+
...
110+
111+
---
112+
name: setreg_on_any_pred_insert_nop
113+
tracksRegLiveness: true
114+
body: |
115+
; CHECK-LABEL: name: setreg_on_any_pred_insert_nop
116+
; CHECK: bb.0:
117+
; CHECK-NEXT: successors: %bb.2(0x80000000)
118+
; CHECK-NEXT: {{ $}}
119+
; CHECK-NEXT: S_BRANCH %bb.2
120+
; CHECK-NEXT: {{ $}}
121+
; CHECK-NEXT: bb.1:
122+
; CHECK-NEXT: successors: %bb.2(0x80000000)
123+
; CHECK-NEXT: {{ $}}
124+
; CHECK-NEXT: S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
125+
; CHECK-NEXT: {{ $}}
126+
; CHECK-NEXT: bb.2:
127+
; CHECK-NEXT: S_NOP 0
128+
; CHECK-NEXT: S_SET_VGPR_MSB 65, implicit-def $mode
129+
; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
130+
; CHECK-NEXT: S_ENDPGM 0
131+
bb.0:
132+
S_BRANCH %bb.2
133+
134+
bb.1:
135+
S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
136+
137+
bb.2:
138+
$vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
139+
S_ENDPGM 0
140+
...
141+
142+
---
143+
name: implicit_fallthrough_coissue_opt_insert_nop
144+
tracksRegLiveness: true
145+
body: |
146+
; CHECK-LABEL: name: implicit_fallthrough_coissue_opt_insert_nop
147+
; CHECK: bb.0:
148+
; CHECK-NEXT: successors: %bb.1(0x80000000)
149+
; CHECK-NEXT: {{ $}}
150+
; CHECK-NEXT: S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
151+
; CHECK-NEXT: {{ $}}
152+
; CHECK-NEXT: bb.1:
153+
; CHECK-NEXT: S_NOP 0
154+
; CHECK-NEXT: S_SET_VGPR_MSB 65, implicit-def $mode
155+
; CHECK-NEXT: S_BARRIER_WAIT -1
156+
; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
157+
; CHECK-NEXT: S_ENDPGM 0
158+
bb.0:
159+
S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
160+
161+
bb.1:
162+
S_BARRIER_WAIT -1
163+
$vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
164+
S_ENDPGM 0
165+
...

0 commit comments

Comments
 (0)