[llvm] r358581 - [AMDGPU][MC] Corrected parsing of registers
Dmitry Preobrazhensky via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 17 07:44:02 PDT 2019
Author: dpreobra
Date: Wed Apr 17 07:44:01 2019
New Revision: 358581
URL: http://llvm.org/viewvc/llvm-project?rev=358581&view=rev
Log:
[AMDGPU][MC] Corrected parsing of registers
See bug 41280: https://bugs.llvm.org/show_bug.cgi?id=41280
Reviewers: artem.tamazov, arsenm
Differential Revision: https://reviews.llvm.org/D60621
Added:
llvm/trunk/test/MC/AMDGPU/reg-syntax-err.s
Modified:
llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
llvm/trunk/test/MC/AMDGPU/sop1-err.s
Modified: llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp?rev=358581&r1=358580&r2=358581&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp Wed Apr 17 07:44:01 2019
@@ -908,6 +908,8 @@ private:
bool ParseAMDGPURegister(RegisterKind& RegKind, unsigned& Reg,
unsigned& RegNum, unsigned& RegWidth,
unsigned *DwordRegIndex);
+ bool isRegister();
+ bool isRegister(const AsmToken &Token, const AsmToken &NextToken) const;
Optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
void initializeGprCountSymbol(RegisterKind RegKind);
bool updateGprCountSymbols(RegisterKind RegKind, unsigned DwordRegIndex,
@@ -1125,11 +1127,19 @@ private:
bool isInlineConstant(const MCInst &Inst, unsigned OpIdx) const;
unsigned findImplicitSGPRReadInVOP(const MCInst &Inst) const;
+ bool isId(const StringRef Id) const;
+ bool isId(const AsmToken &Token, const StringRef Id) const;
+ bool isToken(const AsmToken::TokenKind Kind) const;
bool trySkipId(const StringRef Id);
bool trySkipToken(const AsmToken::TokenKind Kind);
bool skipToken(const AsmToken::TokenKind Kind, const StringRef ErrMsg);
bool parseString(StringRef &Val, const StringRef ErrMsg = "expected a string");
+ AsmToken::TokenKind getTokenKind() const;
bool parseExpr(int64_t &Imm);
+ AsmToken peekToken();
+ AsmToken getToken() const;
+ SMLoc getLoc() const;
+ void lex();
public:
OperandMatchResultTy parseOptionalOperand(OperandVector &Operands);
@@ -1748,6 +1758,51 @@ bool AMDGPUAsmParser::AddNextRegisterToL
}
}
+static const StringRef Registers[] = {
+ { "v" },
+ { "s" },
+ { "ttmp" },
+};
+
+bool
+AMDGPUAsmParser::isRegister(const AsmToken &Token,
+ const AsmToken &NextToken) const {
+
+ // A list of consecutive registers: [s0,s1,s2,s3]
+ if (Token.is(AsmToken::LBrac))
+ return true;
+
+ if (!Token.is(AsmToken::Identifier))
+ return false;
+
+ // A single register like s0 or a range of registers like s[0:1]
+
+ StringRef RegName = Token.getString();
+
+ for (StringRef Reg : Registers) {
+ if (RegName.startswith(Reg)) {
+ if (Reg.size() < RegName.size()) {
+ unsigned RegNum;
+ // A single register with an index: rXX
+ if (!RegName.substr(Reg.size()).getAsInteger(10, RegNum))
+ return true;
+ } else {
+ // A range of registers: r[XX:YY].
+ if (NextToken.is(AsmToken::LBrac))
+ return true;
+ }
+ }
+ }
+
+ return getSpecialRegForName(RegName);
+}
+
+bool
+AMDGPUAsmParser::isRegister()
+{
+ return isRegister(getToken(), peekToken());
+}
+
bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind, unsigned &Reg,
unsigned &RegNum, unsigned &RegWidth,
unsigned *DwordRegIndex) {
@@ -1933,6 +1988,8 @@ std::unique_ptr<AMDGPUOperand> AMDGPUAsm
unsigned Reg, RegNum, RegWidth, DwordRegIndex;
if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth, &DwordRegIndex)) {
+ //FIXME: improve error messages (bug 41303).
+ Error(StartLoc, "not a valid operand.");
return nullptr;
}
if (AMDGPU::IsaInfo::hasCodeObjectV3(&getSTI())) {
@@ -2012,23 +2069,24 @@ AMDGPUAsmParser::parseImm(OperandVector
OperandMatchResultTy
AMDGPUAsmParser::parseReg(OperandVector &Operands) {
+ if (!isRegister())
+ return MatchOperand_NoMatch;
+
if (auto R = parseRegister()) {
assert(R->isReg());
R->Reg.IsForcedVOP3 = isForcedVOP3();
Operands.push_back(std::move(R));
return MatchOperand_Success;
}
- return MatchOperand_NoMatch;
+ return MatchOperand_ParseFail;
}
OperandMatchResultTy
AMDGPUAsmParser::parseRegOrImm(OperandVector &Operands, bool AbsMod) {
- auto res = parseImm(Operands, AbsMod);
- if (res != MatchOperand_NoMatch) {
- return res;
- }
-
- return parseReg(Operands);
+ auto res = parseReg(Operands);
+ return (res == MatchOperand_NoMatch)?
+ parseImm(Operands, AbsMod) :
+ res;
}
OperandMatchResultTy
@@ -2195,21 +2253,24 @@ AMDGPUAsmParser::parseRegWithIntInputMod
}
OperandMatchResultTy AMDGPUAsmParser::parseVReg32OrOff(OperandVector &Operands) {
+ auto Loc = getLoc();
+ if (trySkipId("off")) {
+ Operands.push_back(AMDGPUOperand::CreateImm(this, 0, Loc,
+ AMDGPUOperand::ImmTyOff, false));
+ return MatchOperand_Success;
+ }
+
+ if (!isRegister())
+ return MatchOperand_NoMatch;
+
std::unique_ptr<AMDGPUOperand> Reg = parseRegister();
if (Reg) {
Operands.push_back(std::move(Reg));
return MatchOperand_Success;
}
- const AsmToken &Tok = Parser.getTok();
- if (Tok.getString() == "off") {
- Operands.push_back(AMDGPUOperand::CreateImm(this, 0, Tok.getLoc(),
- AMDGPUOperand::ImmTyOff, false));
- Parser.Lex();
- return MatchOperand_Success;
- }
+ return MatchOperand_ParseFail;
- return MatchOperand_NoMatch;
}
unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
@@ -3520,7 +3581,7 @@ AMDGPUAsmParser::parseOperand(OperandVec
ResTy = parseRegOrImm(Operands);
- if (ResTy == MatchOperand_Success)
+ if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
return ResTy;
const auto &Tok = Parser.getTok();
@@ -4492,10 +4553,24 @@ bool AMDGPUOperand::isSendMsg() const {
//===----------------------------------------------------------------------===//
bool
+AMDGPUAsmParser::isId(const AsmToken &Token, const StringRef Id) const {
+ return Token.is(AsmToken::Identifier) && Token.getString() == Id;
+}
+
+bool
+AMDGPUAsmParser::isId(const StringRef Id) const {
+ return isId(getToken(), Id);
+}
+
+bool
+AMDGPUAsmParser::isToken(const AsmToken::TokenKind Kind) const {
+ return getTokenKind() == Kind;
+}
+
+bool
AMDGPUAsmParser::trySkipId(const StringRef Id) {
- if (getLexer().getKind() == AsmToken::Identifier &&
- Parser.getTok().getString() == Id) {
- Parser.Lex();
+ if (isId(Id)) {
+ lex();
return true;
}
return false;
@@ -4503,8 +4578,8 @@ AMDGPUAsmParser::trySkipId(const StringR
bool
AMDGPUAsmParser::trySkipToken(const AsmToken::TokenKind Kind) {
- if (getLexer().getKind() == Kind) {
- Parser.Lex();
+ if (isToken(Kind)) {
+ lex();
return true;
}
return false;
@@ -4514,7 +4589,7 @@ bool
AMDGPUAsmParser::skipToken(const AsmToken::TokenKind Kind,
const StringRef ErrMsg) {
if (!trySkipToken(Kind)) {
- Error(Parser.getTok().getLoc(), ErrMsg);
+ Error(getLoc(), ErrMsg);
return false;
}
return true;
@@ -4527,17 +4602,41 @@ AMDGPUAsmParser::parseExpr(int64_t &Imm)
bool
AMDGPUAsmParser::parseString(StringRef &Val, const StringRef ErrMsg) {
- SMLoc S = Parser.getTok().getLoc();
- if (getLexer().getKind() == AsmToken::String) {
- Val = Parser.getTok().getStringContents();
- Parser.Lex();
+ if (isToken(AsmToken::String)) {
+ Val = getToken().getStringContents();
+ lex();
return true;
} else {
- Error(S, ErrMsg);
+ Error(getLoc(), ErrMsg);
return false;
}
}
+AsmToken
+AMDGPUAsmParser::getToken() const {
+ return Parser.getTok();
+}
+
+AsmToken
+AMDGPUAsmParser::peekToken() {
+ return getLexer().peekTok();
+}
+
+AsmToken::TokenKind
+AMDGPUAsmParser::getTokenKind() const {
+ return getLexer().getKind();
+}
+
+SMLoc
+AMDGPUAsmParser::getLoc() const {
+ return getToken().getLoc();
+}
+
+void
+AMDGPUAsmParser::lex() {
+ Parser.Lex();
+}
+
//===----------------------------------------------------------------------===//
// swizzle
//===----------------------------------------------------------------------===//
Added: llvm/trunk/test/MC/AMDGPU/reg-syntax-err.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/reg-syntax-err.s?rev=358581&view=auto
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/reg-syntax-err.s (added)
+++ llvm/trunk/test/MC/AMDGPU/reg-syntax-err.s Wed Apr 17 07:44:01 2019
@@ -0,0 +1,64 @@
+// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga %s 2>&1 | FileCheck -check-prefix=NOVI %s
+
+s_mov_b32 s1, s 1
+// NOVI: error: invalid operand for instruction
+
+s_mov_b32 s1, s[0 1
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, s[0:0 1
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, [s[0 1
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, [s[0:1] 1
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, [s0, 1
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, s999 1
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, s[1:2] 1
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, s[0:2] 1
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, xnack_mask_lo 1
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, s s0
+// NOVI: error: invalid operand for instruction
+
+s_mov_b32 s1, s[0 s0
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, s[0:0 s0
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, [s[0 s0
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, [s[0:1] s0
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, [s0, s0
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, s999 s0
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, s[1:2] s0
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, s[0:2] vcc_lo
+// NOVI: error: failed parsing operand
+
+s_mov_b32 s1, xnack_mask_lo s1
+// NOVI: error: failed parsing operand
+
+exp mrt0 v1, v2, v3, v4000 off
+// NOVI: error: failed parsing operand
Modified: llvm/trunk/test/MC/AMDGPU/sop1-err.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/sop1-err.s?rev=358581&r1=358580&r2=358581&view=diff
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/sop1-err.s (original)
+++ llvm/trunk/test/MC/AMDGPU/sop1-err.s Wed Apr 17 07:44:01 2019
@@ -28,7 +28,7 @@ s_mov_b64 s[0:1], s1
// FIXME: This shoudl probably say failed to parse.
s_mov_b32 s
-// GCN: error: not a valid operand
+// GCN: error: invalid operand for instruction
// Out of range register
s_mov_b32 s102, 1
More information about the llvm-commits
mailing list