forked from OSchip/llvm-project
[AMDGPU][MC][GFX11] Add VOPD literals validation
Differential Revision: https://reviews.llvm.org/D133864
This commit is contained in:
parent
8bb5c89205
commit
c89e60bf1f
|
@ -3425,6 +3425,35 @@ unsigned AMDGPUAsmParser::getConstantBusLimit(unsigned Opcode) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr unsigned MAX_SRC_OPERANDS_NUM = 6;
|
||||||
|
using OperandIndices = SmallVector<int16_t, MAX_SRC_OPERANDS_NUM>;
|
||||||
|
|
||||||
|
// Get regular operand indices in the same order as specified
|
||||||
|
// in the instruction (but append mandatory literals to the end).
|
||||||
|
static OperandIndices getSrcOperandIndices(unsigned Opcode,
|
||||||
|
bool AddMandatoryLiterals = false) {
|
||||||
|
|
||||||
|
int16_t ImmIdx =
|
||||||
|
AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
|
||||||
|
|
||||||
|
if (isVOPD(Opcode)) {
|
||||||
|
int16_t ImmDeferredIdx =
|
||||||
|
AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immDeferred)
|
||||||
|
: -1;
|
||||||
|
|
||||||
|
return {getNamedOperandIdx(Opcode, OpName::src0X),
|
||||||
|
getNamedOperandIdx(Opcode, OpName::vsrc1X),
|
||||||
|
getNamedOperandIdx(Opcode, OpName::src0Y),
|
||||||
|
getNamedOperandIdx(Opcode, OpName::vsrc1Y),
|
||||||
|
ImmDeferredIdx,
|
||||||
|
ImmIdx};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {getNamedOperandIdx(Opcode, OpName::src0),
|
||||||
|
getNamedOperandIdx(Opcode, OpName::src1),
|
||||||
|
getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
|
||||||
|
}
|
||||||
|
|
||||||
bool AMDGPUAsmParser::usesConstantBus(const MCInst &Inst, unsigned OpIdx) {
|
bool AMDGPUAsmParser::usesConstantBus(const MCInst &Inst, unsigned OpIdx) {
|
||||||
const MCOperand &MO = Inst.getOperand(OpIdx);
|
const MCOperand &MO = Inst.getOperand(OpIdx);
|
||||||
if (MO.isImm()) {
|
if (MO.isImm()) {
|
||||||
|
@ -4285,16 +4314,12 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst &Inst,
|
||||||
const OperandVector &Operands) {
|
const OperandVector &Operands) {
|
||||||
unsigned Opcode = Inst.getOpcode();
|
unsigned Opcode = Inst.getOpcode();
|
||||||
const MCInstrDesc &Desc = MII.get(Opcode);
|
const MCInstrDesc &Desc = MII.get(Opcode);
|
||||||
const int ImmIdx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::imm);
|
bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
|
||||||
if (!(Desc.TSFlags & (SIInstrFlags::VOP3 | SIInstrFlags::VOP3P)) &&
|
if (!(Desc.TSFlags & (SIInstrFlags::VOP3 | SIInstrFlags::VOP3P)) &&
|
||||||
ImmIdx == -1)
|
!HasMandatoryLiteral && !isVOPD(Opcode))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
|
OperandIndices OpIndices = getSrcOperandIndices(Opcode, HasMandatoryLiteral);
|
||||||
const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
|
|
||||||
const int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2);
|
|
||||||
|
|
||||||
const int OpIndices[] = {Src0Idx, Src1Idx, Src2Idx, ImmIdx};
|
|
||||||
|
|
||||||
unsigned NumExprs = 0;
|
unsigned NumExprs = 0;
|
||||||
unsigned NumLiterals = 0;
|
unsigned NumLiterals = 0;
|
||||||
|
@ -4307,7 +4332,7 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst &Inst,
|
||||||
const MCOperand &MO = Inst.getOperand(OpIdx);
|
const MCOperand &MO = Inst.getOperand(OpIdx);
|
||||||
if (!MO.isImm() && !MO.isExpr())
|
if (!MO.isImm() && !MO.isExpr())
|
||||||
continue;
|
continue;
|
||||||
if (!AMDGPU::isSISrcOperand(Desc, OpIdx))
|
if (!isSISrcOperand(Desc, OpIdx))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (MO.isImm() && !isInlineConstant(Inst, OpIdx)) {
|
if (MO.isImm() && !isInlineConstant(Inst, OpIdx)) {
|
||||||
|
@ -4325,13 +4350,13 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst &Inst,
|
||||||
if (!NumLiterals)
|
if (!NumLiterals)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (ImmIdx == -1 && !getFeatureBits()[AMDGPU::FeatureVOP3Literal]) {
|
if (!HasMandatoryLiteral && !getFeatureBits()[FeatureVOP3Literal]) {
|
||||||
Error(getLitLoc(Operands), "literal operands are not supported");
|
Error(getLitLoc(Operands), "literal operands are not supported");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NumLiterals > 1) {
|
if (NumLiterals > 1) {
|
||||||
Error(getLitLoc(Operands), "only one literal operand is allowed");
|
Error(getLitLoc(Operands, true), "only one literal operand is allowed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -427,7 +427,9 @@ unsigned getVOPDOpcode(unsigned Opc) {
|
||||||
return Info ? Info->VOPDOp : ~0u;
|
return Info ? Info->VOPDOp : ~0u;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isVOPD(unsigned Opc) { return getVOPDOpcodeHelper(Opc); }
|
bool isVOPD(unsigned Opc) {
|
||||||
|
return AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0X) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned mapWMMA2AddrTo3AddrOpcode(unsigned Opc) {
|
unsigned mapWMMA2AddrTo3AddrOpcode(unsigned Opc) {
|
||||||
const WMMAOpcodeMappingInfo *Info = getWMMAMappingInfoFrom2AddrOpcode(Opc);
|
const WMMAOpcodeMappingInfo *Info = getWMMAMappingInfoFrom2AddrOpcode(Opc);
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx1100 %s 2>&1 | FileCheck %s -check-prefix=GFX11 --implicit-check-not=error: --strict-whitespace
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// A VOPD instruction can use only one literal.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
v_dual_mul_f32 v11, 0x24681357, v2 :: v_dual_mul_f32 v10, 0xbabe, v5
|
||||||
|
// GFX11: error: only one literal operand is allowed
|
||||||
|
// GFX11-NEXT:{{^}}v_dual_mul_f32 v11, 0x24681357, v2 :: v_dual_mul_f32 v10, 0xbabe, v5
|
||||||
|
// GFX11-NEXT:{{^}} ^
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// When 2 different literals are specified, show the location
|
||||||
|
// of the last literal which is not a KImm, if any.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
v_dual_fmamk_f32 v122, v74, 0xa0172923, v161 :: v_dual_lshlrev_b32 v247, 0xbabe, v99
|
||||||
|
// GFX11: error: only one literal operand is allowed
|
||||||
|
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, v74, 0xa0172923, v161 :: v_dual_lshlrev_b32 v247, 0xbabe, v99
|
||||||
|
// GFX11-NEXT:{{^}} ^
|
||||||
|
|
||||||
|
v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, v3, v1, 0xbabe
|
||||||
|
// GFX11: error: only one literal operand is allowed
|
||||||
|
// GFX11-NEXT:{{^}}v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, v3, v1, 0xbabe
|
||||||
|
// GFX11-NEXT:{{^}} ^
|
||||||
|
|
||||||
|
v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, 0xbabe, v1, 0xbabe
|
||||||
|
// GFX11: error: only one literal operand is allowed
|
||||||
|
// GFX11-NEXT:{{^}}v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, 0xbabe, v1, 0xbabe
|
||||||
|
// GFX11-NEXT:{{^}} ^
|
||||||
|
|
||||||
|
v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0x1234, v162
|
||||||
|
// GFX11: error: only one literal operand is allowed
|
||||||
|
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0x1234, v162
|
||||||
|
// GFX11-NEXT:{{^}} ^
|
||||||
|
|
||||||
|
v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, s0, 0x1234, v162
|
||||||
|
// GFX11: error: only one literal operand is allowed
|
||||||
|
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, s0, 0x1234, v162
|
||||||
|
// GFX11-NEXT:{{^}} ^
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Check that assembler detects a different literal regardless of its location.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0x1234, v162
|
||||||
|
// GFX11: error: only one literal operand is allowed
|
||||||
|
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0x1234, v162
|
||||||
|
// GFX11-NEXT:{{^}} ^
|
||||||
|
|
||||||
|
v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0x1234, 0xdeadbeef, v162
|
||||||
|
// GFX11: error: only one literal operand is allowed
|
||||||
|
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0x1234, 0xdeadbeef, v162
|
||||||
|
// GFX11-NEXT:{{^}} ^
|
||||||
|
|
||||||
|
v_dual_fmamk_f32 v122, 0xdeadbeef, 0x1234, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0xdeadbeef, v162
|
||||||
|
// GFX11: error: only one literal operand is allowed
|
||||||
|
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0xdeadbeef, 0x1234, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0xdeadbeef, v162
|
||||||
|
// GFX11-NEXT:{{^}} ^
|
||||||
|
|
||||||
|
v_dual_fmamk_f32 v122, 0x1234, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0xdeadbeef, v162
|
||||||
|
// GFX11: error: only one literal operand is allowed
|
||||||
|
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0x1234, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0xdeadbeef, v162
|
||||||
|
// GFX11-NEXT:{{^}} ^
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// When 2 different literals are specified and all literals are KImm,
|
||||||
|
// show the location of the last KImm literal.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
v_dual_fmamk_f32 v122, s0, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, s0, 0x1234, v162
|
||||||
|
// GFX11: error: only one literal operand is allowed
|
||||||
|
// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, s0, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, s0, 0x1234, v162
|
||||||
|
// GFX11-NEXT:{{^}} ^
|
|
@ -0,0 +1,41 @@
|
||||||
|
// RUN: llvm-mc -arch=amdgcn -mcpu=gfx1100 -show-encoding %s | FileCheck -check-prefix=GFX11 %s
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// A VOPD instruction can use one or more literals,
|
||||||
|
// provided that they are identical.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// LITERAL
|
||||||
|
|
||||||
|
v_dual_mul_f32 v11, v1, v2 :: v_dual_mul_f32 v10, 0x24681357, v5
|
||||||
|
// GFX11: encoding: [0x01,0x05,0xc6,0xc8,0xff,0x0a,0x0a,0x0b,0x57,0x13,0x68,0x24]
|
||||||
|
|
||||||
|
// LITERAL*2
|
||||||
|
|
||||||
|
v_dual_mul_f32 v11, 0x24681357, v2 :: v_dual_mul_f32 v10, 0x24681357, v5
|
||||||
|
// GFX11: encoding: [0xff,0x04,0xc6,0xc8,0xff,0x0a,0x0a,0x0b,0x57,0x13,0x68,0x24]
|
||||||
|
|
||||||
|
// LITERAL*2 (this is an unclear case because literals have different size, but SP3 accepts this code)
|
||||||
|
|
||||||
|
v_dual_add_f32 v6, 0xfe0b, v5 :: v_dual_dot2acc_f32_f16 v255, 0xfe0b, v4
|
||||||
|
// GFX11: encoding: [0xff,0x0a,0x18,0xc9,0xff,0x08,0xfe,0x06,0x0b,0xfe,0x00,0x00]
|
||||||
|
|
||||||
|
// LITERAL + KIMM
|
||||||
|
|
||||||
|
v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, v3, v1, 0xaf123456 ;
|
||||||
|
// GFX11: encoding: [0xff,0x04,0x02,0xc9,0x03,0x03,0x06,0x05,0x56,0x34,0x12,0xaf]
|
||||||
|
|
||||||
|
// KIMM + LITERAL
|
||||||
|
|
||||||
|
v_dual_fmamk_f32 v122, v74, 0xa0172923, v161 :: v_dual_lshlrev_b32 v247, 0xa0172923, v99
|
||||||
|
// GFX11: encoding: [0x4a,0x43,0xa3,0xc8,0xff,0xc6,0xf6,0x7a,0x23,0x29,0x17,0xa0]
|
||||||
|
|
||||||
|
// KIMM + LITERAL (this is an unclear case because literals have different size, but SP3 accepts this code)
|
||||||
|
|
||||||
|
v_dual_fmamk_f32 v122, v74, 0xfe0b, v162 :: v_dual_dot2acc_f32_f16 v247, 0xfe0b, v99
|
||||||
|
// GFX11: encoding: [0x4a,0x45,0x99,0xc8,0xff,0xc6,0xf6,0x7a,0x0b,0xfe,0x00,0x00]
|
||||||
|
|
||||||
|
// KIMM*2
|
||||||
|
|
||||||
|
v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, 0xdeadbeef, 0xdeadbeef, v162
|
||||||
|
// GFX11: encoding: [0xff,0x42,0x85,0xc8,0xff,0x44,0x7b,0x7a,0xef,0xbe,0xad,0xde]
|
Loading…
Reference in New Issue