forked from OSchip/llvm-project
[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:
parent
47e9a21d34
commit
61105bab29
|
@ -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)");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
Loading…
Reference in New Issue