Skip to content

Commit 81827f8

Browse files
committed
[AMDGPU] Support wwm-reg AV spill pseudos
The wwm register spill pseudos are currently defined for VGPR_32 regclass. It causes a verifier error for gfx908 or above as the regalloc sometimes restores the values to the vector superclass AV_32. Fixing it by supporting AV wwm-spill pseudos as well. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D155646
1 parent 6244e38 commit 81827f8

File tree

5 files changed

+38
-20
lines changed

5 files changed

+38
-20
lines changed

llvm/lib/Target/AMDGPU/SIInstrInfo.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,11 +1589,15 @@ static unsigned getAVSpillSaveOpcode(unsigned Size) {
15891589
}
15901590
}
15911591

1592-
static unsigned getWWMRegSpillSaveOpcode(unsigned Size) {
1592+
static unsigned getWWMRegSpillSaveOpcode(unsigned Size,
1593+
bool IsVectorSuperClass) {
15931594
// Currently, there is only 32-bit WWM register spills needed.
15941595
if (Size != 4)
15951596
llvm_unreachable("unknown wwm register spill size");
15961597

1598+
if (IsVectorSuperClass)
1599+
return AMDGPU::SI_SPILL_WWM_AV32_SAVE;
1600+
15971601
return AMDGPU::SI_SPILL_WWM_V32_SAVE;
15981602
}
15991603

@@ -1602,11 +1606,13 @@ static unsigned getVectorRegSpillSaveOpcode(Register Reg,
16021606
unsigned Size,
16031607
const SIRegisterInfo &TRI,
16041608
const SIMachineFunctionInfo &MFI) {
1609+
bool IsVectorSuperClass = TRI.isVectorSuperClass(RC);
1610+
16051611
// Choose the right opcode if spilling a WWM register.
16061612
if (MFI.checkFlag(Reg, AMDGPU::VirtRegFlag::WWM_REG))
1607-
return getWWMRegSpillSaveOpcode(Size);
1613+
return getWWMRegSpillSaveOpcode(Size, IsVectorSuperClass);
16081614

1609-
if (TRI.isVectorSuperClass(RC))
1615+
if (IsVectorSuperClass)
16101616
return getAVSpillSaveOpcode(Size);
16111617

16121618
return TRI.isAGPRClass(RC) ? getAGPRSpillSaveOpcode(Size)
@@ -1809,23 +1815,29 @@ static unsigned getAVSpillRestoreOpcode(unsigned Size) {
18091815
}
18101816
}
18111817

1812-
static unsigned getWWMRegSpillRestoreOpcode(unsigned Size) {
1818+
static unsigned getWWMRegSpillRestoreOpcode(unsigned Size,
1819+
bool IsVectorSuperClass) {
18131820
// Currently, there is only 32-bit WWM register spills needed.
18141821
if (Size != 4)
18151822
llvm_unreachable("unknown wwm register spill size");
18161823

1824+
if (IsVectorSuperClass)
1825+
return AMDGPU::SI_SPILL_WWM_AV32_RESTORE;
1826+
18171827
return AMDGPU::SI_SPILL_WWM_V32_RESTORE;
18181828
}
18191829

18201830
static unsigned
18211831
getVectorRegSpillRestoreOpcode(Register Reg, const TargetRegisterClass *RC,
18221832
unsigned Size, const SIRegisterInfo &TRI,
18231833
const SIMachineFunctionInfo &MFI) {
1834+
bool IsVectorSuperClass = TRI.isVectorSuperClass(RC);
1835+
18241836
// Choose the right opcode if restoring a WWM register.
18251837
if (MFI.checkFlag(Reg, AMDGPU::VirtRegFlag::WWM_REG))
1826-
return getWWMRegSpillRestoreOpcode(Size);
1838+
return getWWMRegSpillRestoreOpcode(Size, IsVectorSuperClass);
18271839

1828-
if (TRI.isVectorSuperClass(RC))
1840+
if (IsVectorSuperClass)
18291841
return getAVSpillRestoreOpcode(Size);
18301842

18311843
return TRI.isAGPRClass(RC) ? getAGPRSpillRestoreOpcode(Size)

llvm/lib/Target/AMDGPU/SIInstrInfo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,9 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo {
670670

671671
static bool isWWMRegSpillOpcode(uint16_t Opcode) {
672672
return Opcode == AMDGPU::SI_SPILL_WWM_V32_SAVE ||
673-
Opcode == AMDGPU::SI_SPILL_WWM_V32_RESTORE;
673+
Opcode == AMDGPU::SI_SPILL_WWM_AV32_SAVE ||
674+
Opcode == AMDGPU::SI_SPILL_WWM_V32_RESTORE ||
675+
Opcode == AMDGPU::SI_SPILL_WWM_AV32_RESTORE;
674676
}
675677

676678
static bool isDPP(const MachineInstr &MI) {

llvm/lib/Target/AMDGPU/SIInstructions.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -952,8 +952,10 @@ defm SI_SPILL_AV384 : SI_SPILL_VGPR <AV_384, 1>;
952952
defm SI_SPILL_AV512 : SI_SPILL_VGPR <AV_512, 1>;
953953
defm SI_SPILL_AV1024 : SI_SPILL_VGPR <AV_1024, 1>;
954954

955-
let isConvergent = 1 in
956-
defm SI_SPILL_WWM_V32 : SI_SPILL_VGPR <VGPR_32>;
955+
let isConvergent = 1 in {
956+
defm SI_SPILL_WWM_V32 : SI_SPILL_VGPR <VGPR_32>;
957+
defm SI_SPILL_WWM_AV32 : SI_SPILL_VGPR <AV_32, 1>;
958+
}
957959

958960
def SI_PC_ADD_REL_OFFSET : SPseudoInstSI <
959961
(outs SReg_64:$dst),

llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,8 @@ static unsigned getNumSubRegsForSpillOp(unsigned Op) {
10651065
case AMDGPU::SI_SPILL_AV32_RESTORE:
10661066
case AMDGPU::SI_SPILL_WWM_V32_SAVE:
10671067
case AMDGPU::SI_SPILL_WWM_V32_RESTORE:
1068+
case AMDGPU::SI_SPILL_WWM_AV32_SAVE:
1069+
case AMDGPU::SI_SPILL_WWM_AV32_RESTORE:
10681070
return 1;
10691071
default: llvm_unreachable("Invalid spill opcode");
10701072
}
@@ -2144,7 +2146,8 @@ bool SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
21442146
case AMDGPU::SI_SPILL_AV96_SAVE:
21452147
case AMDGPU::SI_SPILL_AV64_SAVE:
21462148
case AMDGPU::SI_SPILL_AV32_SAVE:
2147-
case AMDGPU::SI_SPILL_WWM_V32_SAVE: {
2149+
case AMDGPU::SI_SPILL_WWM_V32_SAVE:
2150+
case AMDGPU::SI_SPILL_WWM_AV32_SAVE: {
21482151
const MachineOperand *VData = TII->getNamedOperand(*MI,
21492152
AMDGPU::OpName::vdata);
21502153
assert(TII->getNamedOperand(*MI, AMDGPU::OpName::soffset)->getReg() ==
@@ -2211,7 +2214,8 @@ bool SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
22112214
case AMDGPU::SI_SPILL_AV384_RESTORE:
22122215
case AMDGPU::SI_SPILL_AV512_RESTORE:
22132216
case AMDGPU::SI_SPILL_AV1024_RESTORE:
2214-
case AMDGPU::SI_SPILL_WWM_V32_RESTORE: {
2217+
case AMDGPU::SI_SPILL_WWM_V32_RESTORE:
2218+
case AMDGPU::SI_SPILL_WWM_AV32_RESTORE: {
22152219
const MachineOperand *VData = TII->getNamedOperand(*MI,
22162220
AMDGPU::OpName::vdata);
22172221
assert(TII->getNamedOperand(*MI, AMDGPU::OpName::soffset)->getReg() ==

llvm/test/CodeGen/AMDGPU/wwm-spill-superclass-pseudo.mir

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
1-
# RUN: not --crash llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -start-before=si-lower-sgpr-spills -stop-after=greedy,1 -verify-machineinstrs --stress-regalloc=2 %s -o /dev/null 2>&1 | FileCheck %s
2-
3-
# This test would fail as there is no wwm-register spill pseudo instructions supported for the vector superclass (AV).
4-
# Currently there is only VGPR_32 regclass spilling allowed for wwm-registers.
5-
6-
# CHECK: Bad machine code: Illegal virtual register for instruction
7-
# CHECK: instruction: {{.*}} [[AV_REG:%[0-9]+]]:av_32 = SI_SPILL_WWM_V32_RESTORE
8-
# CHECK-NEXT: - operand 0: [[AV_REG]]:av_32
9-
# CHECK-NEXT: Expected a VGPR_32 register, but got a AV_32 register
1+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -start-before=si-lower-sgpr-spills -stop-after=greedy,1 -verify-machineinstrs --stress-regalloc=2 -o - %s | FileCheck -check-prefix GCN-REGALLOC %s
2+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -start-before=si-lower-sgpr-spills -stop-after=virtregrewriter,1 -verify-machineinstrs --stress-regalloc=2 -o - %s | FileCheck -check-prefix GCN-REWRITER %s
103

114
name: test_wwm_reg_superclass_spill
125
tracksRegLiveness: true
@@ -19,6 +12,11 @@ machineFunctionInfo:
1912
sgprForEXECCopy: '$sgpr100_sgpr101'
2013
body: |
2114
bb.0:
15+
; GCN-REGALLOC-NUM-2: %{{[0-9]+}}:av_32 = SI_SPILL_WWM_AV32_RESTORE
16+
; GCN-REGALLOC: S_ENDPGM 0
17+
;
18+
; GCN-REWRITER-NUM-2: renamable $vgpr0 = SI_SPILL_WWM_AV32_RESTORE
19+
; GCN-REWRITER: S_ENDPGM 0
2220
$vgpr0 = IMPLICIT_DEF
2321
$sgpr0_sgpr1 = IMPLICIT_DEF
2422
%temp0:vgpr_32(s32) = COPY $vgpr0

0 commit comments

Comments
 (0)