[AMDGPU] Remove Dwarf encodings for subregisters (#117891)

Previously, registers and subregisters mapped to the same Dwarf
encoding. We don't really have any way to refer to subregisters directly
from Dwarf, the expression emitter should instead use DW_OPs to stencil
out the subregister from the whole register. This was also confusing
tools that need to map back to the llvm reg (e.g. dwarfdump), since
getLLVMRegNum() would arbitrarily return the _LO16 register.
This commit is contained in:
Emma Pilkington 2025-01-06 14:51:16 -05:00 committed by GitHub
parent f4bab06c97
commit dc0e258fe4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 61 additions and 29 deletions

View File

@ -153,14 +153,16 @@ class SIRegisterClass <string n, list<ValueType> rTypes, int Align, dag rList>
}
multiclass SIRegLoHi16 <string n, bits<8> regIdx, bit ArtificialHigh = 1,
bit isVGPR = 0, bit isAGPR = 0> {
bit isVGPR = 0, bit isAGPR = 0,
list<int> DwarfEncodings = [-1, -1]> {
def _LO16 : SIReg<n#".l", regIdx, isVGPR, isAGPR>;
def _HI16 : SIReg<!if(ArtificialHigh, "", n#".h"), regIdx, isVGPR, isAGPR,
/* isHi16 */ 1> {
let isArtificial = ArtificialHigh;
}
def "" : RegisterWithSubRegs<n, [!cast<Register>(NAME#"_LO16"),
!cast<Register>(NAME#"_HI16")]> {
!cast<Register>(NAME#"_HI16")]>,
DwarfRegNum<DwarfEncodings> {
let Namespace = "AMDGPU";
let SubRegIndices = [lo16, hi16];
let CoveredBySubRegs = !not(ArtificialHigh);
@ -197,7 +199,8 @@ def VCC : RegisterWithSubRegs<"vcc", [VCC_LO, VCC_HI]> {
let HWEncoding = VCC_LO.HWEncoding;
}
defm EXEC_LO : SIRegLoHi16<"exec_lo", 126>, DwarfRegNum<[1, 1]>;
defm EXEC_LO : SIRegLoHi16<"exec_lo", 126, /*ArtificialHigh=*/1, /*isVGPR=*/0,
/*isAGPR=*/0, /*DwarfEncodings=*/[1, 1]>;
defm EXEC_HI : SIRegLoHi16<"exec_hi", 127>;
def EXEC : RegisterWithSubRegs<"exec", [EXEC_LO, EXEC_HI]>, DwarfRegNum<[17, 1]> {
@ -337,25 +340,26 @@ def FLAT_SCR : FlatReg<FLAT_SCR_LO, FLAT_SCR_HI, 0>;
// SGPR registers
foreach Index = 0...105 in {
defm SGPR#Index :
SIRegLoHi16 <"s"#Index, Index>,
DwarfRegNum<[!if(!le(Index, 63), !add(Index, 32), !add(Index, 1024)),
!if(!le(Index, 63), !add(Index, 32), !add(Index, 1024))]>;
SIRegLoHi16 <"s"#Index, Index, /*ArtificialHigh=*/1,
/*isVGPR=*/0, /*isAGPR=*/0, /*DwarfEncodings=*/
[!if(!le(Index, 63), !add(Index, 32), !add(Index, 1024)),
!if(!le(Index, 63), !add(Index, 32), !add(Index, 1024))]>;
}
// VGPR registers
foreach Index = 0...255 in {
defm VGPR#Index :
SIRegLoHi16 <"v"#Index, Index, /* ArtificialHigh= */ 0,
/* isVGPR= */ 1, /* isAGPR= */ 0>,
DwarfRegNum<[!add(Index, 2560), !add(Index, 1536)]>;
SIRegLoHi16 <"v"#Index, Index, /*ArtificialHigh=*/ 0,
/*isVGPR=*/ 1, /*isAGPR=*/ 0, /*DwarfEncodings=*/
[!add(Index, 2560), !add(Index, 1536)]>;
}
// AccVGPR registers
foreach Index = 0...255 in {
defm AGPR#Index :
SIRegLoHi16 <"a"#Index, Index, /* ArtificialHigh= */ 1,
/* isVGPR= */ 0, /* isAGPR= */ 1>,
DwarfRegNum<[!add(Index, 3072), !add(Index, 2048)]>;
SIRegLoHi16 <"a"#Index, Index, /*ArtificialHigh=*/ 1,
/*isVGPR=*/ 0, /*isAGPR=*/ 1, /*DwarfEncodings=*/
[!add(Index, 3072), !add(Index, 2048)]>;
}
//===----------------------------------------------------------------------===//

View File

@ -67,7 +67,7 @@ body: |
; GCN-NEXT: {{ $}}
; GCN-NEXT: S_WAITCNT 0
; GCN-NEXT: $vgpr0 = GLOBAL_LOAD_DWORD $vgpr0_vgpr1, 0, 0, implicit $exec
; GCN-NEXT: CFI_INSTRUCTION offset $vgpr0_lo16, 16
; GCN-NEXT: CFI_INSTRUCTION offset $vgpr0, 16
$vgpr0 = GLOBAL_LOAD_DWORD $vgpr0_vgpr1, 0, 0, implicit $exec
CFI_INSTRUCTION offset $vgpr0, 16

View File

@ -51,10 +51,11 @@ TEST(AMDGPUDwarfRegMappingTests, TestWave64DwarfRegMapping) {
// PC_64 => 16, EXEC_MASK_64 => 17, S0 => 32, S63 => 95,
// S64 => 1088, S105 => 1129, V0 => 2560, V255 => 2815,
// A0 => 3072, A255 => 3327
for (int llvmReg : {16, 17, 32, 95, 1088, 1129, 2560, 2815, 3072, 3327}) {
MCRegister PCReg(*MRI->getLLVMRegNum(llvmReg, false));
EXPECT_EQ(llvmReg, MRI->getDwarfRegNum(PCReg, false));
EXPECT_EQ(llvmReg, MRI->getDwarfRegNum(PCReg, true));
for (int DwarfEncoding :
{16, 17, 32, 95, 1088, 1129, 2560, 2815, 3072, 3327}) {
MCRegister Reg = *MRI->getLLVMRegNum(DwarfEncoding, false);
EXPECT_EQ(DwarfEncoding, MRI->getDwarfRegNum(Reg, false));
EXPECT_EQ(DwarfEncoding, MRI->getDwarfRegNum(Reg, true));
}
}
}
@ -70,10 +71,11 @@ TEST(AMDGPUDwarfRegMappingTests, TestWave32DwarfRegMapping) {
// PC_64 => 16, EXEC_MASK_32 => 1, S0 => 32, S63 => 95,
// S64 => 1088, S105 => 1129, V0 => 1536, V255 => 1791,
// A0 => 2048, A255 => 2303
for (int llvmReg : {16, 1, 32, 95, 1088, 1129, 1536, 1791, 2048, 2303}) {
MCRegister PCReg(*MRI->getLLVMRegNum(llvmReg, false));
EXPECT_EQ(llvmReg, MRI->getDwarfRegNum(PCReg, false));
EXPECT_EQ(llvmReg, MRI->getDwarfRegNum(PCReg, true));
for (int DwarfEncoding :
{16, 1, 32, 95, 1088, 1129, 1536, 1791, 2048, 2303}) {
MCRegister Reg = *MRI->getLLVMRegNum(DwarfEncoding, false);
EXPECT_EQ(DwarfEncoding, MRI->getDwarfRegNum(Reg, false));
EXPECT_EQ(DwarfEncoding, MRI->getDwarfRegNum(Reg, true));
}
}
}

View File

@ -25,11 +25,24 @@ TEST(AMDGPU, TestWave64DwarfRegMapping) {
// PC_64 => 16, EXEC_MASK_64 => 17, S0 => 32, S63 => 95,
// S64 => 1088, S105 => 1129, V0 => 2560, V255 => 2815,
// A0 => 3072, A255 => 3327
for (int llvmReg :
for (int DwarfEncoding :
{16, 17, 32, 95, 1088, 1129, 2560, 2815, 3072, 3327}) {
MCRegister PCReg(*MRI->getLLVMRegNum(llvmReg, false));
EXPECT_EQ(llvmReg, MRI->getDwarfRegNum(PCReg, false));
EXPECT_EQ(llvmReg, MRI->getDwarfRegNum(PCReg, true));
MCRegister Reg = *MRI->getLLVMRegNum(DwarfEncoding, false);
EXPECT_EQ(DwarfEncoding, MRI->getDwarfRegNum(Reg, false));
EXPECT_EQ(DwarfEncoding, MRI->getDwarfRegNum(Reg, true));
}
// We should get the correct LLVM register when round tripping through
// the dwarf encoding.
for (MCRegister LLReg : {AMDGPU::VGPR1, AMDGPU::AGPR2, AMDGPU::SGPR3}) {
int DwarfEncoding = MRI->getDwarfRegNum(LLReg, false);
EXPECT_EQ(LLReg, MRI->getLLVMRegNum(DwarfEncoding, false));
}
// Verify that subregisters have no dwarf encoding.
for (MCRegister LLSubReg :
{AMDGPU::VGPR1_LO16, AMDGPU::AGPR1_HI16, AMDGPU::SGPR1_HI16}) {
EXPECT_EQ(MRI->getDwarfRegNum(LLSubReg, false), -1);
}
}
}
@ -49,11 +62,24 @@ TEST(AMDGPU, TestWave32DwarfRegMapping) {
// PC_64 => 16, EXEC_MASK_32 => 1, S0 => 32, S63 => 95,
// S64 => 1088, S105 => 1129, V0 => 1536, V255 => 1791,
// A0 => 2048, A255 => 2303
for (int llvmReg :
for (int DwarfEncoding :
{16, 1, 32, 95, 1088, 1129, 1536, 1791, 2048, 2303}) {
MCRegister PCReg(*MRI->getLLVMRegNum(llvmReg, false));
EXPECT_EQ(llvmReg, MRI->getDwarfRegNum(PCReg, false));
EXPECT_EQ(llvmReg, MRI->getDwarfRegNum(PCReg, true));
MCRegister Reg = *MRI->getLLVMRegNum(DwarfEncoding, false);
EXPECT_EQ(DwarfEncoding, MRI->getDwarfRegNum(Reg, false));
EXPECT_EQ(DwarfEncoding, MRI->getDwarfRegNum(Reg, true));
}
// We should get the correct LLVM register when round tripping through
// the dwarf encoding.
for (MCRegister LLReg : {AMDGPU::VGPR1, AMDGPU::AGPR2, AMDGPU::SGPR3}) {
int DwarfEncoding = MRI->getDwarfRegNum(LLReg, false);
EXPECT_EQ(LLReg, MRI->getLLVMRegNum(DwarfEncoding, false));
}
// Verify that subregisters have no dwarf encoding.
for (MCRegister LLSubReg :
{AMDGPU::VGPR1_LO16, AMDGPU::AGPR1_HI16, AMDGPU::SGPR1_HI16}) {
EXPECT_EQ(MRI->getDwarfRegNum(LLSubReg, false), -1);
}
}
}