[llvm] r358888 - [AMDGPU][MC] Corrected parsing of SP3 'neg' modifier

Dmitry Preobrazhensky via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 22 07:35:47 PDT 2019


Author: dpreobra
Date: Mon Apr 22 07:35:47 2019
New Revision: 358888

URL: http://llvm.org/viewvc/llvm-project?rev=358888&view=rev
Log:
[AMDGPU][MC] Corrected parsing of SP3 'neg' modifier

See bug 41156: https://bugs.llvm.org/show_bug.cgi?id=41156

Reviewers: artem.tamazov, arsenm

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

Modified:
    llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
    llvm/trunk/test/MC/AMDGPU/expressions.s
    llvm/trunk/test/MC/AMDGPU/vop3-modifiers-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=358888&r1=358887&r2=358888&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp Mon Apr 22 07:35:47 2019
@@ -1080,6 +1080,7 @@ public:
                                              StringRef &Value);
 
   bool parseAbsoluteExpr(int64_t &Val, bool HasSP3AbsModifier = false);
+  bool parseSP3NegModifier();
   OperandMatchResultTy parseImm(OperandVector &Operands, bool HasSP3AbsModifier = false);
   OperandMatchResultTy parseReg(OperandVector &Operands);
   OperandMatchResultTy parseRegOrImm(OperandVector &Operands, bool AbsMod = false);
@@ -1134,6 +1135,7 @@ private:
   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");
+  void peekTokens(MutableArrayRef<AsmToken> Tokens);
   AsmToken::TokenKind getTokenKind() const;
   bool parseExpr(int64_t &Imm);
   StringRef getTokenStr() const;
@@ -2104,34 +2106,58 @@ AMDGPUAsmParser::parseRegOrImm(OperandVe
          res;
 }
 
