Skip to content

Commit 33503d0

Browse files
authored
[AMDGPU] Preserve literal operands on disassembling. (llvm#163376)
Fixes round-tripping where literals used to be reassembled into inline constants. Also fix the %extract-encodings substitution in lit tests to emit each instruction code once and not twice. Eliminate the Literal64 field.
1 parent e3f9b4c commit 33503d0

File tree

12 files changed

+278
-149
lines changed

12 files changed

+278
-149
lines changed

llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp

Lines changed: 80 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,7 @@ void AMDGPUDisassembler::decodeImmOperands(MCInst &MI,
513513
}
514514

515515
if (Imm == AMDGPU::EncValues::LITERAL_CONST) {
516-
Op = decodeLiteralConstant(
517-
Desc, OpDesc, OpDesc.OperandType == AMDGPU::OPERAND_REG_IMM_FP64);
516+
Op = decodeLiteralConstant(Desc, OpDesc);
518517
continue;
519518
}
520519

@@ -1545,21 +1544,21 @@ AMDGPUDisassembler::decodeMandatoryLiteralConstant(unsigned Val) const {
15451544
MCOperand
15461545
AMDGPUDisassembler::decodeMandatoryLiteral64Constant(uint64_t Val) const {
15471546
if (HasLiteral) {
1548-
if (Literal64 != Val)
1547+
if (Literal != Val)
15491548
return errOperand(Val, "More than one unique literal is illegal");
15501549
}
15511550
HasLiteral = true;
1552-
Literal = Literal64 = Val;
1551+
Literal = Val;
15531552

1554-
bool UseLit64 = Hi_32(Literal64) == 0;
1553+
bool UseLit64 = Hi_32(Literal) == 0;
15551554
return UseLit64 ? MCOperand::createExpr(AMDGPUMCExpr::createLit(
1556-
LitModifier::Lit64, Literal64, getContext()))
1557-
: MCOperand::createImm(Literal64);
1555+
LitModifier::Lit64, Literal, getContext()))
1556+
: MCOperand::createImm(Literal);
15581557
}
15591558

1560-
MCOperand AMDGPUDisassembler::decodeLiteralConstant(const MCInstrDesc &Desc,
1561-
const MCOperandInfo &OpDesc,
1562-
bool ExtendFP64) const {
1559+
MCOperand
1560+
AMDGPUDisassembler::decodeLiteralConstant(const MCInstrDesc &Desc,
1561+
const MCOperandInfo &OpDesc) const {
15631562
// For now all literal constants are supposed to be unsigned integer
15641563
// ToDo: deal with signed/unsigned 64-bit integer constants
15651564
// ToDo: deal with float/double constants
@@ -1569,35 +1568,79 @@ MCOperand AMDGPUDisassembler::decodeLiteralConstant(const MCInstrDesc &Desc,
15691568
Twine(Bytes.size()));
15701569
}
15711570
HasLiteral = true;
1572-
Literal = Literal64 = eatBytes<uint32_t>(Bytes);
1573-
if (ExtendFP64)
1574-
Literal64 <<= 32;
1571+
Literal = eatBytes<uint32_t>(Bytes);
15751572
}
15761573

1577-
int64_t Val = ExtendFP64 ? Literal64 : Literal;
1574+
// For disassembling always assume all inline constants are available.
1575+
bool HasInv2Pi = true;
15781576

