Skip to content

Commit

Permalink
[AArch64][SVE] Asm: Report SVE parsing diagnostics only once
Browse files Browse the repository at this point in the history
Summary:
Prevent an issue where a diagnostic is reported multiple times by bailing out with a ParseFail if an invalid SVE register element qualifier/suffix is specified, for example:

 <stdin>:10:18: error: invalid sve vector kind qualifier
 add z20.h, z2.h, z31.x
                 ^
 <stdin>:10:18: error: invalid sve vector kind qualifier
 add z20.h, z2.h, z31.x
 
 ...
 
 <stdin>:10:18: error: invalid sve vector kind qualifier
 add z20.h, z2.h, z31.x
                 ^


Reviewers: fhahn, rengolin

Reviewed By: rengolin

Subscribers: aemerson, javed.absar, tschuett, llvm-commits, kristof.beyls

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

llvm-svn: 318297
  • Loading branch information
sdesmalen-arm committed Nov 15, 2017
1 parent cd729ea commit 8e60734
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 25 deletions.
61 changes: 36 additions & 25 deletions llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ class AArch64AsmParser : public MCTargetAsmParser {
unsigned matchRegisterNameAlias(StringRef Name, RegKind Kind);
int tryParseRegister();
int tryMatchVectorRegister(StringRef &Kind, bool expected);
int tryParseSVEDataVectorRegister(const AsmToken &Tok, StringRef &Kind);
bool parseRegister(OperandVector &Operands);
bool parseSymbolicImmVal(const MCExpr *&ImmVal);
bool parseVectorList(OperandVector &Operands);
Expand Down Expand Up @@ -117,6 +116,8 @@ class AArch64AsmParser : public MCTargetAsmParser {

/// }

OperandMatchResultTy tryParseSVERegister(int &Reg, StringRef &Kind,
RegKind MatchKind);
OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands);
OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands);
OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands);
Expand Down Expand Up @@ -2708,30 +2709,37 @@ bool AArch64AsmParser::tryParseNeonVectorRegister(OperandVector &Operands) {
// tryParseSVEDataVectorRegister - Try to parse a SVE vector register name with
// optional kind specifier. If it is a register specifier, eat the token
// and return it.
int AArch64AsmParser::tryParseSVEDataVectorRegister(const AsmToken &Tok,
StringRef &Kind) {
OperandMatchResultTy
AArch64AsmParser::tryParseSVERegister(int &Reg, StringRef &Kind,
RegKind MatchKind) {
MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();

if (Tok.isNot(AsmToken::Identifier))
return -1;
return MatchOperand_NoMatch;

StringRef Name = Tok.getString();
// If there is a kind specifier, it's separated from the register name by
// a '.'.
size_t Start = 0, Next = Name.find('.');
StringRef Head = Name.slice(Start, Next);
unsigned RegNum = matchRegisterNameAlias(Head, RegKind::SVEDataVector);
unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);

if (RegNum) {
if (Next != StringRef::npos) {
Kind = Name.slice(Next, StringRef::npos);
if (!isValidSVEKind(Kind)) {
TokError("invalid sve vector kind qualifier");
return -1;
return MatchOperand_ParseFail;
}
}
return RegNum;
Parser.Lex(); // Eat the register token.

Reg = RegNum;
return MatchOperand_Success;
}

return -1;
return MatchOperand_NoMatch;
}

/// parseRegister - Parse a non-vector register operand.
Expand Down Expand Up @@ -4291,37 +4299,40 @@ bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
MCAsmParser &Parser = getParser();
Parser.Lex(); // Eat the '.req' token.
SMLoc SRegLoc = getLoc();
unsigned RegNum = tryParseRegister();
int RegNum = tryParseRegister();
RegKind RegisterKind = RegKind::Scalar;

if (RegNum == static_cast<unsigned>(-1)) {
if (RegNum == -1) {
StringRef Kind;
RegisterKind = RegKind::NeonVector;
RegNum = tryMatchVectorRegister(Kind, false);
if (!Kind.empty())
return Error(SRegLoc, "vector register without type specifier expected");
}

if (RegNum == static_cast<unsigned>(-1)) {
if (RegNum == -1) {
StringRef Kind;
RegisterKind = RegKind::SVEDataVector;
int RegNumTmp = tryParseSVEDataVectorRegister(Parser.getTok(), Kind);
if (RegNumTmp != -1)
Parser.Lex();
RegNum = RegNumTmp;
if (!Kind.empty())
return Error(SRegLoc, "sve vector register without type specifier expected");
OperandMatchResultTy Res =
tryParseSVERegister(RegNum, Kind, RegKind::SVEDataVector);

if (Res == MatchOperand_ParseFail)
return true;

if (Res == MatchOperand_Success && !Kind.empty())
return Error(SRegLoc,
"sve vector register without type specifier expected");
}

if (RegNum == static_cast<unsigned>(-1))
if (RegNum == -1)
return Error(SRegLoc, "register name or alias expected");

// Shouldn't be anything else.
if (parseToken(AsmToken::EndOfStatement,
"unexpected input in .req directive"))
return true;

auto pair = std::make_pair(RegisterKind, RegNum);
auto pair = std::make_pair(RegisterKind, (unsigned) RegNum);
if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
Warning(L, "ignoring redefinition of register alias '" + Name + "'");

Expand Down Expand Up @@ -4542,16 +4553,16 @@ AArch64AsmParser::tryParseGPRSeqPair(OperandVector &Operands) {
template <bool ParseSuffix>
OperandMatchResultTy
AArch64AsmParser::tryParseSVEDataVector(OperandVector &Operands) {
MCAsmParser &Parser = getParser();
const SMLoc S = getLoc();
// Check for a SVE vector register specifier first.
int RegNum = -1;
StringRef Kind;
int RegNum = tryParseSVEDataVectorRegister(Parser.getTok(), Kind);
if (RegNum == -1)
return MatchOperand_NoMatch;

// Eat the SVE Register Token
Parser.Lex();
OperandMatchResultTy Res =
tryParseSVERegister(RegNum, Kind, RegKind::SVEDataVector);

if (Res != MatchOperand_Success)
return Res;

if (ParseSuffix && Kind.empty())
return MatchOperand_NoMatch;
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/MC/AArch64/SVE/add-diagnostics.s
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
add z22.h, z10.h, z32.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: add z22.h, z10.h, z32.h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

// Invalid element kind.
add z20.h, z2.h, z31.x
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid sve vector kind qualifier
// CHECK-NEXT: add z20.h, z2.h, z31.x
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

// Element size specifiers should match.
add z27.h, z11.h, z27.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: add z27.h, z11.h, z27.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
3 changes: 3 additions & 0 deletions llvm/test/MC/AArch64/SVE/sub-diagnostics.s
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
sub z3.h, z26.h, z32.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: sub z3.h, z26.h, z32.h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

// Invalid element kind.
sub z4.h, z27.h, z31.x
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid sve vector kind qualifier
// CHECK-NEXT: sub z4.h, z27.h, z31.x
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

// Element size specifiers should match.
sub z0.h, z8.h, z8.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: sub z0.h, z8.h, z8.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

0 comments on commit 8e60734

Please sign in to comment.