Skip to content

Commit 499afd1

Browse files
committed
[RISCV] Improve Errors for X1/X5/X1X5 Reg Classes
LLVM has functionality for producing a register-class-specific error message in the assembly parser, rather than just emitting the generic "invalid operand for instruction" error. This starts the gradual adoption of this functionality for RISC-V, with some lesser-used shadow-stack register classes: - GPRX1 (only contains `ra`) - GPRX5 (only contains `t0`) - GPRX1X5 (only contains `ra` and `t0`) LLVM is reasonably conservative about when these errors are used, in particular you have to have all the features for the relevant mnemonic enabled before it will do, hence the test updates. I also merged a pair of almost identical rv32/rv64 test files into a single file with one run line.
1 parent 50cdf6c commit 499afd1

File tree

5 files changed

+36
-34
lines changed

5 files changed

+36
-34
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,6 +1723,18 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
17231723
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
17241724
return Error(ErrorLoc, "operands must be register and register");
17251725
}
1726+
case Match_InvalidRegClassGPRX1: {
1727+
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1728+
return Error(ErrorLoc, "register must be ra (x1)");
1729+
}
1730+
case Match_InvalidRegClassGPRX5: {
1731+
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1732+
return Error(ErrorLoc, "register must be t0 (x5)");
1733+
}
1734+
case Match_InvalidRegClassGPRX1X5: {
1735+
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1736+
return Error(ErrorLoc, "register must be ra or t0 (x1 or x5)");
1737+
}
17261738
}
17271739

17281740
llvm_unreachable("Unknown match type detected!");

llvm/lib/Target/RISCV/RISCVRegisterInfo.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,11 @@ def GPR : GPRRegisterClass<(add (sequence "X%u", 10, 17),
247247
(sequence "X%u", 0, 4))>;
248248

249249
def GPRX0 : GPRRegisterClass<(add X0)>;
250+
251+
let DiagnosticType = "InvalidRegClassGPRX1" in
250252
def GPRX1 : GPRRegisterClass<(add X1)>;
253+
254+
let DiagnosticType = "InvalidRegClassGPRX5" in
251255
def GPRX5 : GPRRegisterClass<(add X5)>;
252256

253257
def GPRNoX0 : GPRRegisterClass<(sub GPR, X0)>;
@@ -282,6 +286,7 @@ def SP : GPRRegisterClass<(add X2)>;
282286
def SR07 : GPRRegisterClass<(add (sequence "X%u", 8, 9),
283287
(sequence "X%u", 18, 23))>;
284288

289+
let DiagnosticType = "InvalidRegClassGPRX1X5" in
285290
def GPRX1X5 : GPRRegisterClass<(add X1, X5)>;
286291

287292
//===----------------------------------------------------------------------===//

llvm/test/MC/RISCV/rv32zicfiss-invalid.s

Lines changed: 0 additions & 17 deletions
This file was deleted.

llvm/test/MC/RISCV/rv64zicfiss-invalid.s

Lines changed: 0 additions & 17 deletions
This file was deleted.

llvm/test/MC/RISCV/zicfiss-invalid.s

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# RUN: not llvm-mc %s -triple=riscv32 -mattr=+experimental-zicfiss,+zcmop,+c -M no-aliases -show-encoding \
2+
# RUN: 2>&1 | FileCheck -check-prefixes=CHECK-ERR %s
3+
# RUN: not llvm-mc %s -triple=riscv64 -mattr=+experimental-zicfiss,+zcmop,+c -M no-aliases -show-encoding \
4+
# RUN: 2>&1 | FileCheck -check-prefixes=CHECK-ERR %s
5+
6+
# CHECK-ERR: error: register must be ra or t0 (x1 or x5)
7+
sspopchk a1
8+
9+
# CHECK-ERR: error: register must be ra (x1)
10+
c.sspush t0
11+
12+
# CHECK-ERR: error: register must be t0 (x5)
13+
c.sspopchk ra
14+
15+
# CHECK-ERR: error: register must be ra or t0 (x1 or x5)
16+
sspush a0
17+
18+
# CHECK-ERR: error: invalid operand for instruction
19+
ssrdp zero

0 commit comments

Comments
 (0)