1579-
bool CanUse64BitLiterals =
1580-
STI.hasFeature(AMDGPU::Feature64BitLiterals) &&
1581-
!(Desc.TSFlags & (SIInstrFlags::VOP3 | SIInstrFlags::VOP3P));
1582-
1583-
bool UseLit64 = false;
1584-
if (CanUse64BitLiterals) {
1585-
if (OpDesc.OperandType == AMDGPU::OPERAND_REG_IMM_INT64 ||
1586-
OpDesc.OperandType == AMDGPU::OPERAND_REG_INLINE_C_INT64)
1587-
UseLit64 = false;
1588-
else if (OpDesc.OperandType == AMDGPU::OPERAND_REG_IMM_FP64 ||
1589-
OpDesc.OperandType == AMDGPU::OPERAND_REG_INLINE_C_FP64 ||
1590-
OpDesc.OperandType == AMDGPU::OPERAND_REG_INLINE_AC_FP64)
1591-
UseLit64 = Hi_32(Literal64) == 0;
1577+
// Invalid instruction codes may contain literals for inline-only
1578+
// operands, so we support them here as well.
1579+
int64_t Val = Literal;
1580+
bool UseLit = false;
1581+
switch (OpDesc.OperandType) {
1582+
default:
1583+
llvm_unreachable("Unexpected operand type!");
1584+
case AMDGPU::OPERAND_REG_IMM_BF16:
1585+
case AMDGPU::OPERAND_REG_INLINE_C_BF16:
1586+
case AMDGPU::OPERAND_REG_INLINE_C_V2BF16:
1587+
UseLit = AMDGPU::isInlinableLiteralBF16(Val, HasInv2Pi);
1588+
break;
1589+
case AMDGPU::OPERAND_REG_IMM_V2BF16:
1590+
UseLit = AMDGPU::isInlinableLiteralV2BF16(Val);
1591+
break;
1592+
case AMDGPU::OPERAND_REG_IMM_FP16:
1593+
case AMDGPU::OPERAND_REG_INLINE_C_FP16:
1594+
case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
1595+
UseLit = AMDGPU::isInlinableLiteralFP16(Val, HasInv2Pi);
1596+
break;
1597+
case AMDGPU::OPERAND_REG_IMM_V2FP16:
1598+
UseLit = AMDGPU::isInlinableLiteralV2F16(Val);
1599+
break;
1600+
case AMDGPU::OPERAND_REG_IMM_NOINLINE_V2FP16:
1601+
break;
1602+
case AMDGPU::OPERAND_REG_IMM_INT16:
1603+
case AMDGPU::OPERAND_REG_INLINE_C_INT16:
1604+
case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
1605+
UseLit = AMDGPU::isInlinableLiteralI16(Val, HasInv2Pi);
1606+
break;
1607+
case AMDGPU::OPERAND_REG_IMM_V2INT16:
1608+
UseLit = AMDGPU::isInlinableLiteralV2I16(Val);
1609+
break;
1610+
case AMDGPU::OPERAND_REG_IMM_FP32:
1611+
case AMDGPU::OPERAND_REG_INLINE_C_FP32:
1612+
case AMDGPU::OPERAND_REG_INLINE_AC_FP32:
1613+
case AMDGPU::OPERAND_REG_IMM_INT32:
1614+
case AMDGPU::OPERAND_REG_INLINE_C_INT32:
1615+
case AMDGPU::OPERAND_REG_INLINE_AC_INT32:
1616+
case AMDGPU::OPERAND_REG_IMM_V2FP32:
1617+
case AMDGPU::OPERAND_REG_IMM_V2INT32:
1618+
case AMDGPU::OPERAND_KIMM32:
1619+
UseLit = AMDGPU::isInlinableLiteral32(Val, HasInv2Pi);
1620+
break;
1621+
case AMDGPU::OPERAND_REG_IMM_FP64:
1622+
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
1623+
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
1624+
Val <<= 32;
1625+
break;
1626+
case AMDGPU::OPERAND_REG_IMM_INT64:
1627+
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
1628+
UseLit = AMDGPU::isInlinableLiteral64(Val, HasInv2Pi);
1629+
break;
1630+
case MCOI::OPERAND_REGISTER:
1631+
// TODO: Disassembling V_DUAL_FMAMK_F32_X_FMAMK_F32_gfx11 hits
1632+
// decoding a literal in a position of a register operand. Give
1633+
// it special handling in the caller, decodeImmOperands(), instead
1634+
// of quietly allowing it here.
1635+
break;
15921636
}
15931637

1594-
return UseLit64 ? MCOperand::createExpr(AMDGPUMCExpr::createLit(
1595-
LitModifier::Lit64, Val, getContext()))
1596-
: MCOperand::createImm(Val);
1638+
return UseLit ? MCOperand::createExpr(AMDGPUMCExpr::createLit(
1639+
LitModifier::Lit, Val, getContext()))
1640+
: MCOperand::createImm(Val);
15971641
}
15981642

