[llvm] [TableGen][Decoder] Remove special case of single sub-op dag (PR #156175)
Sergei Barannikov via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 30 04:34:09 PDT 2025
https://github.com/s-barannikov created https://github.com/llvm/llvm-project/pull/156175
If a custom operand has MIOperandInfo with >= 2 sub-operands, it is required that either the custom operand or its sub-operands have a custom decoder method. There is no good reason why this rule should not apply to operands with only one sub-operand.
>From 4268afba0f39537b6c0b4443a6cd5f68eba5c9c4 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 30 Aug 2025 14:33:41 +0300
Subject: [PATCH] [TableGen][Decoder] Remove special case of single sub-op dag
If a custom operand has MIOperandInfo with >= 2 sub-operands, it is
required that either the custom operand or its sub-operands have
a custom decoder method. There is no good reason why this rule should
not apply to operands with only one sub-operand.
---
llvm/lib/Target/ARC/ARCInstrFormats.td | 2 --
llvm/lib/Target/ARC/ARCInstrInfo.td | 2 +-
llvm/lib/Target/ARM/ARMInstrInfo.td | 2 --
llvm/lib/Target/ARM/ARMInstrNEON.td | 4 ---
llvm/lib/Target/Lanai/LanaiInstrInfo.td | 16 +++++-----
llvm/lib/Target/PowerPC/PPCInstrFuture.td | 32 +++++++++----------
.../TableGen/Common/CodeGenInstruction.cpp | 13 ++++++--
llvm/utils/TableGen/DecoderEmitter.cpp | 13 +++-----
8 files changed, 39 insertions(+), 45 deletions(-)
diff --git a/llvm/lib/Target/ARC/ARCInstrFormats.td b/llvm/lib/Target/ARC/ARCInstrFormats.td
index bd2ed00576177..0560bb1dc9661 100644
--- a/llvm/lib/Target/ARC/ARCInstrFormats.td
+++ b/llvm/lib/Target/ARC/ARCInstrFormats.td
@@ -964,12 +964,10 @@ class F16_OP_U7<bit i, string asmstr> :
// Special types for different instruction operands.
def ccond : Operand<i32> {
- let MIOperandInfo = (ops i32imm);
let PrintMethod = "printPredicateOperand";
}
def brccond : Operand<i32> {
- let MIOperandInfo = (ops i32imm);
let PrintMethod = "printBRCCPredicateOperand";
}
diff --git a/llvm/lib/Target/ARC/ARCInstrInfo.td b/llvm/lib/Target/ARC/ARCInstrInfo.td
index f26b49119caba..8ff5f4a39ca7f 100644
--- a/llvm/lib/Target/ARC/ARCInstrInfo.td
+++ b/llvm/lib/Target/ARC/ARCInstrInfo.td
@@ -18,7 +18,7 @@ include "ARCInstrFormats.td"
// Operand for printing out a condition code.
let PrintMethod = "printCCOperand" in
- def CCOp : PredicateOperand<i32, (ops i32imm), (ops)>;
+ def CCOp : PredicateOperand<i32, (ops), (ops)>;
// The "u6" operand of a RRU6-type instruction
let PrintMethod = "printU6" in {
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index 4345f7a4a0ebc..a4d7a20305624 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -765,7 +765,6 @@ class MVEVectorIndexOperand<int NumLanes> : AsmOperandClass {
class MVEVectorIndex<int NumLanes> : Operand<i32> {
let PrintMethod = "printVectorIndex";
let ParserMatchClass = MVEVectorIndexOperand<NumLanes>;
- let MIOperandInfo = (ops i32imm);
}
// shift_imm: An integer that encodes a shift amount and the type of shift
@@ -1181,7 +1180,6 @@ def PostIdxImm8AsmOperand : AsmOperandClass { let Name = "PostIdxImm8"; }
def postidx_imm8 : MemOperand {
let PrintMethod = "printPostIdxImm8Operand";
let ParserMatchClass = PostIdxImm8AsmOperand;
- let MIOperandInfo = (ops i32imm);
}
// postidx_imm8s4 := +/- [0,1020]
diff --git a/llvm/lib/Target/ARM/ARMInstrNEON.td b/llvm/lib/Target/ARM/ARMInstrNEON.td
index 7485ef569445a..37f0103363b9a 100644
--- a/llvm/lib/Target/ARM/ARMInstrNEON.td
+++ b/llvm/lib/Target/ARM/ARMInstrNEON.td
@@ -95,28 +95,24 @@ def VectorIndex8 : Operand<i32>, ImmLeaf<i32, [{
}]> {
let ParserMatchClass = VectorIndex8Operand;
let PrintMethod = "printVectorIndex";
- let MIOperandInfo = (ops i32imm);
}
def VectorIndex16 : Operand<i32>, ImmLeaf<i32, [{
return ((uint64_t)Imm) < 4;
}]> {
let ParserMatchClass = VectorIndex16Operand;
let PrintMethod = "printVectorIndex";
- let MIOperandInfo = (ops i32imm);
}
def VectorIndex32 : Operand<i32>, ImmLeaf<i32, [{
return ((uint64_t)Imm) < 2;
}]> {
let ParserMatchClass = VectorIndex32Operand;
let PrintMethod = "printVectorIndex";
- let MIOperandInfo = (ops i32imm);
}
def VectorIndex64 : Operand<i32>, ImmLeaf<i32, [{
return ((uint64_t)Imm) < 1;
}]> {
let ParserMatchClass = VectorIndex64Operand;
let PrintMethod = "printVectorIndex";
- let MIOperandInfo = (ops i32imm);
}
// Register list of one D register.
diff --git a/llvm/lib/Target/Lanai/LanaiInstrInfo.td b/llvm/lib/Target/Lanai/LanaiInstrInfo.td
index 1d968fa391c2a..5129de047f953 100644
--- a/llvm/lib/Target/Lanai/LanaiInstrInfo.td
+++ b/llvm/lib/Target/Lanai/LanaiInstrInfo.td
@@ -540,15 +540,15 @@ let E = 0 in {
def LDBs_RR : LoadRR<"ld.b", sextloadi8, i32>;
}
-def LDADDR : InstSLS<0x0, (outs GPR:$Rd), (ins MEMi:$src),
+def LDADDR : InstSLS<0x0, (outs GPR:$Rd), (ins (MEMi $offset):$src),
"ld\t$src, $Rd",
[(set (i32 GPR:$Rd), (load ADDRsls:$src))]>,
Sched<[WriteLD]> {
- bits<21> src;
+ bits<21> offset;
let Itinerary = IIC_LD;
- let msb = src{20-16};
- let lsb = src{15-0};
+ let msb = offset{20-16};
+ let lsb = offset{15-0};
let isReMaterializable = 1;
let mayLoad = 1;
}
@@ -639,15 +639,15 @@ let E = 0 in {
def STB_RR : StoreRR<"st.b", truncstorei8, i32>;
}
-def STADDR : InstSLS<0x1, (outs), (ins GPR:$Rd, MEMi:$dst),
+def STADDR : InstSLS<0x1, (outs), (ins GPR:$Rd, (MEMi $offset):$dst),
"st\t$Rd, $dst",
[(store (i32 GPR:$Rd), ADDRsls:$dst)]>,
Sched<[WriteST]> {
- bits<21> dst;
+ bits<21> offset;
let Itinerary = IIC_ST;
- let msb = dst{20-16};
- let lsb = dst{15-0};
+ let msb = offset{20-16};
+ let lsb = offset{15-0};
let mayStore = 1;
}
diff --git a/llvm/lib/Target/PowerPC/PPCInstrFuture.td b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
index 80fac18d5737f..9eef7332f573b 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFuture.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
@@ -54,31 +54,31 @@ let Predicates = [IsISAFuture] in {
let Predicates = [HasVSX, IsISAFuture] in {
let mayLoad = 1 in {
def LXVRL
- : XX1Form_memOp<31, 525, (outs vsrc:$XT), (ins memr:$RA, g8rc:$RB),
- "lxvrl $XT, $RA, $RB", IIC_LdStLoad, []>;
+ : XX1Form_memOp<31, 525, (outs vsrc:$XT), (ins (memr $RA):$addr, g8rc:$RB),
+ "lxvrl $XT, $addr, $RB", IIC_LdStLoad, []>;
def LXVRLL
- : XX1Form_memOp<31, 557, (outs vsrc:$XT), (ins memr:$RA, g8rc:$RB),
- "lxvrll $XT, $RA, $RB", IIC_LdStLoad, []>;
+ : XX1Form_memOp<31, 557, (outs vsrc:$XT), (ins (memr $RA):$addr, g8rc:$RB),
+ "lxvrll $XT, $addr, $RB", IIC_LdStLoad, []>;
def LXVPRL
- : XForm_XTp5_XAB5<31, 589, (outs vsrprc:$XTp), (ins memr:$RA, g8rc:$RB),
- "lxvprl $XTp, $RA, $RB", IIC_LdStLFD, []>;
+ : XForm_XTp5_XAB5<31, 589, (outs vsrprc:$XTp), (ins (memr $RA):$addr, g8rc:$RB),
+ "lxvprl $XTp, $addr, $RB", IIC_LdStLFD, []>;
def LXVPRLL
- : XForm_XTp5_XAB5<31, 621, (outs vsrprc:$XTp), (ins memr:$RA, g8rc:$RB),
- "lxvprll $XTp, $RA, $RB", IIC_LdStLFD, []>;
+ : XForm_XTp5_XAB5<31, 621, (outs vsrprc:$XTp), (ins (memr $RA):$addr, g8rc:$RB),
+ "lxvprll $XTp, $addr, $RB", IIC_LdStLFD, []>;
}
let mayStore = 1 in {
def STXVRL
- : XX1Form_memOp<31, 653, (outs), (ins vsrc:$XT, memr:$RA, g8rc:$RB),
- "stxvrl $XT, $RA, $RB", IIC_LdStLoad, []>;
+ : XX1Form_memOp<31, 653, (outs), (ins vsrc:$XT, (memr $RA):$addr, g8rc:$RB),
+ "stxvrl $XT, $addr, $RB", IIC_LdStLoad, []>;
def STXVRLL
- : XX1Form_memOp<31, 685, (outs), (ins vsrc:$XT, memr:$RA, g8rc:$RB),
- "stxvrll $XT, $RA, $RB", IIC_LdStLoad, []>;
+ : XX1Form_memOp<31, 685, (outs), (ins vsrc:$XT, (memr $RA):$addr, g8rc:$RB),
+ "stxvrll $XT, $addr, $RB", IIC_LdStLoad, []>;
def STXVPRL : XForm_XTp5_XAB5<31, 717, (outs),
- (ins vsrprc:$XTp, memr:$RA, g8rc:$RB),
- "stxvprl $XTp, $RA, $RB", IIC_LdStLFD, []>;
+ (ins vsrprc:$XTp, (memr $RA):$addr, g8rc:$RB),
+ "stxvprl $XTp, $addr, $RB", IIC_LdStLFD, []>;
def STXVPRLL : XForm_XTp5_XAB5<31, 749, (outs),
- (ins vsrprc:$XTp, memr:$RA, g8rc:$RB),
- "stxvprll $XTp, $RA, $RB", IIC_LdStLFD, []>;
+ (ins vsrprc:$XTp, (memr $RA):$addr, g8rc:$RB),
+ "stxvprll $XTp, $addr, $RB", IIC_LdStLFD, []>;
}
}
diff --git a/llvm/utils/TableGen/Common/CodeGenInstruction.cpp b/llvm/utils/TableGen/Common/CodeGenInstruction.cpp
index da343e5e23177..bb96d0d5fe1bb 100644
--- a/llvm/utils/TableGen/Common/CodeGenInstruction.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenInstruction.cpp
@@ -143,15 +143,22 @@ CGIOperandList::CGIOperandList(const Record *R) : TheDef(R) {
MIOperandNo, NumOps, MIOpInfo);
if (SubArgDag) {
- if (SubArgDag->getNumArgs() != NumOps) {
+ if (!MIOpInfo) {
+ PrintFatalError(R->getLoc(), "In instruction '" + R->getName() +
+ "', operand #" + Twine(i) + " has " +
+ Twine(SubArgDag->getNumArgs()) +
+ " sub-arg names, but no sub-operands");
+ }
+ unsigned NumArgs = SubArgDag->getNumArgs();
+ if (NumArgs != MIOpInfo->getNumArgs()) {
PrintFatalError(R->getLoc(), "In instruction '" + R->getName() +
"', operand #" + Twine(i) + " has " +
Twine(SubArgDag->getNumArgs()) +
" sub-arg names, expected " +
- Twine(NumOps) + ".");
+ Twine(NumArgs) + ".");
}
- for (unsigned j = 0; j < NumOps; ++j) {
+ for (unsigned j = 0; j < NumArgs; ++j) {
if (!isa<UnsetInit>(SubArgDag->getArg(j)))
PrintFatalError(R->getLoc(),
"In instruction '" + R->getName() + "', operand #" +
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index f1db0368d0988..451e831d2dd5f 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -2023,17 +2023,12 @@ void InstructionEncoding::parseFixedLenOperands(const BitsInit &Bits) {
// Otherwise, if we have an operand with sub-operands, but they aren't
// named...
if (SubOps && OpInfo.Decoder.empty()) {
- // If it's a single sub-operand, and no custom decoder, use the decoder
- // from the one sub-operand.
- if (SubOps->getNumArgs() == 1)
- OpInfo = getOpInfo(cast<DefInit>(SubOps->getArg(0))->getDef());
-
- // If we have multiple sub-ops, there'd better have a custom
- // decoder. (Otherwise we don't know how to populate them properly...)
- if (SubOps->getNumArgs() > 1) {
+ // If we have sub-ops, we'd better have a custom decoder.
+ // (Otherwise we don't know how to populate them properly...)
+ if (SubOps->getNumArgs()) {
PrintError(EncodingDef,
"DecoderEmitter: operand \"" + OpName +
- "\" uses MIOperandInfo with multiple ops, but doesn't "
+ "\" has non-empty MIOperandInfo, but doesn't "
"have a custom decoder!");
debugDumpRecord(*EncodingDef);
continue;
More information about the llvm-commits
mailing list