[AMDGPU][MC] Disabled use of 2 different literals with SOP2/SOPC instructions

See bug 39319: https://bugs.llvm.org/show_bug.cgi?id=39319

Reviewers: artem.tamazov, arsenm, rampitec

Differential Revision: https://reviews.llvm.org/D56847

llvm-svn: 351549
This commit is contained in:
Dmitry Preobrazhensky 2019-01-18 13:57:43 +00:00
parent 47e9a21d34
commit 61105bab29
6 changed files with 71 additions and 0 deletions

View File

@ -1084,6 +1084,7 @@ private:
OperandMatchResultTy parseExpTgtImpl(StringRef Str, uint8_t &Val);
bool validateInstruction(const MCInst &Inst, const SMLoc &IDLoc);
bool validateSOPLiteral(const MCInst &Inst) const;
bool validateConstantBusLimitations(const MCInst &Inst);
bool validateEarlyClobberLimitations(const MCInst &Inst);
bool validateIntClampSupported(const MCInst &Inst);
@ -2461,8 +2462,46 @@ bool AMDGPUAsmParser::validateMIMGD16(const MCInst &Inst) {
return true;
}
bool AMDGPUAsmParser::validateSOPLiteral(const MCInst &Inst) const {
unsigned Opcode = Inst.getOpcode();
const MCInstrDesc &Desc = MII.get(Opcode);
if (!(Desc.TSFlags & (SIInstrFlags::SOP2 | SIInstrFlags::SOPC)))
return true;
const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
const int OpIndices[] = { Src0Idx, Src1Idx };
unsigned NumLiterals = 0;
uint32_t LiteralValue;
for (int OpIdx : OpIndices) {
if (OpIdx == -1) break;
const MCOperand &MO = Inst.getOperand(OpIdx);
if (MO.isImm() &&
// Exclude special imm operands (like that used by s_set_gpr_idx_on)
AMDGPU::isSISrcOperand(Desc, OpIdx) &&
!isInlineConstant(Inst, OpIdx)) {
uint32_t Value = static_cast<uint32_t>(MO.getImm());
if (NumLiterals == 0 || LiteralValue != Value) {
LiteralValue = Value;
++NumLiterals;
}
}
}
return NumLiterals <= 1;
}
bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst,
const SMLoc &IDLoc) {
if (!validateSOPLiteral(Inst)) {
Error(IDLoc,
"only one literal operand is allowed");
return false;
}
if (!validateConstantBusLimitations(Inst)) {
Error(IDLoc,
"invalid operand (violates constant bus restrictions)");

View File

@ -302,6 +302,8 @@ class SOP2_Real<bits<7> op, SOP_Pseudo ps> :
// copy relevant pseudo op flags
let SubtargetPredicate = ps.SubtargetPredicate;
let AsmMatchConverter = ps.AsmMatchConverter;
let UseNamedOperandTable = ps.UseNamedOperandTable;
let TSFlags = ps.TSFlags;
// encoding
bits<7> sdst;

View File

@ -5,3 +5,9 @@ s_cbranch_g_fork 100, s[6:7]
s_cbranch_g_fork s[6:7], 100
// GCN: error: invalid operand for instruction
s_and_b32 s2, 0x12345678, 0x12345679
// GCN: error: only one literal operand is allowed
s_and_b64 s[2:3], 0x12345678, 0x12345679
// GCN: error: only one literal operand is allowed

View File

@ -50,6 +50,14 @@ s_and_b32 s2, s4, s6
// SICI: s_and_b32 s2, s4, s6 ; encoding: [0x04,0x06,0x02,0x87]
// GFX89: s_and_b32 s2, s4, s6 ; encoding: [0x04,0x06,0x02,0x86]
s_and_b32 s2, 1234, 1234
// SICI: s_and_b32 s2, 0x4d2, 0x4d2 ; encoding: [0xff,0xff,0x02,0x87,0xd2,0x04,0x00,0x00]
// GFX89: s_and_b32 s2, 0x4d2, 0x4d2 ; encoding: [0xff,0xff,0x02,0x86,0xd2,0x04,0x00,0x00]
s_and_b32 s2, 0xFFFF0000, -65536
// SICI: s_and_b32 s2, 0xffff0000, 0xffff0000 ; encoding: [0xff,0xff,0x02,0x87,0x00,0x00,0xff,0xff]
// GFX89: s_and_b32 s2, 0xffff0000, 0xffff0000 ; encoding: [0xff,0xff,0x02,0x86,0x00,0x00,0xff,0xff]
s_and_b64 s[2:3], s[4:5], s[6:7]
// SICI: s_and_b64 s[2:3], s[4:5], s[6:7] ; encoding: [0x04,0x06,0x82,0x87]
// GFX89: s_and_b64 s[2:3], s[4:5], s[6:7] ; encoding: [0x04,0x06,0x82,0x86]
@ -134,6 +142,10 @@ s_ashr_i64 s[2:3], s[4:5], s6
// SICI: s_ashr_i64 s[2:3], s[4:5], s6 ; encoding: [0x04,0x06,0x82,0x91]
// GFX89: s_ashr_i64 s[2:3], s[4:5], s6 ; encoding: [0x04,0x06,0x82,0x90]
s_ashr_i64 s[2:3], -65536, 0xFFFF0000
// SICI: s_ashr_i64 s[2:3], 0xffff0000, 0xffff0000 ; encoding: [0xff,0xff,0x82,0x91,0x00,0x00,0xff,0xff]
// GFX89: s_ashr_i64 s[2:3], 0xffff0000, 0xffff0000 ; encoding: [0xff,0xff,0x82,0x90,0x00,0x00,0xff,0xff]
s_bfm_b32 s2, s4, s6
// SICI: s_bfm_b32 s2, s4, s6 ; encoding: [0x04,0x06,0x02,0x92]
// GFX89: s_bfm_b32 s2, s4, s6 ; encoding: [0x04,0x06,0x02,0x91]

View File

@ -8,3 +8,9 @@ s_set_gpr_idx_on s0, 16
s_set_gpr_idx_on s0, -1
// GCN: error: invalid operand for instruction
s_cmp_eq_i32 0x12345678, 0x12345679
// GCN: error: only one literal operand is allowed
s_cmp_eq_u64 0x12345678, 0x12345679
// GCN: error: only one literal operand is allowed

View File

@ -9,6 +9,12 @@
s_cmp_eq_i32 s1, s2
// GCN: s_cmp_eq_i32 s1, s2 ; encoding: [0x01,0x02,0x00,0xbf]
s_cmp_eq_i32 0xabcd1234, 0xabcd1234
// GCN: s_cmp_eq_i32 0xabcd1234, 0xabcd1234 ; encoding: [0xff,0xff,0x00,0xbf,0x34,0x12,0xcd,0xab]
s_cmp_eq_i32 0xFFFF0000, -65536
// GCN: s_cmp_eq_i32 0xffff0000, 0xffff0000 ; encoding: [0xff,0xff,0x00,0xbf,0x00,0x00,0xff,0xff]
s_cmp_lg_i32 s1, s2
// GCN: s_cmp_lg_i32 s1, s2 ; encoding: [0x01,0x02,0x01,0xbf]