1599-
MCOperand
1600-
AMDGPUDisassembler::decodeLiteral64Constant(const MCInst &Inst) const {
1643+
MCOperand AMDGPUDisassembler::decodeLiteral64Constant() const {
16011644
assert(STI.hasFeature(AMDGPU::Feature64BitLiterals));
16021645

16031646
if (!HasLiteral) {
@@ -1606,25 +1649,13 @@ AMDGPUDisassembler::decodeLiteral64Constant(const MCInst &Inst) const {
16061649
Twine(Bytes.size()));
16071650
}
16081651
HasLiteral = true;
1609-
Literal64 = eatBytes<uint64_t>(Bytes);
1610-
}
1611-
1612-
bool UseLit64 = false;
1613-
const MCInstrDesc &Desc = MCII->get(Inst.getOpcode());
1614-
const MCOperandInfo &OpDesc = Desc.operands()[Inst.getNumOperands()];
1615-
if (OpDesc.OperandType == AMDGPU::OPERAND_REG_IMM_INT64 ||
1616-
OpDesc.OperandType == AMDGPU::OPERAND_REG_INLINE_C_INT64) {
1617-
UseLit64 = false;
1618-
} else {
1619-
assert(OpDesc.OperandType == AMDGPU::OPERAND_REG_IMM_FP64 ||
1620-
OpDesc.OperandType == AMDGPU::OPERAND_REG_INLINE_C_FP64 ||
1621-
OpDesc.OperandType == AMDGPU::OPERAND_REG_INLINE_AC_FP64);
1622-
UseLit64 = Hi_32(Literal64) == 0;
1652+
Literal = eatBytes<uint64_t>(Bytes);
16231653
}
16241654

1655+
bool UseLit64 = Hi_32(Literal) == 0;
16251656
return UseLit64 ? MCOperand::createExpr(AMDGPUMCExpr::createLit(
1626-
LitModifier::Lit64, Literal64, getContext()))
1627-
: MCOperand::createImm(Literal64);
1657+
LitModifier::Lit64, Literal, getContext()))
1658+
: MCOperand::createImm(Literal);
16281659
}
16291660

