Skip to content

Commit

Permalink
[AMDGPU][MC] Added check for truncation of SOPK imm operand
Browse files Browse the repository at this point in the history
See bug 30827: https://bugs.llvm.org//show_bug.cgi?id=30827

Reviewers: artem.tamazov, vpykhtin

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

llvm-svn: 301418
  • Loading branch information
dpreobra committed Apr 26, 2017
1 parent b435a5f commit c7d35a0
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 17 deletions.
16 changes: 16 additions & 0 deletions llvm/lib/Target/AMDGPU/AMDGPUInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ def UnsafeFPMath : Predicate<"TM.Options.UnsafeFPMath">;
def InstFlag : OperandWithDefaultOps <i32, (ops (i32 0))>;
def ADDRIndirect : ComplexPattern<iPTR, 2, "SelectADDRIndirect", [], []>;

def u16ImmTarget : AsmOperandClass {
let Name = "U16Imm";
let RenderMethod = "addImmOperands";
}

def s16ImmTarget : AsmOperandClass {
let Name = "S16Imm";
let RenderMethod = "addImmOperands";
}

let OperandType = "OPERAND_IMMEDIATE" in {

def u32imm : Operand<i32> {
Expand All @@ -58,6 +68,12 @@ def u32imm : Operand<i32> {

def u16imm : Operand<i16> {
let PrintMethod = "printU16ImmOperand";
let ParserMatchClass = u16ImmTarget;
}

def s16imm : Operand<i16> {
let PrintMethod = "printU16ImmOperand";
let ParserMatchClass = s16ImmTarget;
}

def u8imm : Operand<i8> {
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,8 @@ class AMDGPUOperand : public MCParsedAsmOperand {
bool isSMRDLiteralOffset() const;
bool isDPPCtrl() const;
bool isGPRIdxMode() const;
bool isS16Imm() const;
bool isU16Imm() const;

StringRef getExpressionAsToken() const {
assert(isExpr());
Expand Down Expand Up @@ -3858,6 +3860,14 @@ bool AMDGPUOperand::isGPRIdxMode() const {
return isImm() && isUInt<4>(getImm());
}

bool AMDGPUOperand::isS16Imm() const {
return isImm() && (isInt<16>(getImm()) || isUInt<16>(getImm()));
}

bool AMDGPUOperand::isU16Imm() const {
return isImm() && isUInt<16>(getImm());
}

OperandMatchResultTy
AMDGPUAsmParser::parseDPPCtrl(OperandVector &Operands) {
SMLoc S = Parser.getTok().getLoc();
Expand Down
36 changes: 19 additions & 17 deletions llvm/lib/Target/AMDGPU/SOPInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -530,14 +530,16 @@ class SOPKInstTable <bit is_sopk, string cmpOp = ""> {
class SOPK_32 <string opName, list<dag> pattern=[]> : SOPK_Pseudo <
opName,
(outs SReg_32:$sdst),
(ins u16imm:$simm16),
(ins s16imm:$simm16),
"$sdst, $simm16",
pattern>;

class SOPK_SCC <string opName, string base_op = ""> : SOPK_Pseudo <
class SOPK_SCC <string opName, string base_op, bit isSignExt> : SOPK_Pseudo <
opName,
(outs),
(ins SReg_32:$sdst, u16imm:$simm16),
!if(isSignExt,
(ins SReg_32:$sdst, s16imm:$simm16),
(ins SReg_32:$sdst, u16imm:$simm16)),
"$sdst, $simm16", []>,
SOPKInstTable<1, base_op>{
let Defs = [SCC];
Expand All @@ -546,7 +548,7 @@ class SOPK_SCC <string opName, string base_op = ""> : SOPK_Pseudo <
class SOPK_32TIE <string opName, list<dag> pattern=[]> : SOPK_Pseudo <
opName,
(outs SReg_32:$sdst),
(ins SReg_32:$src0, u16imm:$simm16),
(ins SReg_32:$src0, s16imm:$simm16),
"$sdst, $simm16",
pattern
>;
Expand Down Expand Up @@ -575,20 +577,20 @@ let isCompare = 1 in {
// [(set i1:$dst, (setcc i32:$src0, imm:$src1, SETEQ))]
// >;

def S_CMPK_EQ_I32 : SOPK_SCC <"s_cmpk_eq_i32", "s_cmp_eq_i32">;
def S_CMPK_LG_I32 : SOPK_SCC <"s_cmpk_lg_i32", "s_cmp_lg_i32">;
def S_CMPK_GT_I32 : SOPK_SCC <"s_cmpk_gt_i32", "s_cmp_gt_i32">;
def S_CMPK_GE_I32 : SOPK_SCC <"s_cmpk_ge_i32", "s_cmp_ge_i32">;
def S_CMPK_LT_I32 : SOPK_SCC <"s_cmpk_lt_i32", "s_cmp_lt_i32">;
def S_CMPK_LE_I32 : SOPK_SCC <"s_cmpk_le_i32", "s_cmp_le_i32">;
def S_CMPK_EQ_I32 : SOPK_SCC <"s_cmpk_eq_i32", "s_cmp_eq_i32", 1>;
def S_CMPK_LG_I32 : SOPK_SCC <"s_cmpk_lg_i32", "s_cmp_lg_i32", 1>;
def S_CMPK_GT_I32 : SOPK_SCC <"s_cmpk_gt_i32", "s_cmp_gt_i32", 1>;
def S_CMPK_GE_I32 : SOPK_SCC <"s_cmpk_ge_i32", "s_cmp_ge_i32", 1>;
def S_CMPK_LT_I32 : SOPK_SCC <"s_cmpk_lt_i32", "s_cmp_lt_i32", 1>;
def S_CMPK_LE_I32 : SOPK_SCC <"s_cmpk_le_i32", "s_cmp_le_i32", 1>;

let SOPKZext = 1 in {
def S_CMPK_EQ_U32 : SOPK_SCC <"s_cmpk_eq_u32", "s_cmp_eq_u32">;
def S_CMPK_LG_U32 : SOPK_SCC <"s_cmpk_lg_u32", "s_cmp_lg_u32">;
def S_CMPK_GT_U32 : SOPK_SCC <"s_cmpk_gt_u32", "s_cmp_gt_u32">;
def S_CMPK_GE_U32 : SOPK_SCC <"s_cmpk_ge_u32", "s_cmp_ge_u32">;
def S_CMPK_LT_U32 : SOPK_SCC <"s_cmpk_lt_u32", "s_cmp_lt_u32">;
def S_CMPK_LE_U32 : SOPK_SCC <"s_cmpk_le_u32", "s_cmp_le_u32">;
def S_CMPK_EQ_U32 : SOPK_SCC <"s_cmpk_eq_u32", "s_cmp_eq_u32", 0>;
def S_CMPK_LG_U32 : SOPK_SCC <"s_cmpk_lg_u32", "s_cmp_lg_u32", 0>;
def S_CMPK_GT_U32 : SOPK_SCC <"s_cmpk_gt_u32", "s_cmp_gt_u32", 0>;
def S_CMPK_GE_U32 : SOPK_SCC <"s_cmpk_ge_u32", "s_cmp_ge_u32", 0>;
def S_CMPK_LT_U32 : SOPK_SCC <"s_cmpk_lt_u32", "s_cmp_lt_u32", 0>;
def S_CMPK_LE_U32 : SOPK_SCC <"s_cmpk_le_u32", "s_cmp_le_u32", 0>;
} // End SOPKZext = 1
} // End isCompare = 1

Expand All @@ -600,7 +602,7 @@ let Defs = [SCC], isCommutable = 1, DisableEncoding = "$src0",

def S_CBRANCH_I_FORK : SOPK_Pseudo <
"s_cbranch_i_fork",
(outs), (ins SReg_64:$sdst, u16imm:$simm16),
(outs), (ins SReg_64:$sdst, s16imm:$simm16),
"$sdst, $simm16"
>;

Expand Down
15 changes: 15 additions & 0 deletions llvm/test/MC/AMDGPU/sopk-err.s
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,18 @@ s_setreg_imm32_b32 hwreg(3,0,33), 0xff

s_getreg_b32 s2, hwreg(3,32,32)
// GCN: error: invalid bit offset: only 5-bit values are legal

s_cmpk_le_u32 s2, -1
// GCN: error: invalid operand for instruction

s_cmpk_le_u32 s2, 0x1ffff
// GCN: error: invalid operand for instruction

s_cmpk_le_u32 s2, 0x10000
// GCN: error: invalid operand for instruction

s_mulk_i32 s2, 0xFFFFFFFFFFFF0000
// GCN: error: invalid operand for instruction

s_mulk_i32 s2, 0x10000
// GCN: error: invalid operand for instruction
12 changes: 12 additions & 0 deletions llvm/test/MC/AMDGPU/sopk.s
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ s_cmpk_le_u32 s2, 0x6
// SICI: s_cmpk_le_u32 s2, 0x6 ; encoding: [0x06,0x00,0x02,0xb7]
// VI: s_cmpk_le_u32 s2, 0x6 ; encoding: [0x06,0x00,0x82,0xb6]

s_cmpk_le_u32 s2, 0xFFFF
// SICI: s_cmpk_le_u32 s2, 0xffff ; encoding: [0xff,0xff,0x02,0xb7]
// VI: s_cmpk_le_u32 s2, 0xffff ; encoding: [0xff,0xff,0x82,0xb6]

s_addk_i32 s2, 0x6
// SICI: s_addk_i32 s2, 0x6 ; encoding: [0x06,0x00,0x82,0xb7]
// VI: s_addk_i32 s2, 0x6 ; encoding: [0x06,0x00,0x02,0xb7]
Expand All @@ -69,6 +73,14 @@ s_mulk_i32 s2, 0x6
// SICI: s_mulk_i32 s2, 0x6 ; encoding: [0x06,0x00,0x02,0xb8]
// VI: s_mulk_i32 s2, 0x6 ; encoding: [0x06,0x00,0x82,0xb7]

s_mulk_i32 s2, -1
// SICI: s_mulk_i32 s2, 0xffff ; encoding: [0xff,0xff,0x02,0xb8]
// VI: s_mulk_i32 s2, 0xffff ; encoding: [0xff,0xff,0x82,0xb7]

s_mulk_i32 s2, 0xFFFF
// SICI: s_mulk_i32 s2, 0xffff ; encoding: [0xff,0xff,0x02,0xb8]
// VI: s_mulk_i32 s2, 0xffff ; encoding: [0xff,0xff,0x82,0xb7]

s_cbranch_i_fork s[2:3], 0x6
// SICI: s_cbranch_i_fork s[2:3], 0x6 ; encoding: [0x06,0x00,0x82,0xb8]
// VI: s_cbranch_i_fork s[2:3], 0x6 ; encoding: [0x06,0x00,0x02,0xb8]
Expand Down

0 comments on commit c7d35a0

Please sign in to comment.