[llvm] r358596 - [AMDGPU][MC] Corrected handling of "-" before expressions
Dmitry Preobrazhensky via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 17 09:56:34 PDT 2019
Author: dpreobra
Date: Wed Apr 17 09:56:34 2019
New Revision: 358596
URL: http://llvm.org/viewvc/llvm-project?rev=358596&view=rev
Log:
[AMDGPU][MC] Corrected handling of "-" before expressions
See bug 41156: https://bugs.llvm.org/show_bug.cgi?id=41156
Reviewers: artem.tamazov, arsenm
Differential Revision: https://reviews.llvm.org/D60622
Modified:
llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
llvm/trunk/test/MC/AMDGPU/expressions.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=358596&r1=358595&r2=358596&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp Wed Apr 17 09:56:34 2019
@@ -1079,8 +1079,8 @@ public:
OperandMatchResultTy parseStringWithPrefix(StringRef Prefix,
StringRef &Value);
- bool parseAbsoluteExpr(int64_t &Val, bool AbsMod = false);
- OperandMatchResultTy parseImm(OperandVector &Operands, bool AbsMod = false);
+ bool parseAbsoluteExpr(int64_t &Val, bool HasSP3AbsModifier = false);
+ OperandMatchResultTy parseImm(OperandVector &Operands, bool HasSP3AbsModifier = false);
OperandMatchResultTy parseReg(OperandVector &Operands);
OperandMatchResultTy parseRegOrImm(OperandVector &Operands, bool AbsMod = false);
OperandMatchResultTy parseRegOrImmWithFPInputMods(OperandVector &Operands, bool AllowImm = true);
@@ -1136,6 +1136,7 @@ private:
bool parseString(StringRef &Val, const StringRef ErrMsg = "expected a string");
AsmToken::TokenKind getTokenKind() const;
bool parseExpr(int64_t &Imm);
+ StringRef getTokenStr() const;
AsmToken peekToken();
AsmToken getToken() const;
SMLoc getLoc() const;
@@ -2001,70 +2002,84 @@ std::unique_ptr<AMDGPUOperand> AMDGPUAsm
}
bool
-AMDGPUAsmParser::parseAbsoluteExpr(int64_t &Val, bool AbsMod) {
- if (AbsMod && getLexer().peekTok().is(AsmToken::Pipe) &&
- (getLexer().getKind() == AsmToken::Integer ||
- getLexer().getKind() == AsmToken::Real)) {
- // This is a workaround for handling operands like these:
+AMDGPUAsmParser::parseAbsoluteExpr(int64_t &Val, bool HasSP3AbsModifier) {
+ if (HasSP3AbsModifier) {
+ // This is a workaround for handling expressions
+ // as arguments of SP3 'abs' modifier, for example:
// |1.0|
// |-1|
+ // |1+x|
// This syntax is not compatible with syntax of standard
// MC expressions (due to the trailing '|').
SMLoc EndLoc;
const MCExpr *Expr;
+ SMLoc StartLoc = getLoc();
if (getParser().parsePrimaryExpr(Expr, EndLoc)) {
return true;
}
- return !Expr->evaluateAsAbsolute(Val);
+ if (!Expr->evaluateAsAbsolute(Val))
+ return Error(StartLoc, "expected absolute expression");
+
+ return false;
}
return getParser().parseAbsoluteExpression(Val);
}
OperandMatchResultTy
-AMDGPUAsmParser::parseImm(OperandVector &Operands, bool AbsMod) {
+AMDGPUAsmParser::parseImm(OperandVector &Operands, bool HasSP3AbsModifier) {
// TODO: add syntactic sugar for 1/(2*PI)
- bool Minus = false;
- if (getLexer().getKind() == AsmToken::Minus) {
- const AsmToken NextToken = getLexer().peekTok();
- if (!NextToken.is(AsmToken::Integer) &&
- !NextToken.is(AsmToken::Real)) {
- return MatchOperand_NoMatch;
- }
- Minus = true;
- Parser.Lex();
+
+ const auto& Tok = getToken();
+ const auto& NextTok = peekToken();
+ bool IsReal = Tok.is(AsmToken::Real);
+ SMLoc S = Tok.getLoc();
+ bool Negate = false;
+
+ if (!IsReal && Tok.is(AsmToken::Minus) && NextTok.is(AsmToken::Real)) {
+ lex();
+ IsReal = true;
+ Negate = true;
}
- SMLoc S = Parser.getTok().getLoc();
- switch(getLexer().getKind()) {
- case AsmToken::Integer: {
- int64_t IntVal;
- if (parseAbsoluteExpr(IntVal, AbsMod))
+ if (IsReal) {
+ // Floating-point expressions are not supported.
+ // Can only allow floating-point literals with an
+ // optional sign.
+
+ StringRef Num = getTokenStr();
+ lex();
+
+ APFloat RealVal(APFloat::IEEEdouble());
+ auto roundMode = APFloat::rmNearestTiesToEven;
+ if (RealVal.convertFromString(Num, roundMode) == APFloat::opInvalidOp) {
return MatchOperand_ParseFail;
- if (Minus)
- IntVal *= -1;
- Operands.push_back(AMDGPUOperand::CreateImm(this, IntVal, S));
+ }
+ if (Negate)
+ RealVal.changeSign();
+
+ Operands.push_back(
+ AMDGPUOperand::CreateImm(this, RealVal.bitcastToAPInt().getZExtValue(), S,
+ AMDGPUOperand::ImmTyNone, true));
+
return MatchOperand_Success;
- }
- case AsmToken::Real: {
+
+ // FIXME: Should enable arbitrary expressions here
+ } else if (Tok.is(AsmToken::Integer) ||
+ (Tok.is(AsmToken::Minus) && NextTok.is(AsmToken::Integer))){
+
int64_t IntVal;
- if (parseAbsoluteExpr(IntVal, AbsMod))
+ if (parseAbsoluteExpr(IntVal, HasSP3AbsModifier))
return MatchOperand_ParseFail;
- APFloat F(BitsToDouble(IntVal));
- if (Minus)
- F.changeSign();
- Operands.push_back(
- AMDGPUOperand::CreateImm(this, F.bitcastToAPInt().getZExtValue(), S,
- AMDGPUOperand::ImmTyNone, true));
+ Operands.push_back(AMDGPUOperand::CreateImm(this, IntVal, S));
return MatchOperand_Success;
}
- default:
- return MatchOperand_NoMatch;
- }
+
+ return MatchOperand_NoMatch;
}
OperandMatchResultTy
@@ -4632,6 +4647,11 @@ AMDGPUAsmParser::getLoc() const {
return getToken().getLoc();
}
+StringRef
+AMDGPUAsmParser::getTokenStr() const {
+ return getToken().getString();
+}
+
void
AMDGPUAsmParser::lex() {
Parser.Lex();
Modified: llvm/trunk/test/MC/AMDGPU/expressions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/expressions.s?rev=358596&r1=358595&r2=358596&view=diff
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/expressions.s (original)
+++ llvm/trunk/test/MC/AMDGPU/expressions.s Wed Apr 17 09:56:34 2019
@@ -1,4 +1,5 @@
-// RUN: llvm-mc -arch=amdgcn -mcpu=fiji -show-encoding %s | FileCheck %s --check-prefix=VI
+// RUN: not llvm-mc -arch=amdgcn -mcpu=fiji -show-encoding %s | FileCheck %s --check-prefix=VI
+// RUN: not llvm-mc -arch=amdgcn -mcpu=fiji -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOVI
.globl global
@@ -57,3 +58,17 @@ s_sub_u32 s0, s0, -t
t=-1
s_sub_u32 s0, s0, -t
// VI: s_sub_u32 s0, s0, 1 ; encoding: [0x00,0x81,0x80,0x80]
+
+s_sub_u32 s0, s0, -2+1
+// VI: s_sub_u32 s0, s0, -1 ; encoding: [0x00,0xc1,0x80,0x80]
+
+t=1
+s_sub_u32 s0, s0, -2+t
+// VI: s_sub_u32 s0, s0, -1 ; encoding: [0x00,0xc1,0x80,0x80]
+
+s_sub_u32 s0, s0, -1.0 + 10000000000
+// NOVI: error: invalid operand for instruction
+
+t=10000000000
+s_sub_u32 s0, s0, 1.0 + t
+// NOVI: error: invalid operand for instruction
More information about the llvm-commits
mailing list