+// Check if the current token is an SP3 'neg' modifier.
+// Currently this modifier is allowed in the following context:
+//
+// 1. Before a register, e.g. "-v0", "-v[...]" or "-[v0,v1]".
+// 2. Before an 'abs' modifier: -abs(...)
+// 3. Before an SP3 'abs' modifier: -|...|
+//
+// In all other cases "-" is handled as a part
+// of an expression that follows the sign.
+//
+// Note: When "-" is followed by an integer literal,
+// this is interpreted as integer negation rather
+// than a floating-point NEG modifier applied to N.
+// Beside being contr-intuitive, such use of floating-point
+// NEG modifier would have resulted in different meaning
+// of integer literals used with VOP1/2/C and VOP3,
+// for example:
+//    v_exp_f32_e32 v5, -1 // VOP1: src0 = 0xFFFFFFFF
+//    v_exp_f32_e64 v5, -1 // VOP3: src0 = 0x80000001
+// Negative fp literals with preceding "-" are
+// handled likewise for unifomtity
+//
+bool
+AMDGPUAsmParser::parseSP3NegModifier() {
+
+  AsmToken NextToken[2];
+  peekTokens(NextToken);
+
+  if (isToken(AsmToken::Minus) &&
+      (isRegister(NextToken[0], NextToken[1]) ||
+       NextToken[0].is(AsmToken::Pipe) ||
+       isId(NextToken[0], "abs"))) {
+    lex();
+    return true;
+  }
+
+  return false;
+}
+
 OperandMatchResultTy
 AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
                                               bool AllowImm) {
-  bool Negate = false, Negate2 = false, Abs = false, Abs2 = false;
-
-  if (getLexer().getKind()== AsmToken::Minus) {
-    const AsmToken NextToken = getLexer().peekTok();
+  bool Negate, Negate2 = false, Abs = false, Abs2 = false;
 
-    // Disable ambiguous constructs like '--1' etc. Should use neg(-1) instead.
-    if (NextToken.is(AsmToken::Minus)) {
-      Error(Parser.getTok().getLoc(), "invalid syntax, expected 'neg' modifier");
-      return MatchOperand_ParseFail;
-    }
-
-    // '-' followed by an integer literal N should be interpreted as integer
-    // negation rather than a floating-point NEG modifier applied to N.
-    // Beside being contr-intuitive, such use of floating-point NEG modifier
-    // results in different meaning of integer literals used with VOP1/2/C
-    // and VOP3, for example:
-    //    v_exp_f32_e32 v5, -1 // VOP1: src0 = 0xFFFFFFFF
-    //    v_exp_f32_e64 v5, -1 // VOP3: src0 = 0x80000001
-    // Negative fp literals should be handled likewise for unifomtity
-    if (!NextToken.is(AsmToken::Integer) && !NextToken.is(AsmToken::Real)) {
-      Parser.Lex();
-      Negate = true;
-    }
+  // Disable ambiguous constructs like '--1' etc. Should use neg(-1) instead.
+  if (isToken(AsmToken::Minus) && peekToken().is(AsmToken::Minus)) {
+    Error(getLoc(), "invalid syntax, expected 'neg' modifier");
+    return MatchOperand_ParseFail;
   }
 
+  Negate = parseSP3NegModifier();
+
   if (getLexer().getKind() == AsmToken::Identifier &&
       Parser.getTok().getString() == "neg") {
     if (Negate) {
@@ -2174,7 +2200,7 @@ AMDGPUAsmParser::parseRegOrImmWithFPInpu
     Res = parseReg(Operands);
   }
   if (Res != MatchOperand_Success) {
-    return Res;
+    return (Negate || Negate2 || Abs || Abs2)? MatchOperand_ParseFail : Res;
   }
 
   AMDGPUOperand::Modifiers Mods;
@@ -2236,7 +2262,7 @@ AMDGPUAsmParser::parseRegOrImmWithIntInp
     Res = parseReg(Operands);
   }
   if (Res != MatchOperand_Success) {
-    return Res;
+    return Sext? MatchOperand_ParseFail : Res;
   }
 
   AMDGPUOperand::Modifiers Mods;
@@ -4637,6 +4663,14 @@ AMDGPUAsmParser::peekToken() {
   return getLexer().peekTok();
 }
 
+void
+AMDGPUAsmParser::peekTokens(MutableArrayRef<AsmToken> Tokens) {
+  auto TokCount = getLexer().peekTokens(Tokens);
+
+  for (auto Idx = TokCount; Idx < Tokens.size(); ++Idx)
+    Tokens[Idx] = AsmToken(AsmToken::Error, "");
+}
+
 AsmToken::TokenKind
 AMDGPUAsmParser::getTokenKind() const {
   return getLexer().getKind();

Modified: llvm/trunk/test/MC/AMDGPU/expressions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/expressions.s?rev=358888&r1=358887&r2=358888&view=diff
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/expressions.s (original)
+++ llvm/trunk/test/MC/AMDGPU/expressions.s Mon Apr 22 07:35:47 2019
@@ -72,3 +72,31 @@ s_sub_u32 s0, s0, -1.0 + 10000000000
 t=10000000000
 s_sub_u32 s0, s0, 1.0 + t
 // NOVI: error: invalid operand for instruction
+
+//===----------------------------------------------------------------------===//
+// Symbols may look like registers.
+// They should be allowed in expressions if there is no ambiguity.
+//===----------------------------------------------------------------------===//
+
+v=1
+v_sin_f32 v0, -v
+// VI: v_sin_f32_e32 v0, -1            ; encoding: [0xc1,0x52,0x00,0x7e]
+
+v_sin_f32 v0, -v[0]
+// VI: v_sin_f32_e64 v0, -v0           ; encoding: [0x00,0x00,0x69,0xd1,0x00,0x01,0x00,0x20]
+
+s=1
+v_sin_f32 v0, -s
+// VI: v_sin_f32_e32 v0, -1            ; encoding: [0xc1,0x52,0x00,0x7e]
+
+s0=1
+v_sin_f32 v0, -s0
+// VI: v_sin_f32_e64 v0, -s0           ; encoding: [0x00,0x00,0x69,0xd1,0x00,0x00,0x00,0x20]
+
+ttmp=1
+v_sin_f32 v0, -ttmp
+// VI: v_sin_f32_e32 v0, -1            ; encoding: [0xc1,0x52,0x00,0x7e]
+
+ttmp0=1
+v_sin_f32 v0, -[ttmp0]
+// VI: v_sin_f32_e64 v0, -ttmp0        ; encoding: [0x00,0x00,0x69,0xd1,0x70,0x00,0x00,0x20]

Modified: llvm/trunk/test/MC/AMDGPU/vop3-modifiers-err.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/vop3-modifiers-err.s?rev=358888&r1=358887&r2=358888&view=diff
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/vop3-modifiers-err.s (original)
+++ llvm/trunk/test/MC/AMDGPU/vop3-modifiers-err.s Mon Apr 22 07:35:47 2019
@@ -12,4 +12,4 @@ v_ceil_f32 v0, --1
 // CHECK: error: invalid syntax, expected 'neg' modifier
 
 v_ceil_f16 v0, abs(neg(1))
-// CHECK: error: not a valid operand
\ No newline at end of file
+// CHECK: error: failed parsing operand




More information about the llvm-commits mailing list