llvm.org GIT mirror llvm / 31bd08a
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358888 91177308-0d34-0410-b5e6-96231b3b80d8 Dmitry Preobrazhensky 5 months ago
3 changed file(s) with 89 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
10791079 StringRef &Value);
10801080
10811081 bool parseAbsoluteExpr(int64_t &Val, bool HasSP3AbsModifier = false);
1082 bool parseSP3NegModifier();
10821083 OperandMatchResultTy parseImm(OperandVector &Operands, bool HasSP3AbsModifier = false);
10831084 OperandMatchResultTy parseReg(OperandVector &Operands);
10841085 OperandMatchResultTy parseRegOrImm(OperandVector &Operands, bool AbsMod = false);
11331134 bool trySkipToken(const AsmToken::TokenKind Kind);
11341135 bool skipToken(const AsmToken::TokenKind Kind, const StringRef ErrMsg);
11351136 bool parseString(StringRef &Val, const StringRef ErrMsg = "expected a string");
1137 void peekTokens(MutableArrayRef Tokens);
11361138 AsmToken::TokenKind getTokenKind() const;
11371139 bool parseExpr(int64_t &Imm);
11381140 StringRef getTokenStr() const;
21032105 res;
21042106 }
21052107
2108 // Check if the current token is an SP3 'neg' modifier.
2109 // Currently this modifier is allowed in the following context:
2110 //
2111 // 1. Before a register, e.g. "-v0", "-v[...]" or "-[v0,v1]".
2112 // 2. Before an 'abs' modifier: -abs(...)
2113 // 3. Before an SP3 'abs' modifier: -|...|
2114 //
2115 // In all other cases "-" is handled as a part
2116 // of an expression that follows the sign.
2117 //
2118 // Note: When "-" is followed by an integer literal,
2119 // this is interpreted as integer negation rather
2120 // than a floating-point NEG modifier applied to N.
2121 // Beside being contr-intuitive, such use of floating-point
2122 // NEG modifier would have resulted in different meaning
2123 // of integer literals used with VOP1/2/C and VOP3,
2124 // for example:
2125 // v_exp_f32_e32 v5, -1 // VOP1: src0 = 0xFFFFFFFF
2126 // v_exp_f32_e64 v5, -1 // VOP3: src0 = 0x80000001
2127 // Negative fp literals with preceding "-" are
2128 // handled likewise for unifomtity
2129 //
2130 bool
2131 AMDGPUAsmParser::parseSP3NegModifier() {
2132
2133 AsmToken NextToken[2];
2134 peekTokens(NextToken);
2135
2136 if (isToken(AsmToken::Minus) &&
2137 (isRegister(NextToken[0], NextToken[1]) ||
2138 NextToken[0].is(AsmToken::Pipe) ||
2139 isId(NextToken[0], "abs"))) {
2140 lex();
2141 return true;
2142 }
2143
2144 return false;
2145 }
2146
21062147 OperandMatchResultTy
21072148 AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
21082149 bool AllowImm) {
2109 bool Negate = false, Negate2 = false, Abs = false, Abs2 = false;
2110
2111 if (getLexer().getKind()== AsmToken::Minus) {
2112 const AsmToken NextToken = getLexer().peekTok();
2113
2114 // Disable ambiguous constructs like '--1' etc. Should use neg(-1) instead.
2115 if (NextToken.is(AsmToken::Minus)) {
2116 Error(Parser.getTok().getLoc(), "invalid syntax, expected 'neg' modifier");
2117 return MatchOperand_ParseFail;
2118 }
2119
2120 // '-' followed by an integer literal N should be interpreted as integer
2121 // negation rather than a floating-point NEG modifier applied to N.
2122 // Beside being contr-intuitive, such use of floating-point NEG modifier
2123 // results in different meaning of integer literals used with VOP1/2/C
2124 // and VOP3, for example:
2125 // v_exp_f32_e32 v5, -1 // VOP1: src0 = 0xFFFFFFFF
2126 // v_exp_f32_e64 v5, -1 // VOP3: src0 = 0x80000001
2127 // Negative fp literals should be handled likewise for unifomtity
2128 if (!NextToken.is(AsmToken::Integer) && !NextToken.is(AsmToken::Real)) {
2129 Parser.Lex();
2130 Negate = true;
2131 }
2132 }
2150 bool Negate, Negate2 = false, Abs = false, Abs2 = false;
2151
2152 // Disable ambiguous constructs like '--1' etc. Should use neg(-1) instead.
2153 if (isToken(AsmToken::Minus) && peekToken().is(AsmToken::Minus)) {
2154 Error(getLoc(), "invalid syntax, expected 'neg' modifier");
2155 return MatchOperand_ParseFail;
2156 }
2157
2158 Negate = parseSP3NegModifier();
21332159
21342160 if (getLexer().getKind() == AsmToken::Identifier &&
21352161 Parser.getTok().getString() == "neg") {
21732199 Res = parseReg(Operands);
21742200 }
21752201 if (Res != MatchOperand_Success) {
2176 return Res;
2202 return (Negate || Negate2 || Abs || Abs2)? MatchOperand_ParseFail : Res;
21772203 }
21782204
21792205 AMDGPUOperand::Modifiers Mods;
22352261 Res = parseReg(Operands);
22362262 }
22372263 if (Res != MatchOperand_Success) {
2238 return Res;
2264 return Sext? MatchOperand_ParseFail : Res;
22392265 }
22402266
22412267 AMDGPUOperand::Modifiers Mods;
46364662 return getLexer().peekTok();
46374663 }
46384664
4665 void
4666 AMDGPUAsmParser::peekTokens(MutableArrayRef Tokens) {
4667 auto TokCount = getLexer().peekTokens(Tokens);
4668
4669 for (auto Idx = TokCount; Idx < Tokens.size(); ++Idx)
4670 Tokens[Idx] = AsmToken(AsmToken::Error, "");
4671 }
4672
46394673 AsmToken::TokenKind
46404674 AMDGPUAsmParser::getTokenKind() const {
46414675 return getLexer().getKind();
7171 t=10000000000
7272 s_sub_u32 s0, s0, 1.0 + t
7373 // NOVI: error: invalid operand for instruction
74
75 //===----------------------------------------------------------------------===//
76 // Symbols may look like registers.
77 // They should be allowed in expressions if there is no ambiguity.
78 //===----------------------------------------------------------------------===//
79
80 v=1
81 v_sin_f32 v0, -v
82 // VI: v_sin_f32_e32 v0, -1 ; encoding: [0xc1,0x52,0x00,0x7e]
83
84 v_sin_f32 v0, -v[0]
85 // VI: v_sin_f32_e64 v0, -v0 ; encoding: [0x00,0x00,0x69,0xd1,0x00,0x01,0x00,0x20]
86
87 s=1
88 v_sin_f32 v0, -s
89 // VI: v_sin_f32_e32 v0, -1 ; encoding: [0xc1,0x52,0x00,0x7e]
90
91 s0=1
92 v_sin_f32 v0, -s0
93 // VI: v_sin_f32_e64 v0, -s0 ; encoding: [0x00,0x00,0x69,0xd1,0x00,0x00,0x00,0x20]
94
95 ttmp=1
96 v_sin_f32 v0, -ttmp
97 // VI: v_sin_f32_e32 v0, -1 ; encoding: [0xc1,0x52,0x00,0x7e]
98
99 ttmp0=1
100 v_sin_f32 v0, -[ttmp0]
101 // VI: v_sin_f32_e64 v0, -ttmp0 ; encoding: [0x00,0x00,0x69,0xd1,0x70,0x00,0x00,0x20]
1111 // CHECK: error: invalid syntax, expected 'neg' modifier
1212
1313 v_ceil_f16 v0, abs(neg(1))
14 // CHECK: error: not a valid operand
14 // CHECK: error: failed parsing operand