Skip to content

Commit 43ae009

Browse files
authored
[RISCV] Make All VType Parts Optional (#144971)
This matches the current binutils behaviour, and the orignal ratified spec that states that LMUL=1 when the lmul operand is omitted. A variety of previously invalid vtype instructions are now accepted by the assembler. To match binutils, at least one of the vtype operands must be provided. Also fixes the MCOperandPredicate definition in VTypeIOp, which had one logic issue and one syntax issue. This is not used by the MC layer currently, so this change should not affect the existing implementation. Fixes #143744
1 parent a6eb5ee commit 43ae009

File tree

4 files changed

+252
-90
lines changed

4 files changed

+252
-90
lines changed

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 65 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,14 @@ struct ParserOptionsSet {
6666
};
6767

6868
class RISCVAsmParser : public MCTargetAsmParser {
69-
// This tracks the parsing of the 4 operands that make up the vtype portion
70-
// of vset(i)vli instructions which are separated by commas. The state names
71-
// represent the next expected operand with Done meaning no other operands are
72-
// expected.
73-
enum VTypeState {
74-
VTypeState_SEW,
75-
VTypeState_LMUL,
76-
VTypeState_TailPolicy,
77-
VTypeState_MaskPolicy,
78-
VTypeState_Done,
69+
// This tracks the parsing of the 4 optional operands that make up the vtype
70+
// portion of vset(i)vli instructions which are separated by commas.
71+
enum class VTypeState {
72+
SeenNothingYet,
73+
SeenSew,
74+
SeenLmul,
75+
SeenTailPolicy,
76+
SeenMaskPolicy,
7977
};
8078

8179
SmallVector<FeatureBitset, 4> FeatureBitStack;
@@ -2229,25 +2227,30 @@ bool RISCVAsmParser::parseVTypeToken(const AsmToken &Tok, VTypeState &State,
22292227
return true;
22302228

22312229
StringRef Identifier = Tok.getIdentifier();
2232-
2233-
switch (State) {
2234-
case VTypeState_SEW:
2235-
if (!Identifier.consume_front("e"))
2236-
break;
2230+
if (State < VTypeState::SeenSew && Identifier.consume_front("e")) {
22372231
if (Identifier.getAsInteger(10, Sew))
2238-
break;
2232+
return true;
22392233
if (!RISCVVType::isValidSEW(Sew))
2240-
break;
2241-
State = VTypeState_LMUL;
2234+
return true;
2235+
2236+
State = VTypeState::SeenSew;
22422237
return false;
2243-
case VTypeState_LMUL: {
2244-
if (!Identifier.consume_front("m"))
2245-
break;
2238+
}
2239+
2240+
if (State < VTypeState::SeenLmul && Identifier.consume_front("m")) {
2241+
// Might arrive here if lmul and tail policy unspecified, if so we're
2242+
// parsing a MaskPolicy not an LMUL.
2243+
if (Identifier == "a" || Identifier == "u") {
2244+
MaskAgnostic = (Identifier == "a");
2245+
State = VTypeState::SeenMaskPolicy;
2246+
return false;
2247+
}
2248+
22462249
Fractional = Identifier.consume_front("f");
22472250
if (Identifier.getAsInteger(10, Lmul))
2248-
break;
2251+
return true;
22492252
if (!RISCVVType::isValidLMUL(Lmul, Fractional))
2250-
break;
2253+
return true;
22512254

22522255
if (Fractional) {
22532256
unsigned ELEN = STI->hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
@@ -2258,30 +2261,32 @@ bool RISCVAsmParser::parseVTypeToken(const AsmToken &Tok, VTypeState &State,
22582261
Twine(MinLMUL) + " is reserved");
22592262
}
22602263

2261-
State = VTypeState_TailPolicy;
2264+
State = VTypeState::SeenLmul;
22622265
return false;
22632266
}
2264-
case VTypeState_TailPolicy:
2267+
2268+
if (State < VTypeState::SeenTailPolicy && Identifier.starts_with("t")) {
22652269
if (Identifier == "ta")
22662270
TailAgnostic = true;
22672271
else if (Identifier == "tu")
22682272
TailAgnostic = false;
22692273
else
2270-
break;
2271-
State = VTypeState_MaskPolicy;
2274+
return true;
2275+
2276+
State = VTypeState::SeenTailPolicy;
22722277
return false;
2273-
case VTypeState_MaskPolicy:
2278+
}
2279+
2280+
if (State < VTypeState::SeenMaskPolicy && Identifier.starts_with("m")) {
22742281
if (Identifier == "ma")
22752282
MaskAgnostic = true;
22762283
else if (Identifier == "mu")
22772284
MaskAgnostic = false;
22782285
else
2279-
break;
2280-
State = VTypeState_Done;
2286+
return true;
2287+
2288+
State = VTypeState::SeenMaskPolicy;
22812289
return false;
2282-
case VTypeState_Done:
2283-
// Extra token?
2284-
break;
22852290
}
22862291

22872292
return true;
@@ -2290,49 +2295,45 @@ bool RISCVAsmParser::parseVTypeToken(const AsmToken &Tok, VTypeState &State,
22902295
ParseStatus RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
22912296
SMLoc S = getLoc();
22922297

2293-
unsigned Sew = 0;
2294-
unsigned Lmul = 0;
2298+
// Default values
2299+
unsigned Sew = 8;
2300+
unsigned Lmul = 1;
22952301
bool Fractional = false;
22962302
bool TailAgnostic = false;
22972303
bool MaskAgnostic = false;
22982304

2299-
VTypeState State = VTypeState_SEW;
2300-
SMLoc SEWLoc = S;
2301-
2302-
if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2303-
MaskAgnostic))
2304-
return ParseStatus::NoMatch;
2305-
2306-
getLexer().Lex();
2307-
2308-
while (parseOptionalToken(AsmToken::Comma)) {
2305+
VTypeState State = VTypeState::SeenNothingYet;
2306+
do {
23092307
if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2310-
MaskAgnostic))
2308+
MaskAgnostic)) {
2309+
// The first time, errors return NoMatch rather than Failure
2310+
if (State == VTypeState::SeenNothingYet)
2311+
return ParseStatus::NoMatch;
23112312
break;
2313+
}
23122314

23132315
getLexer().Lex();
2314-
}
2316+
} while (parseOptionalToken(AsmToken::Comma));
23152317

2316-
if (getLexer().is(AsmToken::EndOfStatement) && State == VTypeState_Done) {
2317-
RISCVVType::VLMUL VLMUL = RISCVVType::encodeLMUL(Lmul, Fractional);
2318-
if (Fractional) {
2319-
unsigned ELEN = STI->hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2320-
unsigned MaxSEW = ELEN / Lmul;
2321-
// If MaxSEW < 8, we should have printed warning about reserved LMUL.
2322-
if (MaxSEW >= 8 && Sew > MaxSEW)
2323-
Warning(SEWLoc,
2324-
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2325-
" and LMUL == mf" + Twine(Lmul) +
2326-
" may not be compatible with all RVV implementations");
2327-
}
2318+
if (!getLexer().is(AsmToken::EndOfStatement) ||
2319+
State == VTypeState::SeenNothingYet)
2320+
return generateVTypeError(S);
23282321

2329-
unsigned VTypeI =
2330-
RISCVVType::encodeVTYPE(VLMUL, Sew, TailAgnostic, MaskAgnostic);
2331-
Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2332-
return ParseStatus::Success;
2322+
RISCVVType::VLMUL VLMUL = RISCVVType::encodeLMUL(Lmul, Fractional);
2323+
if (Fractional) {
2324+
unsigned ELEN = STI->hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2325+
unsigned MaxSEW = ELEN / Lmul;
2326+
// If MaxSEW < 8, we should have printed warning about reserved LMUL.
2327+
if (MaxSEW >= 8 && Sew > MaxSEW)
2328+
Warning(S, "use of vtype encodings with SEW > " + Twine(MaxSEW) +
2329+
" and LMUL == mf" + Twine(Lmul) +
2330+
" may not be compatible with all RVV implementations");
23332331
}
23342332

2335-
return generateVTypeError(S);
2333+
unsigned VTypeI =
2334+
RISCVVType::encodeVTYPE(VLMUL, Sew, TailAgnostic, MaskAgnostic);
2335+
Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2336+
return ParseStatus::Success;
23362337
}
23372338

23382339
bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {

llvm/lib/Target/RISCV/RISCVInstrInfoV.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ class VTypeIOp<int VTypeINum> : RISCVOp {
3030
let MCOperandPredicate = [{
3131
int64_t Imm;
3232
if (MCOp.evaluateAsConstantImm(Imm))
33-
return isUInt<VTypeINum>(Imm);
34-
return MCOp.isBareSymbolRef();
33+
return isUInt<}] # VTypeINum # [{>(Imm);
34+
return MCOp.Kind == KindTy::VType;
3535
}];
3636
}
3737