16301661
MCOperand AMDGPUDisassembler::decodeIntImmed(unsigned Imm) {
@@ -1913,7 +1944,7 @@ MCOperand AMDGPUDisassembler::decodeNonVGPRSrcOp(const MCInst &Inst,
19131944
return MCOperand::createImm(Val);
19141945

19151946
if (Val == LITERAL64_CONST && STI.hasFeature(AMDGPU::Feature64BitLiterals)) {
1916-
return decodeLiteral64Constant(Inst);
1947+
return decodeLiteral64Constant();
19171948
}
19181949

19191950
switch (Width) {

llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ class AMDGPUDisassembler : public MCDisassembler {
4444
const unsigned HwModeRegClass;
4545
const unsigned TargetMaxInstBytes;
4646
mutable ArrayRef<uint8_t> Bytes;
47-
mutable uint32_t Literal;
48-
mutable uint64_t Literal64;
47+
mutable uint64_t Literal;
4948
mutable bool HasLiteral;
5049
mutable std::optional<bool> EnableWavefrontSize32;
5150
unsigned CodeObjectVersion;
@@ -144,9 +143,8 @@ class AMDGPUDisassembler : public MCDisassembler {
144143
MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const;
145144
MCOperand decodeMandatoryLiteral64Constant(uint64_t Imm) const;
146145
MCOperand decodeLiteralConstant(const MCInstrDesc &Desc,
147-
const MCOperandInfo &OpDesc,
148-
bool ExtendFP64) const;
149-
MCOperand decodeLiteral64Constant(const MCInst &Inst) const;
146+
const MCOperandInfo &OpDesc) const;
147+
MCOperand decodeLiteral64Constant() const;
150148

151149
MCOperand decodeSrcOp(const MCInst &Inst, unsigned Width, unsigned Val) const;
152150

llvm/test/MC/AMDGPU/gfx1250_asm_salu_lit64.s

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
2-
// RUN: llvm-mc -triple=amdgcn -show-encoding -mcpu=gfx1250 %s | FileCheck --check-prefixes=GFX1250,GFX1250-ASM %s
3-
// RUN: llvm-mc -triple=amdgcn -mcpu=gfx1250 -show-encoding %s | %extract-encodings | llvm-mc -triple=amdgcn -mcpu=gfx1250 -disassemble -show-encoding | FileCheck --check-prefixes=GFX1250,GFX1250-DIS %s
2+
// RUN: llvm-mc -triple=amdgcn -show-encoding -mcpu=gfx1250 %s | FileCheck --check-prefixes=GFX1250 %s
3+
// RUN: llvm-mc -triple=amdgcn -mcpu=gfx1250 -show-encoding %s | %extract-encodings | llvm-mc -triple=amdgcn -mcpu=gfx1250 -disassemble -show-encoding | FileCheck --check-prefixes=GFX1250 %s
44

55
s_mov_b64 s[2:3], 0x10abcdef12345678
66
// GFX1250: s_mov_b64 s[2:3], 0x10abcdef12345678 ; encoding: [0xfe,0x01,0x82,0xbe,0x78,0x56,0x34,0x12,0xef,0xcd,0xab,0x10]
@@ -62,10 +62,8 @@ s_cselect_b64 s[2:3], s[4:5], 0x10abcdef12345678
6262
s_mov_b64 s[2:3], 0xffffffff01234567
6363
// GFX1250: s_mov_b64 s[2:3], 0xffffffff01234567 ; encoding: [0xfe,0x01,0x82,0xbe,0x67,0x45,0x23,0x01,0xff,0xff,0xff,0xff]
6464

65-
// TODO: disasm
6665
s_mov_b64 s[2:3], lit64(0x777)
67-
// GFX1250-ASM: s_mov_b64 s[2:3], lit64(0x777) ; encoding: [0xfe,0x01,0x82,0xbe,0x77,0x07,0x00,0x00,0x00,0x00,0x00,0x00]
68-
// GFX1250-DIS: s_mov_b64 s[2:3], 0x777 ; encoding: [0xff,0x01,0x82,0xbe,0x77,0x07,0x00,0x00]
66+
// GFX1250: s_mov_b64 s[2:3], lit64(0x777) ; encoding: [0xfe,0x01,0x82,0xbe,0x77,0x07,0x00,0x00,0x00,0x00,0x00,0x00]
6967

7068
s_mov_b64 s[2:3], 0x777
7169
// GFX1250: s_mov_b64 s[2:3], 0x777 ; encoding: [0xff,0x01,0x82,0xbe,0x77,0x07,0x00,0x00]

llvm/test/MC/AMDGPU/gfx1250_asm_vop1.s

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
2-
// RUN: llvm-mc -triple=amdgcn -mcpu=gfx1250 -mattr=+real-true16 -show-encoding %s | FileCheck --check-prefix=GFX1250 %s
3-
// RUN: llvm-mc -triple=amdgcn -mcpu=gfx1250 -mattr=+real-true16 -show-encoding %s | %extract-encodings | llvm-mc -triple=amdgcn -mcpu=gfx1250 -mattr=+real-true16 -disassemble -show-encoding | FileCheck --check-prefixes=GFX1250 %s
2+
// RUN: llvm-mc -triple=amdgcn -mcpu=gfx1250 -mattr=+real-true16 -show-encoding %s | FileCheck --check-prefixes=GFX1250,GFX1250-ASM %s
3+
// RUN: llvm-mc -triple=amdgcn -mcpu=gfx1250 -mattr=+real-true16 -show-encoding %s | %extract-encodings | llvm-mc -triple=amdgcn -mcpu=gfx1250 -mattr=+real-true16 -disassemble -show-encoding | FileCheck --check-prefixes=GFX1250,GFX1250-DIS %s
44

55
v_mov_b64_e32 v[4:5], v[2:3]
66
// GFX1250: v_mov_b64_e32 v[4:5], v[2:3] ; encoding: [0x02,0x3b,0x08,0x7e]
@@ -26,8 +26,10 @@ v_mov_b64 v[4:5], -1
2626
v_mov_b64 v[4:5], 0.5
2727
// GFX1250: v_mov_b64_e32 v[4:5], 0.5 ; encoding: [0xf0,0x3a,0x08,0x7e]
2828

29+
// TODO: Encode as a 32-bit literal unless lit64() is specified.
2930
v_mov_b64 v[254:255], 0xaf123456
30-
// GFX1250: v_mov_b64_e32 v[254:255], 0xaf123456 ; encoding: [0xfe,0x3a,0xfc,0x7f,0x56,0x34,0x12,0xaf,0x00,0x00,0x00,0x00]
31+
// GFX1250-ASM: v_mov_b64_e32 v[254:255], 0xaf123456 ; encoding: [0xfe,0x3a,0xfc,0x7f,0x56,0x34,0x12,0xaf,0x00,0x00,0x00,0x00]
32+
// GFX1250-DIS: v_mov_b64_e32 v[254:255], lit64(0xaf123456) ; encoding: [0xfe,0x3a,0xfc,0x7f,0x56,0x34,0x12,0xaf,0x00,0x00,0x00,0x00]
3133

3234
v_tanh_f32 v5, v1
3335
// GFX1250: v_tanh_f32_e32 v5, v1 ; encoding: [0x01,0x3d,0x0a,0x7e]

llvm/test/MC/AMDGPU/gfx1250_asm_vop2.s

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,9 @@ v_add_nc_u64 v[4:5], -4.0, v[4:5]
196196
// GFX1200-ERR: :[[@LINE-2]]:1: error: instruction not supported on this GPU
197197

198198
v_add_nc_u64 v[4:5], 0xaf123456, v[4:5]
199-
// GFX1250: v_add_nc_u64_e32 v[4:5], 0xaf123456, v[4:5] ; encoding: [0xfe,0x08,0x08,0x50,0x56,0x34,0x12,0xaf,0x00,0x00,0x00,0x00]
200-
// GFX1200-ERR: :[[@LINE-2]]:1: error: instruction not supported on this GPU
199+
// GFX1250-ASM: v_add_nc_u64_e32 v[4:5], 0xaf123456, v[4:5] ; encoding: [0xfe,0x08,0x08,0x50,0x56,0x34,0x12,0xaf,0x00,0x00,0x00,0x00]
200+
// GFX1250-DIS: v_add_nc_u64_e32 v[4:5], lit64(0xaf123456), v[4:5] ; encoding: [0xfe,0x08,0x08,0x50,0x56,0x34,0x12,0xaf,0x00,0x00,0x00,0x00]
201+
// GFX1200-ERR: :[[@LINE-3]]:1: error: instruction not supported on this GPU
201202

202203
v_add_nc_u64 v[4:5], 0x3f717273, v[4:5]
203204
// GFX1250: v_add_nc_u64_e32 v[4:5], 0x3f717273, v[4:5] ; encoding: [0xff,0x08,0x08,0x50,0x73,0x72,0x71,0x3f]
@@ -316,8 +317,9 @@ v_sub_nc_u64 v[4:5], -4.0, v[4:5]
316317
// GFX1200-ERR: :[[@LINE-2]]:1: error: instruction not supported on this GPU
317318

318319
v_sub_nc_u64 v[4:5], 0xaf123456, v[4:5]
319-
// GFX1250: v_sub_nc_u64_e32 v[4:5], 0xaf123456, v[4:5] ; encoding: [0xfe,0x08,0x08,0x52,0x56,0x34,0x12,0xaf,0x00,0x00,0x00,0x00]
320-
// GFX1200-ERR: :[[@LINE-2]]:1: error: instruction not supported on this GPU
320+
// GFX1250-ASM: v_sub_nc_u64_e32 v[4:5], 0xaf123456, v[4:5] ; encoding: [0xfe,0x08,0x08,0x52,0x56,0x34,0x12,0xaf,0x00,0x00,0x00,0x00]
321+
// GFX1250-DIS: v_sub_nc_u64_e32 v[4:5], lit64(0xaf123456), v[4:5] ; encoding: [0xfe,0x08,0x08,0x52,0x56,0x34,0x12,0xaf,0x00,0x00,0x00,0x00]
322+
// GFX1200-ERR: :[[@LINE-3]]:1: error: instruction not supported on this GPU
321323

322324
v_sub_nc_u64 v[4:5], 0x3f717273, v[4:5]
323325
// GFX1250: v_sub_nc_u64_e32 v[4:5], 0x3f717273, v[4:5] ; encoding: [0xff,0x08,0x08,0x52,0x73,0x72,0x71,0x3f]
@@ -436,8 +438,9 @@ v_mul_u64 v[4:5], -4.0, v[4:5]
436438
// GFX1200-ERR: :[[@LINE-2]]:1: error: instruction not supported on this GPU
437439

438440
v_mul_u64 v[4:5], 0xaf123456, v[4:5]
439-
// GFX1250: v_mul_u64_e32 v[4:5], 0xaf123456, v[4:5] ; encoding: [0xfe,0x08,0x08,0x54,0x56,0x34,0x12,0xaf,0x00,0x00,0x00,0x00]
440-
// GFX1200-ERR: :[[@LINE-2]]:1: error: instruction not supported on this GPU
441+
// GFX1250-ASM: v_mul_u64_e32 v[4:5], 0xaf123456, v[4:5] ; encoding: [0xfe,0x08,0x08,0x54,0x56,0x34,0x12,0xaf,0x00,0x00,0x00,0x00]
442+
// GFX1250-DIS: v_mul_u64_e32 v[4:5], lit64(0xaf123456), v[4:5] ; encoding: [0xfe,0x08,0x08,0x54,0x56,0x34,0x12,0xaf,0x00,0x00,0x00,0x00]
443+
// GFX1200-ERR: :[[@LINE-3]]:1: error: instruction not supported on this GPU
441444

442445
v_mul_u64 v[4:5], 0x3f717273, v[4:5]
443446
// GFX1250: v_mul_u64_e32 v[4:5], 0x3f717273, v[4:5] ; encoding: [0xff,0x08,0x08,0x54,0x73,0x72,0x71,0x3f]

0 commit comments

Comments
 (0)