[llvm] fd6cd1a - [RISCV] Refactor parseVTypeI and use ParseFail if we parsed more than one identifier.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed May 17 10:32:10 PDT 2023


Author: Craig Topper
Date: 2023-05-17T10:31:39-07:00
New Revision: fd6cd1a249136e93e73cc09c3408871255c5ae72

URL: https://github.com/llvm/llvm-project/commit/fd6cd1a249136e93e73cc09c3408871255c5ae72
DIFF: https://github.com/llvm/llvm-project/commit/fd6cd1a249136e93e73cc09c3408871255c5ae72.diff

LOG: [RISCV] Refactor parseVTypeI and use ParseFail if we parsed more than one identifier.

Previously we lexed into a SmallVector and unlexed the tokens if
the parsing failed.

This patch gets rid of the SmallVector and the unlexing.

If the first token fails to parse, return MatchFail. This allows us
to fallback to parsing as an immediate. If we successfully parsed the
first token, use ParseFail if any later tokens fail to parse. This
avoids needing to UnLex the tokens.

I've used a state machine to keep track of what component we've
parsed so far.

Reviewed By: asb

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

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/test/MC/RISCV/rvv/invalid.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 4c1bd2a6e6ff1..31d5e134b10ad 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -64,6 +64,18 @@ struct ParserOptionsSet {
 };
 
 class RISCVAsmParser : public MCTargetAsmParser {
+  // This tracks the parsing of the 4 operands that make up the vtype portion
+  // of vset(i)vli instructions which are separated by commas. The state names
+  // represent the next expected operand with Done meaning no other operands are
+  // expected.
+  enum VTypeState {
+    VTypeState_SEW,
+    VTypeState_LMUL,
+    VTypeState_TailPolicy,
+    VTypeState_MaskPolicy,
+    VTypeState_Done,
+  };
+
   SmallVector<FeatureBitset, 4> FeatureBitStack;
 
   SmallVector<ParserOptionsSet, 4> ParserOptionsStack;
@@ -105,6 +117,11 @@ class RISCVAsmParser : public MCTargetAsmParser {
 
   bool ParseDirective(AsmToken DirectiveID) override;
 
+  bool parseVTypeToken(StringRef Identifier, VTypeState &State, unsigned &Sew,
+                       unsigned &Lmul, bool &Fractional, bool &TailAgnostic,
+                       bool &MaskAgnostic);
+  bool generateVTypeError(SMLoc ErrorLoc);
+
   // Helper to actually emit an instruction to the MCStreamer. Also, when
   // possible, compression of the instruction is performed.
   void emitToStreamer(MCStreamer &S, const MCInst &Inst);
@@ -1471,10 +1488,7 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   }
   case Match_InvalidVTypeI: {
     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
-    return Error(
-        ErrorLoc,
-        "operand must be "
-        "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
+    return generateVTypeError(ErrorLoc);
   }
   case Match_InvalidVMaskRegister: {
     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
@@ -2037,69 +2051,96 @@ OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
   return parseImmediate(Operands);
 }
 
-OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
-  SMLoc S = getLoc();
-
-  SmallVector<AsmToken, 7> VTypeIElements;
-  // Put all the tokens for vtypei operand into VTypeIElements vector.
-  while (getLexer().isNot(AsmToken::EndOfStatement)) {
-    if (getLexer().isNot(AsmToken::Identifier))
-      goto MatchFail;
-    VTypeIElements.push_back(getLexer().getTok());
-    getLexer().Lex();
-    if (getLexer().is(AsmToken::EndOfStatement))
+bool RISCVAsmParser::parseVTypeToken(StringRef Identifier, VTypeState &State,
+                                     unsigned &Sew, unsigned &Lmul,
+                                     bool &Fractional, bool &TailAgnostic,
+                                     bool &MaskAgnostic) {
+  switch (State) {
+  case VTypeState_SEW:
+    if (!Identifier.consume_front("e"))
+      break;
+    if (Identifier.getAsInteger(10, Sew))
       break;
-    if (getLexer().isNot(AsmToken::Comma))
-      goto MatchFail;
-    AsmToken Comma = getLexer().getTok();
-    VTypeIElements.push_back(Comma);
-    getLexer().Lex();
-  }
-
-  if (VTypeIElements.size() == 7) {
-    // The VTypeIElements layout is:
-    // SEW comma LMUL comma TA comma MA
-    //  0    1    2     3    4   5    6
-    StringRef Name = VTypeIElements[0].getIdentifier();
-    if (!Name.consume_front("e"))
-      goto MatchFail;
-    unsigned Sew;
-    if (Name.getAsInteger(10, Sew))
-      goto MatchFail;
     if (!RISCVVType::isValidSEW(Sew))
-      goto MatchFail;
-
-    Name = VTypeIElements[2].getIdentifier();
-    if (!Name.consume_front("m"))
-      goto MatchFail;
-    // "m" or "mf"
-    bool Fractional = Name.consume_front("f");
-    unsigned Lmul;
-    if (Name.getAsInteger(10, Lmul))
-      goto MatchFail;
+      break;
+    State = VTypeState_LMUL;
+    return false;
+  case VTypeState_LMUL: {
+    if (!Identifier.consume_front("m"))
+      break;
+    Fractional = Identifier.consume_front("f");
+    if (Identifier.getAsInteger(10, Lmul))
+      break;
     if (!RISCVVType::isValidLMUL(Lmul, Fractional))
-      goto MatchFail;
-
-    // ta or tu
-    Name = VTypeIElements[4].getIdentifier();
-    bool TailAgnostic;
-    if (Name == "ta")
+      break;
+    State = VTypeState_TailPolicy;
+    return false;
+  }
+  case VTypeState_TailPolicy:
+    if (Identifier == "ta")
       TailAgnostic = true;
-    else if (Name == "tu")
+    else if (Identifier == "tu")
       TailAgnostic = false;
     else
-      goto MatchFail;
-
-    // ma or mu
-    Name = VTypeIElements[6].getIdentifier();
-    bool MaskAgnostic;
-    if (Name == "ma")
+      break;
+    State = VTypeState_MaskPolicy;
+    return false;
+  case VTypeState_MaskPolicy:
+    if (Identifier == "ma")
       MaskAgnostic = true;
-    else if (Name == "mu")
+    else if (Identifier == "mu")
       MaskAgnostic = false;
     else
-      goto MatchFail;
+      break;
+    State = VTypeState_Done;
+    return false;
+  case VTypeState_Done:
+    // Extra token?
+    break;
+  }
 
+  return true;
+}
+
+OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
+  SMLoc S = getLoc();
+
+  unsigned Sew = 0;
+  unsigned Lmul = 0;
+  bool Fractional = false;
+  bool TailAgnostic = false;
+  bool MaskAgnostic = false;
+
+  VTypeState State = VTypeState_SEW;
+
+  if (getLexer().isNot(AsmToken::Identifier))
+    return MatchOperand_NoMatch;
+
+  StringRef Identifier = getTok().getIdentifier();
+
+  if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic,
+                      MaskAgnostic))
+    return MatchOperand_NoMatch;
+
+  getLexer().Lex();
+
+  while (getLexer().is(AsmToken::Comma)) {
+    // Consume comma.
+    getLexer().Lex();
+
+    if (getLexer().isNot(AsmToken::Identifier))
+      break;
+
+    Identifier = getTok().getIdentifier();
+
+    if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic,
+                        MaskAgnostic))
+      break;
+
+    getLexer().Lex();
+  }
+
+  if (getLexer().is(AsmToken::EndOfStatement) && State == VTypeState_Done) {
     RISCVII::VLMUL VLMUL = RISCVVType::encodeLMUL(Lmul, Fractional);
 
     unsigned VTypeI =
@@ -2108,11 +2149,15 @@ OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
     return MatchOperand_Success;
   }
 
-// If NoMatch, unlex all the tokens that comprise a vtypei operand
-MatchFail:
-  while (!VTypeIElements.empty())
-    getLexer().UnLex(VTypeIElements.pop_back_val());
-  return MatchOperand_NoMatch;
+  generateVTypeError(S);
+  return MatchOperand_ParseFail;
+}
+
+bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
+  return Error(
+      ErrorLoc,
+      "operand must be "
+      "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
 }
 
 OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) {

diff  --git a/llvm/test/MC/RISCV/rvv/invalid.s b/llvm/test/MC/RISCV/rvv/invalid.s
index 16f64cf46fd55..09fd2c3bebf03 100644
--- a/llvm/test/MC/RISCV/rvv/invalid.s
+++ b/llvm/test/MC/RISCV/rvv/invalid.s
@@ -2,10 +2,10 @@
 # RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
 
 vsetivli a2, 32, e8,m1
-# CHECK-ERROR: immediate must be an integer in the range [0, 31]
+# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
 
 vsetivli a2, zero, e8,m1
-# CHECK-ERROR: immediate must be an integer in the range [0, 31]
+# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
 
 vsetivli a2, 5, (1 << 10)
 # CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]


        


More information about the llvm-commits mailing list