Skip to content

Commit c89e60b

Browse files
committed
[AMDGPU][MC][GFX11] Add VOPD literals validation
Differential Revision: https://reviews.llvm.org/D133864
1 parent 8bb5c89 commit c89e60b

File tree

4 files changed

+153
-11
lines changed

4 files changed

+153
-11
lines changed

llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3425,6 +3425,35 @@ unsigned AMDGPUAsmParser::getConstantBusLimit(unsigned Opcode) const {
34253425
}
34263426
}
34273427

3428+
constexpr unsigned MAX_SRC_OPERANDS_NUM = 6;
3429+
using OperandIndices = SmallVector<int16_t, MAX_SRC_OPERANDS_NUM>;
3430+
3431+
// Get regular operand indices in the same order as specified
3432+
// in the instruction (but append mandatory literals to the end).
3433+
static OperandIndices getSrcOperandIndices(unsigned Opcode,
3434+
bool AddMandatoryLiterals = false) {
3435+
3436+
int16_t ImmIdx =
3437+
AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3438+
3439+
if (isVOPD(Opcode)) {
3440+
int16_t ImmDeferredIdx =
3441+
AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immDeferred)
3442+
: -1;
3443+
3444+
return {getNamedOperandIdx(Opcode, OpName::src0X),
3445+
getNamedOperandIdx(Opcode, OpName::vsrc1X),
3446+
getNamedOperandIdx(Opcode, OpName::src0Y),
3447+
getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3448+
ImmDeferredIdx,
3449+
ImmIdx};
3450+
}
3451+
3452+
return {getNamedOperandIdx(Opcode, OpName::src0),
3453+
getNamedOperandIdx(Opcode, OpName::src1),
3454+
getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3455+
}
3456+
34283457
bool AMDGPUAsmParser::usesConstantBus(const MCInst &Inst, unsigned OpIdx) {
34293458
const MCOperand &MO = Inst.getOperand(OpIdx);
34303459
if (MO.isImm()) {
@@ -4285,16 +4314,12 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst &Inst,
42854314
const OperandVector &Operands) {
42864315
unsigned Opcode = Inst.getOpcode();
42874316
const MCInstrDesc &Desc = MII.get(Opcode);
4288-
const int ImmIdx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::imm);
4317+
bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
42894318
if (!(Desc.TSFlags & (SIInstrFlags::VOP3 | SIInstrFlags::VOP3P)) &&
4290-
ImmIdx == -1)
4319+
!HasMandatoryLiteral && !isVOPD(Opcode))
42914320
return true;
42924321

4293-
const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4294-
const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4295-
const int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2);
4296-
4297-
const int OpIndices[] = {Src0Idx, Src1Idx, Src2Idx, ImmIdx};
4322+
OperandIndices OpIndices = getSrcOperandIndices(Opcode, HasMandatoryLiteral);
42984323

42994324
unsigned NumExprs = 0;
43004325
unsigned NumLiterals = 0;
@@ -4307,7 +4332,7 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst &Inst,
43074332
const MCOperand &MO = Inst.getOperand(OpIdx);
43084333
if (!MO.isImm() && !MO.isExpr())
43094334
continue;
4310-
if (!AMDGPU::isSISrcOperand(Desc, OpIdx))
4335+
if (!isSISrcOperand(Desc, OpIdx))
43114336
continue;
43124337

