Skip to content

Commit

Permalink
AMDGPU: Check if operand RC contains register used when printing
Browse files Browse the repository at this point in the history
Disassembler can successfully decode sgpr register when only vgpr
registers are valid for the operand (e.g. VReg_* and VISrc_* operands).
In InstPrinter, detect when operand register class does not contain
register that is being printed. Does not result in an error.
Intended use is for disassembler tests.

Differential Revision: https://reviews.llvm.org/D139646
  • Loading branch information
petar-avramovic committed Dec 9, 2022
1 parent a1ceacd commit cc6b10d
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 27 deletions.
23 changes: 0 additions & 23 deletions llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
Expand Up @@ -2305,29 +2305,6 @@ void AMDGPUOperand::addRegOperands(MCInst &Inst, unsigned N) const {
Inst.addOperand(MCOperand::createReg(AMDGPU::getMCReg(getReg(), AsmParser->getSTI())));
}

static bool isInlineValue(unsigned Reg) {
switch (Reg) {
case AMDGPU::SRC_SHARED_BASE_LO:
case AMDGPU::SRC_SHARED_BASE:
case AMDGPU::SRC_SHARED_LIMIT_LO:
case AMDGPU::SRC_SHARED_LIMIT:
case AMDGPU::SRC_PRIVATE_BASE_LO:
case AMDGPU::SRC_PRIVATE_BASE:
case AMDGPU::SRC_PRIVATE_LIMIT_LO:
case AMDGPU::SRC_PRIVATE_LIMIT:
case AMDGPU::SRC_POPS_EXITING_WAVE_ID:
return true;
case AMDGPU::SRC_VCCZ:
case AMDGPU::SRC_EXECZ:
case AMDGPU::SRC_SCC:
return true;
case AMDGPU::SGPR_NULL:
return true;
default:
return false;
}
}

bool AMDGPUOperand::isInlineValue() const {
return isRegKind() && ::isInlineValue(getReg());
}
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
Expand Up @@ -667,6 +667,19 @@ void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
printRegOperand(Op.getReg(), O, MRI);

// Check if operand register class contains register used.
// Intention: print disassembler message when invalid code is decoded,
// for example sgpr register used in VReg or VISrc(VReg or imm) operand.
int RCID = Desc.OpInfo[OpNo].RegClass;
if (RCID != -1) {
const MCRegisterClass RC = MRI.getRegClass(RCID);
auto Reg = mc2PseudoReg(Op.getReg());
if (!RC.contains(Reg) && !isInlineValue(Reg)) {
O << "/*Invalid register, operand has \'" << MRI.getRegClassName(&RC)
<< "\' register class*/";
}
}
} else if (Op.isImm()) {
const uint8_t OpTy = Desc.OpInfo[OpNo].OperandType;
switch (OpTy) {
Expand Down
23 changes: 23 additions & 0 deletions llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
Expand Up @@ -2093,6 +2093,29 @@ unsigned mc2PseudoReg(unsigned Reg) {
MAP_REG2REG
}

bool isInlineValue(unsigned Reg) {
switch (Reg) {
case AMDGPU::SRC_SHARED_BASE_LO:
case AMDGPU::SRC_SHARED_BASE:
case AMDGPU::SRC_SHARED_LIMIT_LO:
case AMDGPU::SRC_SHARED_LIMIT:
case AMDGPU::SRC_PRIVATE_BASE_LO:
case AMDGPU::SRC_PRIVATE_BASE:
case AMDGPU::SRC_PRIVATE_LIMIT_LO:
case AMDGPU::SRC_PRIVATE_LIMIT:
case AMDGPU::SRC_POPS_EXITING_WAVE_ID:
return true;
case AMDGPU::SRC_VCCZ:
case AMDGPU::SRC_EXECZ:
case AMDGPU::SRC_SCC:
return true;
case AMDGPU::SGPR_NULL:
return true;
default:
return false;
}
}

#undef CASE_CI_VI
#undef CASE_VI_GFX9PLUS
#undef CASE_GFXPRE11_GFX11PLUS
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
Expand Up @@ -1131,6 +1131,9 @@ unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI);
LLVM_READNONE
unsigned mc2PseudoReg(unsigned Reg);

LLVM_READNONE
bool isInlineValue(unsigned Reg);

/// Is this an AMDGPU specific source operand? These include registers,
/// inline constants, literals and mandatory literals (KImm).
bool isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo);
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/MC/Disassembler/AMDGPU/decode-err.txt
Expand Up @@ -21,14 +21,14 @@
# W64: v_wmma_f32_16x16x16_f16 v[16:19], /*invalid immediate*/, v[8:15], v[16:19] ; encoding: [0x10,0x40,0x40,0xcc,0x00,0x10,0x42,0x1c]
0x10,0x40,0x40,0xcc,0xf2,0x10,0x42,0x1c # src0 1.0

# W32: v_wmma_f32_16x16x16_f16 v[16:23], s[0:7], v[8:15], v[16:23] ; encoding: [0x10,0x40,0x40,0xcc,0x00,0x10,0x42,0x1c]
# W64: v_wmma_f32_16x16x16_f16 v[16:19], s[0:7], v[8:15], v[16:19] ; encoding: [0x10,0x40,0x40,0xcc,0x00,0x10,0x42,0x1c]
# W32: v_wmma_f32_16x16x16_f16 v[16:23], s[0:7]/*Invalid register, operand has 'VReg_256' register class*/, v[8:15], v[16:23] ; encoding: [0x10,0x40,0x40,0xcc,0x00,0x10,0x42,0x1c]
# W64: v_wmma_f32_16x16x16_f16 v[16:19], s[0:7]/*Invalid register, operand has 'VReg_256' register class*/, v[8:15], v[16:19] ; encoding: [0x10,0x40,0x40,0xcc,0x00,0x10,0x42,0x1c]
0x10,0x40,0x40,0xcc,0x00,0x10,0x42,0x1c # src0 sgpr0

# W32: v_wmma_f32_16x16x16_f16 v[16:23], v[0:7], v[8:15], 1.0 ; encoding: [0x10,0x40,0x40,0xcc,0x00,0x11,0xca,0x1b]
# W64: v_wmma_f32_16x16x16_f16 v[16:19], v[0:7], v[8:15], 1.0 ; encoding: [0x10,0x40,0x40,0xcc,0x00,0x11,0xca,0x1b]
0x10,0x40,0x40,0xcc,0x00,0x11,0xca,0x1b # src2 1.0

# W32: v_wmma_f32_16x16x16_f16 v[16:23], v[0:7], v[8:15], s[0:7] ; encoding: [0x10,0x40,0x40,0xcc,0x00,0x11,0x02,0x18]
# W64: v_wmma_f32_16x16x16_f16 v[16:19], v[0:7], v[8:15], s[0:3] ; encoding: [0x10,0x40,0x40,0xcc,0x00,0x11,0x02,0x18]
# W32: v_wmma_f32_16x16x16_f16 v[16:23], v[0:7], v[8:15], s[0:7]/*Invalid register, operand has 'VReg_256' register class*/ ; encoding: [0x10,0x40,0x40,0xcc,0x00,0x11,0x02,0x18]
# W64: v_wmma_f32_16x16x16_f16 v[16:19], v[0:7], v[8:15], s[0:3]/*Invalid register, operand has 'VReg_128' register class*/ ; encoding: [0x10,0x40,0x40,0xcc,0x00,0x11,0x02,0x18]
0x10,0x40,0x40,0xcc,0x00,0x11,0x02,0x18 # src2 sgpr0

0 comments on commit cc6b10d

Please sign in to comment.