From: Dmitry Preobrazhensky Date: Wed, 26 Apr 2017 17:55:50 +0000 (+0000) Subject: [AMDGPU][MC] Added arg checks for vmcnt, expcnt, lgkmcnt helpers X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=559cd481444795822c9792dc98faf17d5a5e7068;p=llvm [AMDGPU][MC] Added arg checks for vmcnt, expcnt, lgkmcnt helpers Summary of changes: - corrected vmcnt, expcnt, lgkmcnt helpers to checks their argument for truncation; - added saturated versions of these helpers. See bug 32711 for details: https://bugs.llvm.org//show_bug.cgi?id=32711 Reviewers: artem.tamazov, vpykhtin Differential Revision: https://reviews.llvm.org/D32546 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301439 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index b88ffa06f7c..70c848f3c7b 100644 --- a/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -2838,6 +2838,28 @@ void AMDGPUAsmParser::cvtExp(MCInst &Inst, const OperandVector &Operands) { // s_waitcnt //===----------------------------------------------------------------------===// +static bool +encodeCnt( + const AMDGPU::IsaInfo::IsaVersion ISA, + int64_t &IntVal, + int64_t CntVal, + bool Saturate, + unsigned (*encode)(const IsaInfo::IsaVersion &Version, unsigned, unsigned), + unsigned (*decode)(const IsaInfo::IsaVersion &Version, unsigned)) +{ + bool Failed = false; + + IntVal = encode(ISA, IntVal, CntVal); + if (CntVal != decode(ISA, IntVal)) { + if (Saturate) { + IntVal = encode(ISA, IntVal, -1); + } else { + Failed = true; + } + } + return Failed; +} + bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) { StringRef CntName = Parser.getTok().getString(); int64_t CntVal; @@ -2853,25 +2875,35 @@ bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) { if (getParser().parseAbsoluteExpression(CntVal)) return true; - if (getLexer().isNot(AsmToken::RParen)) - return true; - - Parser.Lex(); - if (getLexer().is(AsmToken::Amp) || getLexer().is(AsmToken::Comma)) - Parser.Lex(); - AMDGPU::IsaInfo::IsaVersion ISA = AMDGPU::IsaInfo::getIsaVersion(getFeatureBits()); - if (CntName == "vmcnt") - IntVal = encodeVmcnt(ISA, IntVal, CntVal); - else if (CntName == "expcnt") - IntVal = encodeExpcnt(ISA, IntVal, CntVal); - else if (CntName == "lgkmcnt") - IntVal = encodeLgkmcnt(ISA, IntVal, CntVal); - else - return true; - return false; + bool Failed = true; + bool Sat = CntName.endswith("_sat"); + + if (CntName == "vmcnt" || CntName == "vmcnt_sat") { + Failed = encodeCnt(ISA, IntVal, CntVal, Sat, encodeVmcnt, decodeVmcnt); + } else if (CntName == "expcnt" || CntName == "expcnt_sat") { + Failed = encodeCnt(ISA, IntVal, CntVal, Sat, encodeExpcnt, decodeExpcnt); + } else if (CntName == "lgkmcnt" || CntName == "lgkmcnt_sat") { + Failed = encodeCnt(ISA, IntVal, CntVal, Sat, encodeLgkmcnt, decodeLgkmcnt); + } + + // To improve diagnostics, do not skip delimiters on errors + if (!Failed) { + if (getLexer().isNot(AsmToken::RParen)) { + return true; + } + Parser.Lex(); + if (getLexer().is(AsmToken::Amp) || getLexer().is(AsmToken::Comma)) { + const AsmToken NextToken = getLexer().peekTok(); + if (NextToken.is(AsmToken::Identifier)) { + Parser.Lex(); + } + } + } + + return Failed; } OperandMatchResultTy diff --git a/test/MC/AMDGPU/sopp-err.s b/test/MC/AMDGPU/sopp-err.s index da6bfbd16f4..fac0d322290 100644 --- a/test/MC/AMDGPU/sopp-err.s +++ b/test/MC/AMDGPU/sopp-err.s @@ -73,3 +73,21 @@ s_sendmsg sendmsg(MSG_SYSMSG, 0) s_sendmsg sendmsg(MSG_SYSMSG, 5) // GCN: error: invalid/unsupported code of SYSMSG_OP + +s_waitcnt lgkmcnt(16) +// GCN: error: failed parsing operand + +s_waitcnt expcnt(8) +// GCN: error: failed parsing operand + +s_waitcnt vmcnt(16) +// GCN: error: failed parsing operand + +s_waitcnt vmcnt(0xFFFFFFFFFFFF0000) +// GCN: error: failed parsing operand + +s_waitcnt vmcnt(0), expcnt(0), lgkmcnt(0), +// GCN: error: failed parsing operand + +s_waitcnt vmcnt(0) & expcnt(0) & lgkmcnt(0)& +// GCN: error: failed parsing operand diff --git a/test/MC/AMDGPU/sopp.s b/test/MC/AMDGPU/sopp.s index 140e26a9f60..f68b8227d76 100644 --- a/test/MC/AMDGPU/sopp.s +++ b/test/MC/AMDGPU/sopp.s @@ -80,18 +80,56 @@ s_waitcnt vmcnt(1) s_waitcnt vmcnt(9) // GCN: s_waitcnt vmcnt(9) ; encoding: [0x79,0x0f,0x8c,0xbf] +s_waitcnt vmcnt(15) +// GCN: s_waitcnt ; encoding: [0x7f,0x0f,0x8c,0xbf] + +s_waitcnt vmcnt_sat(9) +// GCN: s_waitcnt vmcnt(9) ; encoding: [0x79,0x0f,0x8c,0xbf] + +s_waitcnt vmcnt_sat(15) +// GCN: s_waitcnt ; encoding: [0x7f,0x0f,0x8c,0xbf] + +s_waitcnt vmcnt_sat(16) +// GCN: s_waitcnt ; encoding: [0x7f,0x0f,0x8c,0xbf] + s_waitcnt expcnt(2) // GCN: s_waitcnt expcnt(2) ; encoding: [0x2f,0x0f,0x8c,0xbf] +s_waitcnt expcnt(7) +// GCN: s_waitcnt ; encoding: [0x7f,0x0f,0x8c,0xbf] + +s_waitcnt expcnt_sat(2) +// GCN: s_waitcnt expcnt(2) ; encoding: [0x2f,0x0f,0x8c,0xbf] + +s_waitcnt expcnt_sat(7) +// GCN: s_waitcnt ; encoding: [0x7f,0x0f,0x8c,0xbf] + +s_waitcnt expcnt_sat(0xFFFF0000) +// GCN: s_waitcnt ; encoding: [0x7f,0x0f,0x8c,0xbf] + s_waitcnt lgkmcnt(3) // GCN: s_waitcnt lgkmcnt(3) ; encoding: [0x7f,0x03,0x8c,0xbf] s_waitcnt lgkmcnt(9) // GCN: s_waitcnt lgkmcnt(9) ; encoding: [0x7f,0x09,0x8c,0xbf] +s_waitcnt lgkmcnt(15) +// GCN: s_waitcnt ; encoding: [0x7f,0x0f,0x8c,0xbf] + s_waitcnt vmcnt(0), expcnt(0) // GCN: s_waitcnt vmcnt(0) expcnt(0) ; encoding: [0x00,0x0f,0x8c,0xbf] +s_waitcnt lgkmcnt_sat(3) +// GCN: s_waitcnt lgkmcnt(3) ; encoding: [0x7f,0x03,0x8c,0xbf] + +s_waitcnt lgkmcnt_sat(9) +// GCN: s_waitcnt lgkmcnt(9) ; encoding: [0x7f,0x09,0x8c,0xbf] + +s_waitcnt lgkmcnt_sat(15) +// GCN: s_waitcnt ; encoding: [0x7f,0x0f,0x8c,0xbf] + +s_waitcnt lgkmcnt_sat(16) +// GCN: s_waitcnt ; encoding: [0x7f,0x0f,0x8c,0xbf] s_sethalt 9 // GCN: s_sethalt 9 ; encoding: [0x09,0x00,0x8d,0xbf]