Skip to content

Commit 2e94a64

Browse files
committed
[AMDGPU] Define 16 bit SGPR subregs
These are needed as a counterpart for VGPR subregs even though there are no scalar instructions which can operate 16 bit values. When we are materializing a constant that is done into an SGPR and that SGPR may/will be copied into a 16 bit VGPR subreg. Such copy is illegal. There are also similar problems if a source operand of a 16 bit VALU instruction is an SGPR. In addition we need to get a register with a lo16 subregister of an SGPR RC during selection and this fails as well. All of that makes me believe we need these subregisters as a syntactic glue. Differential Revision: https://reviews.llvm.org/D78250
1 parent 3a6b60f commit 2e94a64

10 files changed

+61
-21
lines changed

llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,12 +764,16 @@ AMDGPUAsmPrinter::SIFunctionResourceInfo AMDGPUAsmPrinter::analyzeResourceUsage(
764764
break;
765765
}
766766

767-
if (AMDGPU::SReg_32RegClass.contains(Reg)) {
767+
if (AMDGPU::SReg_32RegClass.contains(Reg) ||
768+
AMDGPU::SGPR_LO16RegClass.contains(Reg) ||
769+
AMDGPU::SGPR_HI16RegClass.contains(Reg)) {
768770
assert(!AMDGPU::TTMP_32RegClass.contains(Reg) &&
769771
"trap handler registers should not be used");
770772
IsSGPR = true;
771773
Width = 1;
772-
} else if (AMDGPU::VGPR_32RegClass.contains(Reg)) {
774+
} else if (AMDGPU::VGPR_32RegClass.contains(Reg) ||
775+
AMDGPU::VGPR_LO16RegClass.contains(Reg) ||
776+
AMDGPU::VGPR_HI16RegClass.contains(Reg)) {
773777
IsSGPR = false;
774778
Width = 1;
775779
} else if (AMDGPU::AGPR_32RegClass.contains(Reg)) {

llvm/lib/Target/AMDGPU/AMDGPURegisterBanks.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
def SGPRRegBank : RegisterBank<"SGPR",
10-
[SReg_32, SReg_64, SReg_128, SReg_256, SReg_512, SReg_1024]
10+
[SGPR_LO16, SReg_32, SReg_64, SReg_128, SReg_256, SReg_512, SReg_1024]
1111
>;
1212

1313
def VGPRRegBank : RegisterBank<"VGPR",

llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ static void insertCSRSaves(MachineBasicBlock &SaveBlock,
100100
unsigned Reg = CS.getReg();
101101

102102
MachineInstrSpan MIS(I, &SaveBlock);
103-
const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
103+
const TargetRegisterClass *RC =
104+
TRI->getMinimalPhysRegClass(Reg, MVT::i32);
104105

105106
TII.storeRegToStackSlot(SaveBlock, I, Reg, true, CS.getFrameIdx(), RC,
106107
TRI);
@@ -133,7 +134,8 @@ static void insertCSRRestores(MachineBasicBlock &RestoreBlock,
133134
if (!TFI->restoreCalleeSavedRegisters(RestoreBlock, I, CSI, TRI)) {
134135
for (const CalleeSavedInfo &CI : reverse(CSI)) {
135136
unsigned Reg = CI.getReg();
136-
const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
137+
const TargetRegisterClass *RC =
138+
TRI->getMinimalPhysRegClass(Reg, MVT::i32);
137139

138140
TII.loadRegFromStackSlot(RestoreBlock, I, Reg, CI.getFrameIdx(), RC, TRI);
139141
assert(I != RestoreBlock.begin() &&
@@ -206,7 +208,8 @@ bool SILowerSGPRSpills::spillCalleeSavedRegs(MachineFunction &MF) {
206208
for (unsigned I = 0; CSRegs[I]; ++I) {
207209
unsigned Reg = CSRegs[I];
208210
if (SavedRegs.test(Reg)) {
209-
const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
211+
const TargetRegisterClass *RC =
212+
TRI->getMinimalPhysRegClass(Reg, MVT::i32);
210213
int JunkFI = MFI.CreateStackObject(TRI->getSpillSize(*RC),
211214
TRI->getSpillAlignment(*RC),
212215
true);

llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,7 @@ SIRegisterInfo::getPhysRegClass(MCRegister Reg) const {
12811281
static const TargetRegisterClass *const BaseClasses[] = {
12821282
&AMDGPU::VGPR_LO16RegClass,
12831283
&AMDGPU::VGPR_HI16RegClass,
1284+
&AMDGPU::SGPR_LO16RegClass,
12841285
&AMDGPU::VGPR_32RegClass,
12851286
&AMDGPU::SReg_32RegClass,
12861287
&AMDGPU::AGPR_32RegClass,
@@ -1375,6 +1376,8 @@ bool SIRegisterInfo::hasAGPRs(const TargetRegisterClass *RC) const {
13751376
const TargetRegisterClass *SIRegisterInfo::getEquivalentVGPRClass(
13761377
const TargetRegisterClass *SRC) const {
13771378
switch (getRegSizeInBits(*SRC)) {
1379+
case 16:
1380+
return &AMDGPU::VGPR_LO16RegClass;
13781381
case 32:
13791382
return &AMDGPU::VGPR_32RegClass;
13801383
case 64:
@@ -1419,6 +1422,8 @@ const TargetRegisterClass *SIRegisterInfo::getEquivalentAGPRClass(
14191422
const TargetRegisterClass *SIRegisterInfo::getEquivalentSGPRClass(
14201423
const TargetRegisterClass *VRC) const {
14211424
switch (getRegSizeInBits(*VRC)) {
1425+
case 16:
1426+
return &AMDGPU::SGPR_LO16RegClass;
14221427
case 32:
14231428
return &AMDGPU::SGPR_32RegClass;
14241429
case 64:
@@ -1795,6 +1800,7 @@ unsigned SIRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
17951800
case AMDGPU::VGPR_HI16RegClassID:
17961801
return std::min(ST.getMaxNumVGPRs(Occupancy), ST.getMaxNumVGPRs(MF));
17971802
case AMDGPU::SGPR_32RegClassID:
1803+
case AMDGPU::SGPR_LO16RegClassID:
17981804
return std::min(ST.getMaxNumSGPRs(Occupancy, true), ST.getMaxNumSGPRs(MF));
17991805
}
18001806
}

llvm/lib/Target/AMDGPU/SIRegisterInfo.td

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,23 @@ def FLAT_SCR : FlatReg<FLAT_SCR_LO, FLAT_SCR_HI, 0>;
253253

254254
// SGPR registers
255255
foreach Index = 0-105 in {
256-
def SGPR#Index :
257-
SIReg <"s"#Index, Index>,
256+
def SGPR#Index#_LO16 : SIReg <"s"#Index#".l", Index>,
258257
DwarfRegNum<[!if(!le(Index, 63), !add(Index, 32), !add(Index, 1024)),
259258
!if(!le(Index, 63), !add(Index, 32), !add(Index, 1024))]>;
259+
260+
// This is a placeholder to fill high lane in mask.
261+
def SGPR#Index#_HI16 : SIReg <"", Index> {
262+
let isArtificial = 1;
263+
}
264+
265+
def SGPR#Index :
266+
SIRegWithSubRegs <"s"#Index, [!cast<Register>("SGPR"#Index#"_LO16"),
267+
!cast<Register>("SGPR"#Index#"_HI16")],
268+
Index>,
269+
DwarfRegNum<[!if(!le(Index, 63), !add(Index, 32), !add(Index, 1024)),
270+
!if(!le(Index, 63), !add(Index, 32), !add(Index, 1024))]> {
271+
let SubRegIndices = [lo16, hi16];
272+
}
260273
}
261274

262275
// VGPR registers
@@ -317,6 +330,20 @@ def M0_CLASS : RegisterClass<"AMDGPU", [i32], 32, (add M0)> {
317330

318331
// TODO: Do we need to set DwarfRegAlias on register tuples?
319332

333+
def SGPR_LO16 : RegisterClass<"AMDGPU", [i16, f16], 16,
334+
(add (sequence "SGPR%u_LO16", 0, 105))> {
335+
let AllocationPriority = 1;
336+
let Size = 16;
337+
let GeneratePressureSet = 0;
338+
}
339+
340+
def SGPR_HI16 : RegisterClass<"AMDGPU", [i16, f16], 16,
341+
(add (sequence "SGPR%u_HI16", 0, 105))> {
342+
let isAllocatable = 0;
343+
let Size = 16;
344+
let GeneratePressureSet = 0;
345+
}
346+
320347
// SGPR 32-bit registers
321348
def SGPR_32 : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16], 32,
322349
(add (sequence "SGPR%u", 0, 105))> {

llvm/test/CodeGen/AMDGPU/postra-bundle-memops.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ body: |
4343
; GCN: DS_WRITE_B32_gfx9 $vgpr0, $vgpr3, 4, 0, implicit killed $m0, implicit $exec
4444
; GCN: }
4545
; GCN: S_NOP 0
46-
; GCN: BUNDLE implicit-def $sgpr2, implicit-def $sgpr3, implicit undef $sgpr0_sgpr1, implicit undef $sgpr10 {
46+
; GCN: BUNDLE implicit-def $sgpr2, implicit-def $sgpr2_lo16, implicit-def $sgpr2_hi16, implicit-def $sgpr3, implicit-def $sgpr3_lo16, implicit-def $sgpr3_hi16, implicit undef $sgpr0_sgpr1, implicit undef $sgpr10 {
4747
; GCN: $sgpr2 = S_LOAD_DWORD_IMM undef $sgpr0_sgpr1, 0, 0, 0
4848
; GCN: $sgpr3 = S_LOAD_DWORD_SGPR undef $sgpr0_sgpr1, undef $sgpr10, 0, 0
4949
; GCN: }

llvm/test/CodeGen/AMDGPU/rename-independent-subregs.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ body: |
7373
# (1) %0.sub0 + %0.sub0 and (2) %0.sub1 + %0.sub1
7474
# Check that renaming (2) does not inadvertently rename (1).
7575
# CHECK-LABEL: name: test2
76-
# CHECK: INLINEASM &"", 32 /* isconvergent attdialect */, 327690 /* regdef:SReg_1_XEXEC_with_sub0 */, def undef %0.sub0, 327690 /* regdef:SReg_1_XEXEC_with_sub0 */, def dead %1.sub1, 2147483657 /* reguse tiedto:$0 */, undef %0.sub0(tied-def 3), 2147549193 /* reguse tiedto:$1 */, %1.sub1(tied-def 5)
76+
# CHECK: INLINEASM &"", 32 /* isconvergent attdialect */, 327690 /* regdef:SReg_1_with_sub0 */, def undef %0.sub0, 327690 /* regdef:SReg_1_with_sub0 */, def dead %1.sub1, 2147483657 /* reguse tiedto:$0 */, undef %0.sub0(tied-def 3), 2147549193 /* reguse tiedto:$1 */, %1.sub1(tied-def 5)
7777
name: test2
7878
body: |
7979
bb.0:

llvm/test/CodeGen/AMDGPU/sched-assert-dead-def-subreg-use-other-subreg.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ body: |
3333
; CHECK: dead %9:vreg_128 = DS_READ_B128_gfx9 [[V_ADD_U32_e32_]], 0, 0, implicit $exec
3434
; CHECK: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[COPY]].sub0
3535
; CHECK: undef %11.sub1:vreg_512 = COPY [[COPY]].sub1
36-
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:VRegOrLds_32 */, def dead [[COPY1]], 851978 /* regdef:VRegOrLds_32 */, def dead [[COPY]].sub1, 2147483657 /* reguse tiedto:$0 */, [[COPY1]], 2147549193 /* reguse tiedto:$1 */, [[COPY]].sub1
36+
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:SGPR_LO16 */, def dead [[COPY1]], 851978 /* regdef:SGPR_LO16 */, def dead [[COPY]].sub1, 2147483657 /* reguse tiedto:$0 */, [[COPY1]], 2147549193 /* reguse tiedto:$1 */, [[COPY]].sub1
3737
; CHECK: %11.sub0:vreg_512 = COPY [[COPY]].sub0
3838
; CHECK: %11.sub3:vreg_512 = COPY [[COPY]].sub3
3939
; CHECK: dead %10:vgpr_32 = V_ADD_I32_e32 4, [[V_MOV_B32_e32_1]], implicit-def dead $vcc, implicit $exec

llvm/test/CodeGen/AMDGPU/sched-handleMoveUp-subreg-def-across-subreg-def.mir

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,18 @@ body: |
3636
; CHECK: [[DEF2:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF
3737
; CHECK: bb.1:
3838
; CHECK: successors: %bb.1(0x80000000)
39-
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:VRegOrLds_32 */, def dead %11
39+
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:SGPR_LO16 */, def dead %11
4040
; CHECK: GLOBAL_STORE_DWORD undef %12:vreg_64, [[BUFFER_LOAD_DWORD_OFFEN]], 0, 0, 0, 0, implicit $exec :: (store 4, addrspace 1)
4141
; CHECK: [[V_MOV_B32_e32_2:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
4242
; CHECK: [[V_MOV_B32_e32_3:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
4343
; CHECK: [[DS_READ_B64_gfx9_:%[0-9]+]]:vreg_64 = DS_READ_B64_gfx9 undef %14:vgpr_32, 0, 0, implicit $exec :: (load 8, addrspace 3)
44-
; CHECK: INLINEASM &"def $0 $1", 1 /* sideeffect attdialect */, 851978 /* regdef:VRegOrLds_32 */, def %15, 851978 /* regdef:VRegOrLds_32 */, def %16
44+
; CHECK: INLINEASM &"def $0 $1", 1 /* sideeffect attdialect */, 851978 /* regdef:SGPR_LO16 */, def %15, 851978 /* regdef:SGPR_LO16 */, def %16
4545
; CHECK: [[DS_READ_B32_gfx9_:%[0-9]+]]:vgpr_32 = DS_READ_B32_gfx9 [[V_MOV_B32_e32_]], 0, 0, implicit $exec
4646
; CHECK: [[DS_READ_B32_gfx9_1:%[0-9]+]]:vgpr_32 = DS_READ_B32_gfx9 [[V_MOV_B32_e32_1]], 0, 0, implicit $exec
4747
; CHECK: [[DS_READ_B32_gfx9_2:%[0-9]+]]:vgpr_32 = DS_READ_B32_gfx9 undef %20:vgpr_32, 0, 0, implicit $exec
48-
; CHECK: INLINEASM &"def $0 $1", 1 /* sideeffect attdialect */, 851978 /* regdef:VRegOrLds_32 */, def %21, 851978 /* regdef:VRegOrLds_32 */, def %22
48+
; CHECK: INLINEASM &"def $0 $1", 1 /* sideeffect attdialect */, 851978 /* regdef:SGPR_LO16 */, def %21, 851978 /* regdef:SGPR_LO16 */, def %22
4949
; CHECK: [[DS_READ_B32_gfx9_3:%[0-9]+]]:vgpr_32 = DS_READ_B32_gfx9 [[V_MOV_B32_e32_1]], 0, 0, implicit $exec
50-
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:VRegOrLds_32 */, def dead [[V_MOV_B32_e32_2]], 851978 /* regdef:VRegOrLds_32 */, def dead [[V_MOV_B32_e32_3]], 851977 /* reguse:VRegOrLds_32 */, [[DS_READ_B64_gfx9_]].sub0, 2147483657 /* reguse tiedto:$0 */, [[V_MOV_B32_e32_2]](tied-def 3), 2147549193 /* reguse tiedto:$1 */, [[V_MOV_B32_e32_3]](tied-def 5), 851977 /* reguse:VRegOrLds_32 */, %15, 851977 /* reguse:VRegOrLds_32 */, %16, 851977 /* reguse:VRegOrLds_32 */, [[DS_READ_B32_gfx9_1]], 851977 /* reguse:VRegOrLds_32 */, [[DS_READ_B32_gfx9_]], 851977 /* reguse:VRegOrLds_32 */, [[DS_READ_B32_gfx9_3]], 851977 /* reguse:VRegOrLds_32 */, [[DS_READ_B32_gfx9_2]]
50+
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:SGPR_LO16 */, def dead [[V_MOV_B32_e32_2]], 851978 /* regdef:SGPR_LO16 */, def dead [[V_MOV_B32_e32_3]], 851977 /* reguse:SGPR_LO16 */, [[DS_READ_B64_gfx9_]].sub0, 2147483657 /* reguse tiedto:$0 */, [[V_MOV_B32_e32_2]](tied-def 3), 2147549193 /* reguse tiedto:$1 */, [[V_MOV_B32_e32_3]](tied-def 5), 851977 /* reguse:SGPR_LO16 */, %15, 851977 /* reguse:SGPR_LO16 */, %16, 851977 /* reguse:SGPR_LO16 */, [[DS_READ_B32_gfx9_1]], 851977 /* reguse:SGPR_LO16 */, [[DS_READ_B32_gfx9_]], 851977 /* reguse:SGPR_LO16 */, [[DS_READ_B32_gfx9_3]], 851977 /* reguse:SGPR_LO16 */, [[DS_READ_B32_gfx9_2]]
5151
; CHECK: %5.sub1:vreg_64 = COPY [[V_MOV_B32_e32_]]
5252
; CHECK: DS_WRITE_B32_gfx9 undef %28:vgpr_32, %21, 0, 0, implicit $exec :: (store 4, addrspace 3)
5353
; CHECK: DS_WRITE_B32_gfx9 undef %29:vgpr_32, %22, 0, 0, implicit $exec :: (store 4, addrspace 3)

llvm/test/CodeGen/AMDGPU/subreg-undef-def-with-other-subreg-defs.mir

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ body: |
2525
; CHECK: bb.1:
2626
; CHECK: successors: %bb.1(0x80000000)
2727
; CHECK: [[DS_READ_B32_gfx9_:%[0-9]+]]:vgpr_32 = DS_READ_B32_gfx9 [[V_MOV_B32_e32_]], 0, 0, implicit $exec :: (load 4, addrspace 3)
28-
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:VRegOrLds_32 */, def %0, 2147549193 /* reguse tiedto:$1 */, %0(tied-def 3)
29-
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851977 /* reguse:VRegOrLds_32 */, [[DS_READ_B32_gfx9_]]
30-
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:VRegOrLds_32 */, def undef %0.sub0, 851978 /* regdef:VRegOrLds_32 */, def undef %0.sub1
28+
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:SGPR_LO16 */, def %0, 2147549193 /* reguse tiedto:$1 */, %0(tied-def 3)
29+
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851977 /* reguse:SGPR_LO16 */, [[DS_READ_B32_gfx9_]]
30+
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:SGPR_LO16 */, def undef %0.sub0, 851978 /* regdef:SGPR_LO16 */, def undef %0.sub1
3131
; CHECK: S_NOP 0, implicit %0.sub1
3232
; CHECK: $sgpr10 = S_MOV_B32 -1
3333
; CHECK: S_BRANCH %bb.1
@@ -63,9 +63,9 @@ body: |
6363
; CHECK: bb.1:
6464
; CHECK: successors: %bb.1(0x80000000)
6565
; CHECK: [[DS_READ_B32_gfx9_:%[0-9]+]]:vgpr_32 = DS_READ_B32_gfx9 [[V_MOV_B32_e32_]], 0, 0, implicit $exec :: (load 4, addrspace 3)
66-
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:VRegOrLds_32 */, def %0, 2147549193 /* reguse tiedto:$1 */, %0(tied-def 3)
67-
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851977 /* reguse:VRegOrLds_32 */, [[DS_READ_B32_gfx9_]]
68-
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:VRegOrLds_32 */, def undef %0.sub1, 851978 /* regdef:VRegOrLds_32 */, def undef %0.sub0
66+
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:SGPR_LO16 */, def %0, 2147549193 /* reguse tiedto:$1 */, %0(tied-def 3)
67+
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851977 /* reguse:SGPR_LO16 */, [[DS_READ_B32_gfx9_]]
68+
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 851978 /* regdef:SGPR_LO16 */, def undef %0.sub1, 851978 /* regdef:SGPR_LO16 */, def undef %0.sub0
6969
; CHECK: S_NOP 0, implicit %0.sub1
7070
; CHECK: $sgpr10 = S_MOV_B32 -1
7171
; CHECK: S_BRANCH %bb.1

0 commit comments

Comments
 (0)