-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[RISCV] Make RISCVInstrInfo::verifyInstruction stricter for immediate-only operands #170736
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…-only operands Most of the immediate operands can only be an immediate, but we were allowing any non-register operand. Split the immediate-only from the immediate or non-register operands. The non-register cases could be made even stricter, but I'll leave that as a TODO.
|
@llvm/pr-subscribers-tools-llvm-exegesis @llvm/pr-subscribers-backend-risc-v Author: Craig Topper (topperc) ChangesMost of the immediate operands can only be an immediate, but we were allowing any non-register operand. Split the immediate-only from the immediate or non-register operands. The non-register cases could be made even stricter, but I'll leave that as a TODO. Full diff: https://github.com/llvm/llvm-project/pull/170736.diff 3 Files Affected:
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index d8dcd963050b5..dbf5cfe6ef463 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -393,7 +393,6 @@ enum OperandType : unsigned {
OPERAND_UIMM14_LSB00,
OPERAND_UIMM16,
OPERAND_UIMM16_NONZERO,
- OPERAND_UIMM20,
OPERAND_UIMMLOG2XLEN,
OPERAND_UIMMLOG2XLEN_NONZERO,
OPERAND_UIMM32,
@@ -412,13 +411,11 @@ enum OperandType : unsigned {
OPERAND_SIMM10_LSB0000_NONZERO,
OPERAND_SIMM10_UNSIGNED,
OPERAND_SIMM11,
- OPERAND_SIMM12,
OPERAND_SIMM12_LSB00000,
OPERAND_SIMM16,
OPERAND_SIMM16_NONZERO,
OPERAND_SIMM20_LI,
OPERAND_SIMM26,
- OPERAND_BARE_SIMM32,
OPERAND_CLUI_IMM,
OPERAND_VTYPEI10,
OPERAND_VTYPEI11,
@@ -447,6 +444,15 @@ enum OperandType : unsigned {
// Vtype operand for XSfmm extension.
OPERAND_XSFMM_VTYPE,
OPERAND_LAST_RISCV_IMM = OPERAND_XSFMM_VTYPE,
+
+ OPERAND_UIMM20_LUI,
+ OPERAND_UIMM20_AUIPC,
+
+ // Simm12 or constant pool, global, basicblock, etc.
+ OPERAND_SIMM12_LO,
+
+ OPERAND_BARE_SIMM32,
+
// Operand is either a register or uimm5, this is used by V extension pseudo
// instructions to represent a value that be passed as AVL to either vsetvli
// or vsetivli.
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 2bd63e75d060b..ee327f3d61a62 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -2850,22 +2850,21 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
MCInstrDesc const &Desc = MI.getDesc();
for (const auto &[Index, Operand] : enumerate(Desc.operands())) {
+ const MachineOperand &MO = MI.getOperand(Index);
unsigned OpType = Operand.OperandType;
if (OpType >= RISCVOp::OPERAND_FIRST_RISCV_IMM &&
OpType <= RISCVOp::OPERAND_LAST_RISCV_IMM) {
- const MachineOperand &MO = MI.getOperand(Index);
- if (MO.isReg()) {
- ErrInfo = "Expected a non-register operand.";
+ if (!MO.isImm()) {
+ ErrInfo = "Expected an immediate operand.";
return false;
}
- if (MO.isImm()) {
- int64_t Imm = MO.getImm();
- bool Ok;
- switch (OpType) {
- default:
- llvm_unreachable("Unexpected operand type");
+ int64_t Imm = MO.getImm();
+ bool Ok;
+ switch (OpType) {
+ default:
+ llvm_unreachable("Unexpected operand type");
- // clang-format off
+ // clang-format off
#define CASE_OPERAND_UIMM(NUM) \
case RISCVOp::OPERAND_UIMM##NUM: \
Ok = isUInt<NUM>(Imm); \
@@ -2874,181 +2873,208 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
case RISCVOp::OPERAND_SIMM##NUM: \
Ok = isInt<NUM>(Imm); \
break;
- CASE_OPERAND_UIMM(1)
- CASE_OPERAND_UIMM(2)
- CASE_OPERAND_UIMM(3)
- CASE_OPERAND_UIMM(4)
- CASE_OPERAND_UIMM(5)
- CASE_OPERAND_UIMM(6)
- CASE_OPERAND_UIMM(7)
- CASE_OPERAND_UIMM(8)
- CASE_OPERAND_UIMM(9)
- CASE_OPERAND_UIMM(10)
- CASE_OPERAND_UIMM(12)
- CASE_OPERAND_UIMM(16)
- CASE_OPERAND_UIMM(20)
- CASE_OPERAND_UIMM(32)
- CASE_OPERAND_UIMM(48)
- CASE_OPERAND_UIMM(64)
- // clang-format on
- case RISCVOp::OPERAND_UIMM2_LSB0:
- Ok = isShiftedUInt<1, 1>(Imm);
- break;
- case RISCVOp::OPERAND_UIMM5_LSB0:
- Ok = isShiftedUInt<4, 1>(Imm);
- break;
- case RISCVOp::OPERAND_UIMM5_NONZERO:
- Ok = isUInt<5>(Imm) && (Imm != 0);
- break;
- case RISCVOp::OPERAND_UIMM5_GT3:
- Ok = isUInt<5>(Imm) && (Imm > 3);
- break;
- case RISCVOp::OPERAND_UIMM5_PLUS1:
- Ok = Imm >= 1 && Imm <= 32;
- break;
- case RISCVOp::OPERAND_UIMM6_LSB0:
- Ok = isShiftedUInt<5, 1>(Imm);
- break;
- case RISCVOp::OPERAND_UIMM7_LSB00:
- Ok = isShiftedUInt<5, 2>(Imm);
- break;
- case RISCVOp::OPERAND_UIMM7_LSB000:
- Ok = isShiftedUInt<4, 3>(Imm);
- break;
- case RISCVOp::OPERAND_UIMM8_LSB00:
- Ok = isShiftedUInt<6, 2>(Imm);
- break;
- case RISCVOp::OPERAND_UIMM8_LSB000:
- Ok = isShiftedUInt<5, 3>(Imm);
- break;
- case RISCVOp::OPERAND_UIMM8_GE32:
- Ok = isUInt<8>(Imm) && Imm >= 32;
- break;
- case RISCVOp::OPERAND_UIMM9_LSB000:
- Ok = isShiftedUInt<6, 3>(Imm);
- break;
- case RISCVOp::OPERAND_SIMM8_UNSIGNED:
- Ok = isInt<8>(Imm);
- break;
- case RISCVOp::OPERAND_SIMM10_LSB0000_NONZERO:
- Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0);
- break;
- case RISCVOp::OPERAND_UIMM10_LSB00_NONZERO:
- Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0);
- break;
- case RISCVOp::OPERAND_UIMM16_NONZERO:
- Ok = isUInt<16>(Imm) && (Imm != 0);
- break;
- case RISCVOp::OPERAND_THREE:
- Ok = Imm == 3;
- break;
- case RISCVOp::OPERAND_FOUR:
- Ok = Imm == 4;
- break;
- case RISCVOp::OPERAND_IMM5_ZIBI:
- Ok = (isUInt<5>(Imm) && Imm != 0) || Imm == -1;
- break;
- // clang-format off
- CASE_OPERAND_SIMM(5)
- CASE_OPERAND_SIMM(6)
- CASE_OPERAND_SIMM(10)
- CASE_OPERAND_SIMM(11)
- CASE_OPERAND_SIMM(12)
- CASE_OPERAND_SIMM(26)
+ CASE_OPERAND_UIMM(1)
+ CASE_OPERAND_UIMM(2)
+ CASE_OPERAND_UIMM(3)
+ CASE_OPERAND_UIMM(4)
+ CASE_OPERAND_UIMM(5)
+ CASE_OPERAND_UIMM(6)
+ CASE_OPERAND_UIMM(7)
+ CASE_OPERAND_UIMM(8)
+ CASE_OPERAND_UIMM(9)
+ CASE_OPERAND_UIMM(10)
+ CASE_OPERAND_UIMM(12)
+ CASE_OPERAND_UIMM(16)
+ CASE_OPERAND_UIMM(32)
+ CASE_OPERAND_UIMM(48)
+ CASE_OPERAND_UIMM(64)
// clang-format on
- case RISCVOp::OPERAND_SIMM5_PLUS1:
- Ok = Imm >= -15 && Imm <= 16;
- break;
- case RISCVOp::OPERAND_SIMM5_NONZERO:
- Ok = isInt<5>(Imm) && (Imm != 0);
- break;
- case RISCVOp::OPERAND_SIMM6_NONZERO:
- Ok = Imm != 0 && isInt<6>(Imm);
- break;
- case RISCVOp::OPERAND_VTYPEI10:
- Ok = isUInt<10>(Imm);
- break;
- case RISCVOp::OPERAND_VTYPEI11:
- Ok = isUInt<11>(Imm);
- break;
- case RISCVOp::OPERAND_SIMM12_LSB00000:
- Ok = isShiftedInt<7, 5>(Imm);
- break;
- case RISCVOp::OPERAND_SIMM16_NONZERO:
- Ok = isInt<16>(Imm) && (Imm != 0);
- break;
- case RISCVOp::OPERAND_SIMM20_LI:
- Ok = isInt<20>(Imm);
- break;
- case RISCVOp::OPERAND_BARE_SIMM32:
- Ok = isInt<32>(Imm);
- break;
- case RISCVOp::OPERAND_UIMMLOG2XLEN:
- Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
- break;
- case RISCVOp::OPERAND_UIMMLOG2XLEN_NONZERO:
- Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
- Ok = Ok && Imm != 0;
- break;
- case RISCVOp::OPERAND_CLUI_IMM:
- Ok = (isUInt<5>(Imm) && Imm != 0) ||
- (Imm >= 0xfffe0 && Imm <= 0xfffff);
- break;
- case RISCVOp::OPERAND_RVKRNUM:
- Ok = Imm >= 0 && Imm <= 10;
- break;
- case RISCVOp::OPERAND_RVKRNUM_0_7:
- Ok = Imm >= 0 && Imm <= 7;
- break;
- case RISCVOp::OPERAND_RVKRNUM_1_10:
- Ok = Imm >= 1 && Imm <= 10;
- break;
- case RISCVOp::OPERAND_RVKRNUM_2_14:
- Ok = Imm >= 2 && Imm <= 14;
- break;
- case RISCVOp::OPERAND_RLIST:
- Ok = Imm >= RISCVZC::RA && Imm <= RISCVZC::RA_S0_S11;
- break;
- case RISCVOp::OPERAND_RLIST_S0:
- Ok = Imm >= RISCVZC::RA_S0 && Imm <= RISCVZC::RA_S0_S11;
- break;
- case RISCVOp::OPERAND_STACKADJ:
- Ok = Imm >= 0 && Imm <= 48 && Imm % 16 == 0;
- break;
- case RISCVOp::OPERAND_FRMARG:
+ case RISCVOp::OPERAND_UIMM2_LSB0:
+ Ok = isShiftedUInt<1, 1>(Imm);
+ break;
+ case RISCVOp::OPERAND_UIMM5_LSB0:
+ Ok = isShiftedUInt<4, 1>(Imm);
+ break;
+ case RISCVOp::OPERAND_UIMM5_NONZERO:
+ Ok = isUInt<5>(Imm) && (Imm != 0);
+ break;
+ case RISCVOp::OPERAND_UIMM5_GT3:
+ Ok = isUInt<5>(Imm) && (Imm > 3);
+ break;
+ case RISCVOp::OPERAND_UIMM5_PLUS1:
+ Ok = Imm >= 1 && Imm <= 32;
+ break;
+ case RISCVOp::OPERAND_UIMM6_LSB0:
+ Ok = isShiftedUInt<5, 1>(Imm);
+ break;
+ case RISCVOp::OPERAND_UIMM7_LSB00:
+ Ok = isShiftedUInt<5, 2>(Imm);
+ break;
+ case RISCVOp::OPERAND_UIMM7_LSB000:
+ Ok = isShiftedUInt<4, 3>(Imm);
+ break;
+ case RISCVOp::OPERAND_UIMM8_LSB00:
+ Ok = isShiftedUInt<6, 2>(Imm);
+ break;
+ case RISCVOp::OPERAND_UIMM8_LSB000:
+ Ok = isShiftedUInt<5, 3>(Imm);
+ break;
+ case RISCVOp::OPERAND_UIMM8_GE32:
+ Ok = isUInt<8>(Imm) && Imm >= 32;
+ break;
+ case RISCVOp::OPERAND_UIMM9_LSB000:
+ Ok = isShiftedUInt<6, 3>(Imm);
+ break;
+ case RISCVOp::OPERAND_SIMM8_UNSIGNED:
+ Ok = isInt<8>(Imm);
+ break;
+ case RISCVOp::OPERAND_SIMM10_LSB0000_NONZERO:
+ Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0);
+ break;
+ case RISCVOp::OPERAND_UIMM10_LSB00_NONZERO:
+ Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0);
+ break;
+ case RISCVOp::OPERAND_UIMM16_NONZERO:
+ Ok = isUInt<16>(Imm) && (Imm != 0);
+ break;
+ case RISCVOp::OPERAND_THREE:
+ Ok = Imm == 3;
+ break;
+ case RISCVOp::OPERAND_FOUR:
+ Ok = Imm == 4;
+ break;
+ case RISCVOp::OPERAND_IMM5_ZIBI:
+ Ok = (isUInt<5>(Imm) && Imm != 0) || Imm == -1;
+ break;
+ // clang-format off
+ CASE_OPERAND_SIMM(5)
+ CASE_OPERAND_SIMM(6)
+ CASE_OPERAND_SIMM(10)
+ CASE_OPERAND_SIMM(11)
+ CASE_OPERAND_SIMM(26)
+ // clang-format on
+ case RISCVOp::OPERAND_SIMM5_PLUS1:
+ Ok = Imm >= -15 && Imm <= 16;
+ break;
+ case RISCVOp::OPERAND_SIMM5_NONZERO:
+ Ok = isInt<5>(Imm) && (Imm != 0);
+ break;
+ case RISCVOp::OPERAND_SIMM6_NONZERO:
+ Ok = Imm != 0 && isInt<6>(Imm);
+ break;
+ case RISCVOp::OPERAND_VTYPEI10:
+ Ok = isUInt<10>(Imm);
+ break;
+ case RISCVOp::OPERAND_VTYPEI11:
+ Ok = isUInt<11>(Imm);
+ break;
+ case RISCVOp::OPERAND_SIMM12_LSB00000:
+ Ok = isShiftedInt<7, 5>(Imm);
+ break;
+ case RISCVOp::OPERAND_SIMM16_NONZERO:
+ Ok = isInt<16>(Imm) && (Imm != 0);
+ break;
+ case RISCVOp::OPERAND_SIMM20_LI:
+ Ok = isInt<20>(Imm);
+ break;
+ case RISCVOp::OPERAND_UIMMLOG2XLEN:
+ Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
+ break;
+ case RISCVOp::OPERAND_UIMMLOG2XLEN_NONZERO:
+ Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
+ Ok = Ok && Imm != 0;
+ break;
+ case RISCVOp::OPERAND_CLUI_IMM:
+ Ok = (isUInt<5>(Imm) && Imm != 0) || (Imm >= 0xfffe0 && Imm <= 0xfffff);
+ break;
+ case RISCVOp::OPERAND_RVKRNUM:
+ Ok = Imm >= 0 && Imm <= 10;
+ break;
+ case RISCVOp::OPERAND_RVKRNUM_0_7:
+ Ok = Imm >= 0 && Imm <= 7;
+ break;
+ case RISCVOp::OPERAND_RVKRNUM_1_10:
+ Ok = Imm >= 1 && Imm <= 10;
+ break;
+ case RISCVOp::OPERAND_RVKRNUM_2_14:
+ Ok = Imm >= 2 && Imm <= 14;
+ break;
+ case RISCVOp::OPERAND_RLIST:
+ Ok = Imm >= RISCVZC::RA && Imm <= RISCVZC::RA_S0_S11;
+ break;
+ case RISCVOp::OPERAND_RLIST_S0:
+ Ok = Imm >= RISCVZC::RA_S0 && Imm <= RISCVZC::RA_S0_S11;
+ break;
+ case RISCVOp::OPERAND_STACKADJ:
+ Ok = Imm >= 0 && Imm <= 48 && Imm % 16 == 0;
+ break;
+ case RISCVOp::OPERAND_FRMARG:
+ Ok = RISCVFPRndMode::isValidRoundingMode(Imm);
+ break;
+ case RISCVOp::OPERAND_RTZARG:
+ Ok = Imm == RISCVFPRndMode::RTZ;
+ break;
+ case RISCVOp::OPERAND_COND_CODE:
+ Ok = Imm >= 0 && Imm < RISCVCC::COND_INVALID;
+ break;
+ case RISCVOp::OPERAND_VEC_POLICY:
+ Ok = (Imm & (RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC)) ==
+ Imm;
+ break;
+ case RISCVOp::OPERAND_SEW:
+ Ok = (isUInt<5>(Imm) && RISCVVType::isValidSEW(1 << Imm));
+ break;
+ case RISCVOp::OPERAND_SEW_MASK:
+ Ok = Imm == 0;
+ break;
+ case RISCVOp::OPERAND_VEC_RM:
+ assert(RISCVII::hasRoundModeOp(Desc.TSFlags));
+ if (RISCVII::usesVXRM(Desc.TSFlags))
+ Ok = isUInt<2>(Imm);
+ else
Ok = RISCVFPRndMode::isValidRoundingMode(Imm);
- break;
- case RISCVOp::OPERAND_RTZARG:
- Ok = Imm == RISCVFPRndMode::RTZ;
- break;
- case RISCVOp::OPERAND_COND_CODE:
- Ok = Imm >= 0 && Imm < RISCVCC::COND_INVALID;
- break;
- case RISCVOp::OPERAND_VEC_POLICY:
- Ok = (Imm &
- (RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC)) == Imm;
- break;
- case RISCVOp::OPERAND_SEW:
- Ok = (isUInt<5>(Imm) && RISCVVType::isValidSEW(1 << Imm));
- break;
- case RISCVOp::OPERAND_SEW_MASK:
- Ok = Imm == 0;
- break;
- case RISCVOp::OPERAND_VEC_RM:
- assert(RISCVII::hasRoundModeOp(Desc.TSFlags));
- if (RISCVII::usesVXRM(Desc.TSFlags))
- Ok = isUInt<2>(Imm);
- else
- Ok = RISCVFPRndMode::isValidRoundingMode(Imm);
- break;
- case RISCVOp::OPERAND_XSFMM_VTYPE:
- Ok = RISCVVType::isValidXSfmmVType(Imm);
- break;
- }
- if (!Ok) {
- ErrInfo = "Invalid immediate";
- return false;
- }
+ break;
+ case RISCVOp::OPERAND_XSFMM_VTYPE:
+ Ok = RISCVVType::isValidXSfmmVType(Imm);
+ break;
+ }
+ if (!Ok) {
+ ErrInfo = "Invalid immediate";
+ return false;
+ }
+ } else if (OpType == RISCVOp::OPERAND_SIMM12_LO) {
+ // TODO: We could be stricter about what non-register operands are
+ // allowed.
+ if (MO.isReg()) {
+ ErrInfo = "Expected a non-register operand.";
+ return false;
+ }
+ if (MO.isImm() && !isInt<12>(MO.getImm())) {
+ ErrInfo = "Invalid immediate";
+ return false;
+ }
+ } else if (OpType == RISCVOp::OPERAND_UIMM20_LUI ||
+ OpType == RISCVOp::OPERAND_UIMM20_AUIPC) {
+ // TODO: We could be stricter about what non-register operands are
+ // allowed.
+ if (MO.isReg()) {
+ ErrInfo = "Expected a non-register operand.";
+ return false;
+ }
+ if (MO.isImm() && !isUInt<20>(MO.getImm())) {
+ ErrInfo = "Invalid immediate";
+ return false;
+ }
+ } else if (OpType == RISCVOp::OPERAND_BARE_SIMM32) {
+ // TODO: We could be stricter about what non-register operands are
+ // allowed.
+ if (MO.isReg()) {
+ ErrInfo = "Expected a non-register operand.";
+ return false;
+ }
+ if (MO.isImm() && !isInt<32>(MO.getImm())) {
+ ErrInfo = "Invalid immediate";
+ return false;
}
}
}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index a27c46ebf3a99..9a4eb12ca0eb0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -349,6 +349,7 @@ def simm12_lo : RISCVSImmLeafOp<12> {
return isInt<12>(Imm);
return MCOp.isBareSymbolRef();
}];
+ let OperandType = "OPERAND_SIMM12_LO";
}
// A 12-bit signed immediate which cannot fit in 6-bit signed immediate,
@@ -394,9 +395,11 @@ class UImm20OperandMaybeSym : RISCVUImmOp<20> {
def uimm20_lui : UImm20OperandMaybeSym {
let ParserMatchClass = UImmAsmOperand<20, "LUI">;
+ let OperandType = "OPERAND_UIMM20_LUI";
}
def uimm20_auipc : UImm20OperandMaybeSym {
let ParserMatchClass = UImmAsmOperand<20, "AUIPC">;
+ let OperandType = "OPERAND_UIMM20_AUIPC";
}
def uimm20 : RISCVUImmOp<20>;
|
🐧 Linux x64 Test Results
Failed Tests(click on a test name to see its output) LLVMLLVM.tools/llvm-exegesis/RISCV/latency-by-load.sIf these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the |
lenary
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
mshockwave
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/134/builds/30960 Here is the relevant piece of the build log for the reference |
…-only operands (llvm#170736) Most of the immediate operands can only be an immediate, but we were allowing any non-register operand. Split the immediate-only from the immediate or non-register operands. The non-register cases could be made even stricter, but I'll leave that as a TODO.
Most of the immediate operands can only be an immediate, but we were allowing any non-register operand.
Split the immediate-only from the immediate or non-register operands. The non-register cases could be made even stricter, but I'll leave that as a TODO.