43134338
if (MO.isImm() && !isInlineConstant(Inst, OpIdx)) {
@@ -4325,13 +4350,13 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst &Inst,
43254350
if (!NumLiterals)
43264351
return true;
43274352

4328-
if (ImmIdx == -1 && !getFeatureBits()[AMDGPU::FeatureVOP3Literal]) {
4353+
if (!HasMandatoryLiteral && !getFeatureBits()[FeatureVOP3Literal]) {
43294354
Error(getLitLoc(Operands), "literal operands are not supported");
43304355
return false;
43314356
}
43324357

43334358
if (NumLiterals > 1) {
4334-
Error(getLitLoc(Operands), "only one literal operand is allowed");
4359+
Error(getLitLoc(Operands, true), "only one literal operand is allowed");
43354360
return false;
43364361
}
43374362

llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,9 @@ unsigned getVOPDOpcode(unsigned Opc) {
427427
return Info ? Info->VOPDOp : ~0u;
428428
}
429429

430-
bool isVOPD(unsigned Opc) { return getVOPDOpcodeHelper(Opc); }
430+
bool isVOPD(unsigned Opc) {
431+
return AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0X) != -1;
432+
}
431433

432434
unsigned mapWMMA2AddrTo3AddrOpcode(unsigned Opc) {
433435
const WMMAOpcodeMappingInfo *Info = getWMMAMappingInfoFrom2AddrOpcode(Opc);
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx1100 %s 2>&1 | FileCheck %s -check-prefix=GFX11 --implicit-check-not=error: --strict-whitespace
2+
3+
//===----------------------------------------------------------------------===//
4+
// A VOPD instruction can use only one literal.
5+
//===----------------------------------------------------------------------===//
6+
7+
v_dual_mul_f32 v11, 0x24681357, v2 :: v_dual_mul_f32 v10, 0xbabe, v5
8+
// GFX11: error: only one literal operand is allowed
9+
// GFX11-NEXT:{{^}}v_dual_mul_f32 v11, 0x24681357, v2 :: v_dual_mul_f32 v10, 0xbabe, v5
10+
// GFX11-NEXT:{{^}} ^
11+
12+
//===----------------------------------------------------------------------===//
13+
// When 2 different literals are specified, show the location
14+
// of the last literal which is not a KImm, if any.
15+
//===----------------------------------------------------------------------===//
16+
17+
v_dual_fmamk_f32 v122, v74, 0xa0172923, v161 :: v_dual_lshlrev_b32 v247, 0xbabe, v99
18+
// GFX11: error: only one literal operand is allowed
19+
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, v74, 0xa0172923, v161 :: v_dual_lshlrev_b32 v247, 0xbabe, v99
20+
// GFX11-NEXT:{{^}} ^
21+
22+
v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, v3, v1, 0xbabe
23+
// GFX11: error: only one literal operand is allowed
24+
// GFX11-NEXT:{{^}}v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, v3, v1, 0xbabe
25+
// GFX11-NEXT:{{^}} ^
26+
27+
v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, 0xbabe, v1, 0xbabe
28+
// GFX11: error: only one literal operand is allowed
29+
// GFX11-NEXT:{{^}}v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, 0xbabe, v1, 0xbabe
30+
// GFX11-NEXT:{{^}} ^
31+
32+
v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0x1234, v162
33+
// GFX11: error: only one literal operand is allowed
34+
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0x1234, v162
35+
// GFX11-NEXT:{{^}} ^
36+
37+
v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, s0, 0x1234, v162
38+
// GFX11: error: only one literal operand is allowed
39+
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, s0, 0x1234, v162
40+
// GFX11-NEXT:{{^}} ^
41+
42+
//===----------------------------------------------------------------------===//
43+
// Check that assembler detects a different literal regardless of its location.
44+
//===----------------------------------------------------------------------===//
45+
46+
v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0x1234, v162
47+
// GFX11: error: only one literal operand is allowed
48+
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0x1234, v162
49+
// GFX11-NEXT:{{^}} ^
50+
51+
v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0x1234, 0xdeadbeef, v162
52+
// GFX11: error: only one literal operand is allowed
53+
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0x1234, 0xdeadbeef, v162
54+
// GFX11-NEXT:{{^}} ^
55+
56+
v_dual_fmamk_f32 v122, 0xdeadbeef, 0x1234, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0xdeadbeef, v162
57+
// GFX11: error: only one literal operand is allowed
58+
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0xdeadbeef, 0x1234, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0xdeadbeef, v162
59+
// GFX11-NEXT:{{^}} ^
60+
61+
v_dual_fmamk_f32 v122, 0x1234, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0xdeadbeef, v162
62+
// GFX11: error: only one literal operand is allowed
63+
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0x1234, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0xdeadbeef, v162
64+
// GFX11-NEXT:{{^}} ^
65+
66+
//===----------------------------------------------------------------------===//
67+
// When 2 different literals are specified and all literals are KImm,
68+
// show the location of the last KImm literal.
69+
//===----------------------------------------------------------------------===//
70+
71+
v_dual_fmamk_f32 v122, s0, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, s0, 0x1234, v162
72+
// GFX11: error: only one literal operand is allowed
73+
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, s0, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, s0, 0x1234, v162
74+
// GFX11-NEXT:{{^}} ^
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: llvm-mc -arch=amdgcn -mcpu=gfx1100 -show-encoding %s | FileCheck -check-prefix=GFX11 %s
2+
3+
//===----------------------------------------------------------------------===//
4+
// A VOPD instruction can use one or more literals,
5+
// provided that they are identical.
6+
//===----------------------------------------------------------------------===//
7+
8+
// LITERAL
9+
10+
v_dual_mul_f32 v11, v1, v2 :: v_dual_mul_f32 v10, 0x24681357, v5
11+
// GFX11: encoding: [0x01,0x05,0xc6,0xc8,0xff,0x0a,0x0a,0x0b,0x57,0x13,0x68,0x24]
12+
13+
// LITERAL*2
14+
15+
v_dual_mul_f32 v11, 0x24681357, v2 :: v_dual_mul_f32 v10, 0x24681357, v5
16+
// GFX11: encoding: [0xff,0x04,0xc6,0xc8,0xff,0x0a,0x0a,0x0b,0x57,0x13,0x68,0x24]
17+
18+
// LITERAL*2 (this is an unclear case because literals have different size, but SP3 accepts this code)
19+
20+
v_dual_add_f32 v6, 0xfe0b, v5 :: v_dual_dot2acc_f32_f16 v255, 0xfe0b, v4
21+
// GFX11: encoding: [0xff,0x0a,0x18,0xc9,0xff,0x08,0xfe,0x06,0x0b,0xfe,0x00,0x00]
22+
23+
// LITERAL + KIMM
24+
25+
v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, v3, v1, 0xaf123456 ;
26+
// GFX11: encoding: [0xff,0x04,0x02,0xc9,0x03,0x03,0x06,0x05,0x56,0x34,0x12,0xaf]
27+
28+
// KIMM + LITERAL
29+
30+
v_dual_fmamk_f32 v122, v74, 0xa0172923, v161 :: v_dual_lshlrev_b32 v247, 0xa0172923, v99
31+
// GFX11: encoding: [0x4a,0x43,0xa3,0xc8,0xff,0xc6,0xf6,0x7a,0x23,0x29,0x17,0xa0]
32+
33+
// KIMM + LITERAL (this is an unclear case because literals have different size, but SP3 accepts this code)
34+
35+
v_dual_fmamk_f32 v122, v74, 0xfe0b, v162 :: v_dual_dot2acc_f32_f16 v247, 0xfe0b, v99
36+
// GFX11: encoding: [0x4a,0x45,0x99,0xc8,0xff,0xc6,0xf6,0x7a,0x0b,0xfe,0x00,0x00]
37+
38+
// KIMM*2
39+
40+
v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0xdeadbeef, v162
41+
// GFX11: encoding: [0xff,0x42,0x85,0xc8,0xff,0x44,0x7b,0x7a,0xef,0xbe,0xad,0xde]

0 commit comments

Comments
 (0)