[llvm] 84b6d07 - [RISCV] Move the even register check for rv32zdinx later in the matching process.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 1 11:15:21 PST 2023
Author: Craig Topper
Date: 2023-02-01T11:15:06-08:00
New Revision: 84b6d074d7dc4474e259d2f535cb53901a03008c
URL: https://github.com/llvm/llvm-project/commit/84b6d074d7dc4474e259d2f535cb53901a03008c
DIFF: https://github.com/llvm/llvm-project/commit/84b6d074d7dc4474e259d2f535cb53901a03008c.diff
LOG: [RISCV] Move the even register check for rv32zdinx later in the matching process.
And remove the IsRV64 checks for isGPRAsFPR and isGPRPF64AsFPR.
Overall I think this results in a better diagnostic experience. We
now do a better job of matching Zdinx instructions even if the registers
aren't correct and report an error for missing features like RV64.
Unfortunately, this makes it difficult to recover the error location
for the invalid odd register when we do report it. But to make up
for it, I gave a more specific error message.
It doesn't look like binutils gives any warning or error for odd registers.
Reviewed By: asb
Differential Revision: https://reviews.llvm.org/D142997
Added:
Modified:
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/test/MC/RISCV/rv32zdinx-invalid.s
llvm/test/MC/RISCV/rv32zfinx-invalid.s
llvm/test/MC/RISCV/rv64zdinx-valid.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index b43cbe4744c1d..c05de2244f0e0 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -78,6 +78,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
unsigned Kind) override;
+ unsigned checkTargetMatchPredicate(MCInst &Inst) override;
bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
int64_t Lower, int64_t Upper, Twine Msg);
@@ -229,6 +230,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
public:
enum RISCVMatchResultTy {
Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
+ Match_RequiresEvenGPRs,
#define GET_OPERAND_DIAGNOSTIC_TYPES
#include "RISCVGenAsmMatcher.inc"
#undef GET_OPERAND_DIAGNOSTIC_TYPES
@@ -285,7 +287,6 @@ struct RISCVOperand final : public MCParsedAsmOperand {
struct RegOp {
MCRegister RegNum;
- bool IsRV64;
bool IsGPRAsFPR;
};
@@ -373,12 +374,9 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isGPRAsFPR() const { return isGPR() && Reg.IsGPRAsFPR; }
- bool isGPRF64AsFPR() const { return isGPR() && Reg.IsGPRAsFPR && Reg.IsRV64; }
+ bool isGPRF64AsFPR() const { return isGPR() && Reg.IsGPRAsFPR; }
- bool isGPRPF64AsFPR() const {
- return isGPR() && Reg.IsGPRAsFPR && !Reg.IsRV64 &&
- !((Reg.RegNum - RISCV::X0) & 1);
- }
+ bool isGPRPF64AsFPR() const { return isGPR() && Reg.IsGPRAsFPR; }
static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
RISCVMCExpr::VariantKind &VK) {
@@ -854,12 +852,10 @@ struct RISCVOperand final : public MCParsedAsmOperand {
return Op;
}
- static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
- SMLoc E, bool IsRV64,
- bool IsGPRAsFPR = false) {
+ static std::unique_ptr<RISCVOperand>
+ createReg(unsigned RegNo, SMLoc S, SMLoc E, bool IsGPRAsFPR = false) {
auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
Op->Reg.RegNum = RegNo;
- Op->Reg.IsRV64 = IsRV64;
Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
Op->StartLoc = S;
Op->EndLoc = E;
@@ -1037,6 +1033,23 @@ unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
return Match_InvalidOperand;
}
+unsigned RISCVAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
+ const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
+
+ for (unsigned I = 0; I < MCID.NumOperands; ++I) {
+ if (MCID.operands()[I].RegClass == RISCV::GPRPF64RegClassID) {
+ const auto &Op = Inst.getOperand(I);
+ assert(Op.isReg());
+
+ MCRegister Reg = Op.getReg();
+ if (((Reg.id() - RISCV::X0) & 1) != 0)
+ return Match_RequiresEvenGPRs;
+ }
+ }
+
+ return Match_Success;
+}
+
bool RISCVAsmParser::generateImmOutOfRangeError(
OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
Twine Msg = "immediate must be an integer in the range") {
@@ -1106,6 +1119,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
switch (Result) {
default:
break;
+ case Match_RequiresEvenGPRs:
+ return Error(IDLoc,
+ "double precision floating point operands must use even "
+ "numbered X register");
case Match_InvalidImmXLenLI:
if (isRV64()) {
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
@@ -1342,7 +1359,7 @@ OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
SMLoc S = getLoc();
SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size());
getLexer().Lex();
- Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
+ Operands.push_back(RISCVOperand::createReg(RegNo, S, E));
}
if (HadParens) {
@@ -1775,7 +1792,7 @@ OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
SMLoc S = getLoc();
SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size());
getLexer().Lex();
- Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
+ Operands.push_back(RISCVOperand::createReg(RegNo, S, E));
return MatchOperand_Success;
}
@@ -1793,7 +1810,7 @@ OperandMatchResultTy RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) {
SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size());
getLexer().Lex();
Operands.push_back(RISCVOperand::createReg(
- RegNo, S, E, isRV64(), !getSTI().hasFeature(RISCV::FeatureStdExtF)));
+ RegNo, S, E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
return MatchOperand_Success;
}
@@ -2637,7 +2654,7 @@ bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const {
return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(),
- llvm::SMLoc(), isRV64());
+ llvm::SMLoc());
}
std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp() const {
diff --git a/llvm/test/MC/RISCV/rv32zdinx-invalid.s b/llvm/test/MC/RISCV/rv32zdinx-invalid.s
index 7af576d32bc13..879157a08d60f 100644
--- a/llvm/test/MC/RISCV/rv32zdinx-invalid.s
+++ b/llvm/test/MC/RISCV/rv32zdinx-invalid.s
@@ -1,7 +1,7 @@
# RUN: not llvm-mc -triple riscv32 -mattr=+zdinx %s 2>&1 | FileCheck %s
# Unsupport Odd Registers in RV32
-fadd.d a0, a1, a2 # CHECK: :[[@LINE]]:12: error: invalid operand for instruction
+fadd.d a0, a1, a2 # CHECK: :[[@LINE]]:1: error: double precision floating point operands must use even numbered X register
# Not support float registers
flw fa4, 12(sp) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point){{$}}
diff --git a/llvm/test/MC/RISCV/rv32zfinx-invalid.s b/llvm/test/MC/RISCV/rv32zfinx-invalid.s
index 7b1eb1e16e931..b4675f85fa6e5 100644
--- a/llvm/test/MC/RISCV/rv32zfinx-invalid.s
+++ b/llvm/test/MC/RISCV/rv32zfinx-invalid.s
@@ -22,4 +22,4 @@ fmsub.s x14, x15, x16, x17, 0 # CHECK: :[[@LINE]]:29: error: operand must be a v
fnmsub.s x18, x19, x20, x21, 0b111 # CHECK: :[[@LINE]]:30: error: operand must be a valid floating point rounding mode mnemonic
# Using 'Zdinx' instructions for an 'Zfinx'-only target
-fadd.d t0, t1, t2 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
+fadd.d t0, t1, t2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zdinx' (Double in Integer){{$}}
diff --git a/llvm/test/MC/RISCV/rv64zdinx-valid.s b/llvm/test/MC/RISCV/rv64zdinx-valid.s
index 1e6e430686d01..fa603f36d9850 100644
--- a/llvm/test/MC/RISCV/rv64zdinx-valid.s
+++ b/llvm/test/MC/RISCV/rv64zdinx-valid.s
@@ -9,35 +9,35 @@
# CHECK-ASM-AND-OBJ: fcvt.l.d a0, t0, dyn
# CHECK-ASM: encoding: [0x53,0xf5,0x22,0xc2]
-# CHECK-RV32: :[[#@LINE+1]]:14: error: invalid operand for instruction
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.l.d a0, t0, dyn
# CHECK-ASM-AND-OBJ: fcvt.lu.d a1, t1, dyn
# CHECK-ASM: encoding: [0xd3,0x75,0x33,0xc2]
-# CHECK-RV32: :[[#@LINE+1]]:15: error: invalid operand for instruction
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.lu.d a1, t1, dyn
# CHECK-ASM-AND-OBJ: fcvt.d.l t3, a3, dyn
# CHECK-ASM: encoding: [0x53,0xfe,0x26,0xd2]
-# CHECK-RV32: :[[#@LINE+1]]:10: error: invalid operand for instruction
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.d.l t3, a3, dyn
# CHECK-ASM-AND-OBJ: fcvt.d.lu t4, a4, dyn
# CHECK-ASM: encoding: [0xd3,0x7e,0x37,0xd2]
-# CHECK-RV32: :[[#@LINE+1]]:11: error: invalid operand for instruction
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.d.lu t4, a4, dyn
# Rounding modes
# CHECK-ASM-AND-OBJ: fcvt.d.l t3, a3, rne
# CHECK-ASM: encoding: [0x53,0x8e,0x26,0xd2]
-# CHECK-RV32: :[[#@LINE+1]]:10: error: invalid operand for instruction
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.d.l t3, a3, rne
# CHECK-ASM-AND-OBJ: fcvt.d.lu t4, a4, rtz
# CHECK-ASM: encoding: [0xd3,0x1e,0x37,0xd2]
-# CHECK-RV32: :[[#@LINE+1]]:11: error: invalid operand for instruction
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.d.lu t4, a4, rtz
# CHECK-ASM-AND-OBJ: fcvt.l.d a0, t0, rdn
# CHECK-ASM: encoding: [0x53,0xa5,0x22,0xc2]
-# CHECK-RV32: :[[#@LINE+1]]:14: error: invalid operand for instruction
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.l.d a0, t0, rdn
# CHECK-ASM-AND-OBJ: fcvt.lu.d a1, t1, rup
# CHECK-ASM: encoding: [0xd3,0x35,0x33,0xc2]
-# CHECK-RV32: :[[#@LINE+1]]:15: error: invalid operand for instruction
+# CHECK-RV32: :[[#@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
fcvt.lu.d a1, t1, rup
More information about the llvm-commits
mailing list