llvm/test/MC/RISCV/rvv/invalid.s

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
# RUN: not llvm-mc -triple=riscv64 --mattr=+v --mattr=+f %s 2>&1 \
22
# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
33

4-
vsetivli a2, 32, e8,m1
5-
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
6-
7-
vsetivli a2, zero, e8,m1
8-
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
9-
104
vsetivli a2, 5, (1 << 10)
115
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
126

@@ -22,10 +16,6 @@ vsetvli a2, a0, (1 << 11)
2216
vsetvli a2, a0, 0x800
2317
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
2418

25-
26-
vsetvli a2, a0, e31
27-
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
28-
2919
vsetvli a2, a0, e32,m3
3020
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
3121

@@ -59,12 +49,6 @@ vsetvli a2, a0, e8,m1,tx
5949
vsetvli a2, a0, e8,m1,ta,mx
6050
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
6151

62-
vsetvli a2, a0, e8,m1,ma
63-
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
64-
65-
vsetvli a2, a0, e8,m1,mu
66-
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
67-
6852
vsetvli a2, a0, e8x,m1,tu,mu
6953
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
7054

@@ -80,17 +64,14 @@ vsetvli a2, a0, e8,m1,tu,mut
8064
vsetvli a2, a0, e8,m1,tut,mu
8165
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
8266

83-
vsetvli a2, a0, e8
84-
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
85-
86-
vsetvli a2, a0, e8,m1
67+
vsetvli a2, a0, e8,1,ta,ma
8768
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
8869

89-
vsetvli a2, a0, e8,m1,ta
70+
vsetvli a2, a0, ma,tu,m1,e8
9071
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
9172

92-
vsetvli a2, a0, e8,1,ta,ma
93-
# CHECK-ERROR: operand must be e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]
73+
vsetvli a2, a0,
74+
# CHECK-ERROR: unknown operand
9475

9576
vadd.vv v1, v3, v2, v4.t
9677
# CHECK-ERROR: operand must be v0.t

0 commit comments

Comments
 (0)