[llvm] 700d1f0 - [TableGen] Support RegClassByHwMode in CompressPat
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 8 11:32:34 PST 2026
Author: Alexander Richardson
Date: 2026-01-08T11:32:30-08:00
New Revision: 700d1f029d00f6c1b6496f148f7d526e690c4643
URL: https://github.com/llvm/llvm-project/commit/700d1f029d00f6c1b6496f148f7d526e690c4643
DIFF: https://github.com/llvm/llvm-project/commit/700d1f029d00f6c1b6496f148f7d526e690c4643.diff
LOG: [TableGen] Support RegClassByHwMode in CompressPat
This does not yet handle all cases but at least for the simple
cases such as:
```
def : CompressPat<(PTR_MOV PtrRC:$dst, PtrRC:$src),
(PTR_MOV_SMALL PtrRC:$dst, PtrRC:$src)>;
```
tablegen generates sensible code instead of emitting confusing errors.
Reviewed By: arsenm
Pull Request: https://github.com/llvm/llvm-project/pull/171061
Added:
llvm/test/TableGen/RegClassByHwModeCompressPat.td
Modified:
llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
llvm/test/TableGen/RegClassByHwMode.td
llvm/utils/TableGen/CompressInstEmitter.cpp
llvm/utils/TableGen/InstrInfoEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
index 5abb5461f74b3..62cd6cca49c0e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "RISCVBaseInfo.h"
+#include "RISCVInstrInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
diff --git a/llvm/test/TableGen/RegClassByHwMode.td b/llvm/test/TableGen/RegClassByHwMode.td
index 97de81df1bea0..6c6d5ef9ecf85 100644
--- a/llvm/test/TableGen/RegClassByHwMode.td
+++ b/llvm/test/TableGen/RegClassByHwMode.td
@@ -66,6 +66,19 @@ include "Common/RegClassByHwModeCommon.td"
// INSTRINFO: static inline void InitMyTargetMCInstrInfo(
// INSTRINFO-NEXT: II->InitMCInstrInfo(MyTargetDescs.Insts, MyTargetInstrNameIndices, MyTargetInstrNameData, nullptr, nullptr, {{[0-9]+}}, &MyTargetRegClassByHwModeTables[0][0], 3);
+// INSTRINFO: #ifdef GET_INSTRINFO_HEADER
+// INSTRINFO-NEXT: #undef GET_INSTRINFO_HEADER
+// INSTRINFO-EMPTY:
+// INSTRINFO-NEXT: namespace llvm {
+// INSTRINFO-EMPTY:
+// INSTRINFO-NEXT: struct MyTargetGenInstrInfo : public TargetInstrInfo {
+// INSTRINFO-NEXT: explicit MyTargetGenInstrInfo(const TargetSubtargetInfo &STI, const TargetRegisterInfo &TRI, unsigned CFSetupOpcode = ~0u, unsigned CFDestroyOpcode = ~0u, unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);
+// INSTRINFO-NEXT: ~MyTargetGenInstrInfo() override = default;
+// INSTRINFO-NEXT: };
+// INSTRINFO-NEXT: extern const int16_t MyTargetRegClassByHwModeTables[4][3];
+// INSTRINFO-EMPTY:
+// INSTRINFO-NEXT: } // namespace llvm
+// INSTRINFO: #endif // GET_INSTRINFO_HEADER
// ASMMATCHER: enum MatchClassKind {
diff --git a/llvm/test/TableGen/RegClassByHwModeCompressPat.td b/llvm/test/TableGen/RegClassByHwModeCompressPat.td
new file mode 100644
index 0000000000000..d642584e52b37
--- /dev/null
+++ b/llvm/test/TableGen/RegClassByHwModeCompressPat.td
@@ -0,0 +1,318 @@
+// RUN: llvm-tblgen --gen-compress-inst-emitter -I %p/../../include -I %S %s -o - | FileCheck %s
+
+include "Common/RegClassByHwModeCommon.td"
+
+def IsPtr64 : Predicate<"Subtarget->isPtr64()">;
+defvar Ptr32 = DefaultMode;
+def Ptr64 : HwMode<[IsPtr64]>;
+def PtrRC : RegClassByHwMode<[Ptr32, Ptr64], [XRegs, YRegs]>;
+
+
+def X_MOV : TestInstruction {
+ let OutOperandList = (outs XRegs:$dst);
+ let InOperandList = (ins XRegs:$src);
+ let AsmString = "x_mov $dst, $src";
+ let opcode = 0;
+}
+
+def X_MOV_SMALL : TestInstruction {
+ let OutOperandList = (outs XRegs:$dst);
+ let InOperandList = (ins XRegs:$src);
+ let AsmString = "x_mov.small $dst, $src";
+ let opcode = 1;
+ let Size = 1;
+}
+def X_MOV_ZERO : TestInstruction {
+ let OutOperandList = (outs XRegs:$dst);
+ let InOperandList = (ins);
+ let AsmString = "x_mov.zero $dst";
+ let opcode = 2;
+ let Size = 1;
+}
+def X_MOV_TIED : TestInstruction {
+ let OutOperandList = (outs XRegs:$dst);
+ let InOperandList = (ins XRegs:$src);
+ let Constraints = "$src = $dst";
+ let AsmString = "x_mov.tied $dst, $src";
+ let opcode = 3;
+ let Size = 1;
+}
+
+def PTR_MOV : TestInstruction {
+ let OutOperandList = (outs PtrRC:$dst);
+ let InOperandList = (ins PtrRC:$src);
+ let AsmString = "ptr_mov $dst, $src";
+ let opcode = 3;
+}
+
+def PTR_MOV_SMALL : TestInstruction {
+ let OutOperandList = (outs PtrRC:$dst);
+ let InOperandList = (ins PtrRC:$src);
+ let AsmString = "ptr_mov.small $dst, $src";
+ let opcode = 4;
+ let Size = 1;
+}
+def PTR_MOV_ZERO : TestInstruction {
+ let OutOperandList = (outs PtrRC:$dst);
+ let InOperandList = (ins);
+ let AsmString = "ptr_mov.zero $dst";
+ let opcode = 3;
+ let Size = 1;
+}
+def PTR_MOV_TIED : TestInstruction {
+ let OutOperandList = (outs PtrRC:$dst);
+ let InOperandList = (ins PtrRC:$src);
+ let Constraints = "$src = $dst";
+ let AsmString = "ptr_mov.tied $dst, $src";
+ let opcode = 3;
+ let Size = 1;
+}
+
+def : CompressPat<(X_MOV XRegs:$dst, X0),
+ (X_MOV_ZERO XRegs:$dst)>;
+def : CompressPat<(X_MOV XRegs:$dst, XRegs:$dst),
+ (X_MOV_TIED XRegs:$dst)>;
+def : CompressPat<(X_MOV XRegs:$dst, XRegs:$src),
+ (X_MOV_SMALL XRegs:$dst, XRegs:$src)>;
+// TODO: Should also be able to use a fixed register with RegClassByHwMode
+// def : CompressPat<(PTR_MOV PtrRC:$dst, X0),
+// (PTR_MOV_ZERO PtrRC:$dst)>;
+def : CompressPat<(PTR_MOV PtrRC:$dst, PtrRC:$dst),
+ (PTR_MOV_TIED PtrRC:$dst)>;
+def : CompressPat<(PTR_MOV PtrRC:$dst, PtrRC:$src),
+ (PTR_MOV_SMALL PtrRC:$dst, PtrRC:$src)>;
+
+// CHECK: static bool compressInst(MCInst &OutInst,
+// CHECK-NEXT: const MCInst &MI,
+// CHECK-NEXT: const MCSubtargetInfo &STI) {
+// CHECK-NEXT: {{\[\[}}maybe_unused]] unsigned HwModeId = STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo);
+// CHECK-NEXT: switch (MI.getOpcode()) {
+// CHECK-NEXT: default: return false;
+// CHECK-NEXT: case MyTarget::PTR_MOV: {
+// CHECK-NEXT: if (MI.getOperand(1).isReg() && MI.getOperand(0).isReg() &&
+// CHECK-NEXT: (MI.getOperand(1).getReg() == MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(1).getReg())) {
+// CHECK-NEXT: // ptr_mov.tied $dst, $src
+// CHECK-NEXT: OutInst.setOpcode(MyTarget::PTR_MOV_TIED);
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
+// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(1).getReg())) {
+// CHECK-NEXT: // ptr_mov.small $dst, $src
+// CHECK-NEXT: OutInst.setOpcode(MyTarget::PTR_MOV_SMALL);
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
+// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: break;
+// CHECK-NEXT: } // case PTR_MOV
+// CHECK-NEXT: case MyTarget::X_MOV: {
+// CHECK-NEXT: if (MI.getOperand(1).isReg() &&
+// CHECK-NEXT: (MI.getOperand(1).getReg() == MyTarget::X0) &&
+// CHECK-NEXT: MI.getOperand(0).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg())) {
+// CHECK-NEXT: // x_mov.zero $dst
+// CHECK-NEXT: OutInst.setOpcode(MyTarget::X_MOV_ZERO);
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
+// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: if (MI.getOperand(1).isReg() && MI.getOperand(0).isReg() &&
+// CHECK-NEXT: (MI.getOperand(1).getReg() == MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(1).getReg())) {
+// CHECK-NEXT: // x_mov.tied $dst, $src
+// CHECK-NEXT: OutInst.setOpcode(MyTarget::X_MOV_TIED);
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
+// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(1).getReg())) {
+// CHECK-NEXT: // x_mov.small $dst, $src
+// CHECK-NEXT: OutInst.setOpcode(MyTarget::X_MOV_SMALL);
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
+// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: break;
+// CHECK-NEXT: } // case X_MOV
+// CHECK-NEXT: } // switch
+// CHECK-NEXT: return false;
+// CHECK-NEXT: }
+
+// CHECK: static bool uncompressInst(MCInst &OutInst,
+// CHECK-NEXT: const MCInst &MI,
+// CHECK-NEXT: const MCSubtargetInfo &STI) {
+// CHECK-NEXT: {{\[\[}}maybe_unused]] unsigned HwModeId = STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo);
+// CHECK-NEXT: switch (MI.getOpcode()) {
+// CHECK-NEXT: default: return false;
+// CHECK-NEXT: case MyTarget::PTR_MOV_SMALL: {
+// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(1).getReg())) {
+// CHECK-NEXT: // ptr_mov $dst, $src
+// CHECK-NEXT: OutInst.setOpcode(MyTarget::PTR_MOV);
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
+// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: break;
+// CHECK-NEXT: } // case PTR_MOV_SMALL
+// CHECK-NEXT: case MyTarget::PTR_MOV_TIED: {
+// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(0).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(0).getReg())) {
+// CHECK-NEXT: // ptr_mov $dst, $src
+// CHECK-NEXT: OutInst.setOpcode(MyTarget::PTR_MOV);
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
+// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: break;
+// CHECK-NEXT: } // case PTR_MOV_TIED
+// CHECK-NEXT: case MyTarget::X_MOV_SMALL: {
+// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(1).getReg())) {
+// CHECK-NEXT: // x_mov $dst, $src
+// CHECK-NEXT: OutInst.setOpcode(MyTarget::X_MOV);
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(1));
+// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: break;
+// CHECK-NEXT: } // case X_MOV_SMALL
+// CHECK-NEXT: case MyTarget::X_MOV_TIED: {
+// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(0).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg())) {
+// CHECK-NEXT: // x_mov $dst, $src
+// CHECK-NEXT: OutInst.setOpcode(MyTarget::X_MOV);
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
+// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: break;
+// CHECK-NEXT: } // case X_MOV_TIED
+// CHECK-NEXT: case MyTarget::X_MOV_ZERO: {
+// CHECK-NEXT: if (MI.getOperand(0).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg())) {
+// CHECK-NEXT: // x_mov $dst, $src
+// CHECK-NEXT: OutInst.setOpcode(MyTarget::X_MOV);
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: OutInst.addOperand(MI.getOperand(0));
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: OutInst.addOperand(MCOperand::createReg(MyTarget::X0));
+// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: break;
+// CHECK-NEXT: } // case X_MOV_ZERO
+// CHECK-NEXT: } // switch
+// CHECK-NEXT: return false;
+// CHECK-NEXT: }
+
+// CHECK: static bool isCompressibleInst(const MachineInstr &MI,
+// CHECK-NEXT: const MyTargetSubtarget &STI) {
+// CHECK-NEXT: {{\[\[}}maybe_unused]] unsigned HwModeId = STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo);
+// CHECK-NEXT: switch (MI.getOpcode()) {
+// CHECK-NEXT: default: return false;
+// CHECK-NEXT: case MyTarget::PTR_MOV: {
+// CHECK-NEXT: if (MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isPhysical() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() && MI.getOperand(1).getReg().isPhysical() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(1).getReg())) {
+// CHECK-NEXT: // ptr_mov.small $dst, $src
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: if (MI.getOperand(1).isReg() && MI.getOperand(0).isReg() &&
+// CHECK-NEXT: (MI.getOperand(1).getReg() == MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() && MI.getOperand(1).getReg().isPhysical() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTargetRegClassByHwModeTables[HwModeId][MyTarget::PtrRC]].contains(MI.getOperand(1).getReg())) {
+// CHECK-NEXT: // ptr_mov.tied $dst, $src
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: break;
+// CHECK-NEXT: } // case PTR_MOV
+// CHECK-NEXT: case MyTarget::X_MOV: {
+// CHECK-NEXT: if (MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isPhysical() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() && MI.getOperand(1).getReg().isPhysical() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(1).getReg())) {
+// CHECK-NEXT: // x_mov.small $dst, $src
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: if (MI.getOperand(1).isReg() && MI.getOperand(0).isReg() &&
+// CHECK-NEXT: (MI.getOperand(1).getReg() == MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() && MI.getOperand(1).getReg().isPhysical() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(1).getReg())) {
+// CHECK-NEXT: // x_mov.tied $dst, $src
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: // Operand: src
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: if (MI.getOperand(1).isReg() &&
+// CHECK-NEXT: (MI.getOperand(1).getReg() == MyTarget::X0) &&
+// CHECK-NEXT: MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isPhysical() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::XRegsRegClassID].contains(MI.getOperand(0).getReg())) {
+// CHECK-NEXT: // x_mov.zero $dst
+// CHECK-NEXT: // Operand: dst
+// CHECK-NEXT: return true;
+// CHECK-NEXT: } // if
+// CHECK-NEXT: break;
+// CHECK-NEXT: } // case X_MOV
+// CHECK-NEXT: } // switch
+// CHECK-NEXT: return false;
+// CHECK-NEXT: }
+
+def MyTargetISA : InstrInfo;
+def MyTargetAsmWriter : AsmWriter {
+ int PassSubtarget = 1;
+}
+def MyTarget : Target {
+ let InstructionSet = MyTargetISA;
+ let AssemblyWriters = [MyTargetAsmWriter];
+}
diff --git a/llvm/utils/TableGen/CompressInstEmitter.cpp b/llvm/utils/TableGen/CompressInstEmitter.cpp
index 94fe3823fae22..1dce0baa5f898 100644
--- a/llvm/utils/TableGen/CompressInstEmitter.cpp
+++ b/llvm/utils/TableGen/CompressInstEmitter.cpp
@@ -630,6 +630,10 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
FuncH << "static bool isCompressibleInst(const MachineInstr &MI,\n";
FuncH.indent(31) << "const " << TargetName << "Subtarget &STI) {\n";
}
+ // HwModeId is used if we have any RegClassByHwMode patterns
+ if (!Target.getAllRegClassByHwMode().empty())
+ FuncH.indent(2) << "[[maybe_unused]] unsigned HwModeId = "
+ << "STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo);\n";
if (CompressPatterns.empty()) {
OS << FH;
@@ -735,7 +739,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
switch (SourceOperandMap[OpNo].Kind) {
case OpData::Operand:
if (SourceOperandMap[OpNo].OpInfo.TiedOpIdx != -1) {
- if (Source.Operands[OpNo].Rec->isSubClassOf("RegisterClass"))
+ if (Source.Operands[OpNo].Rec->isSubClassOf("RegisterClassLike"))
CondStream << CondSep << "MI.getOperand(" << OpNo
<< ").isReg() && MI.getOperand("
<< SourceOperandMap[OpNo].OpInfo.TiedOpIdx
@@ -788,11 +792,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
const Record *DagRec = DestOperandMap[OpNo].OpInfo.DagRec;
// Check that the operand in the Source instruction fits
// the type for the Dest instruction.
- if (DagRec->isSubClassOf("RegisterClass") ||
- DagRec->isSubClassOf("RegisterOperand")) {
- auto *ClassRec = DagRec->isSubClassOf("RegisterClass")
- ? DagRec
- : DagRec->getValueAsDef("RegClass");
+ if (auto *ClassRec = Target.getAsRegClassLike(DagRec)) {
// This is a register operand. Check the register class.
// Don't check register class if this is a tied operand, it was done
// for the operand it's tied to.
@@ -801,9 +801,15 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
if (EType == EmitterType::CheckCompress)
CondStream << " && MI.getOperand(" << OpIdx
<< ").getReg().isPhysical()";
- CondStream << CondSep << TargetName << "MCRegisterClasses["
- << TargetName << "::" << ClassRec->getName()
- << "RegClassID].contains(MI.getOperand(" << OpIdx
+ CondStream << CondSep << TargetName << "MCRegisterClasses[";
+ if (ClassRec->isSubClassOf("RegClassByHwMode")) {
+ CondStream << TargetName << "RegClassByHwModeTables[HwModeId]["
+ << TargetName << "::" << ClassRec->getName() << "]";
+ } else {
+ CondStream << TargetName << "::" << ClassRec->getName()
+ << "RegClassID";
+ }
+ CondStream << "].contains(MI.getOperand(" << OpIdx
<< ").getReg())";
}
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index cae1fb9b7bb7f..8442ad0dc0edd 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -1169,6 +1169,13 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
"unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);\n"
<< " ~" << ClassName << "() override = default;\n"
<< "};\n";
+
+ // Declare RegClassByHwModeTables, so that other files can use this
+ // without having to indirect via MCInstInfo.
+ if (NumClassesByHwMode != 0) {
+ OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
+ << NumModes << "][" << NumClassesByHwMode << "];\n";
+ }
} // end llvm namespace.
OS << "\n";
@@ -1205,11 +1212,6 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
OS << "extern const char " << TargetName << "InstrNameData[];\n";
- if (NumClassesByHwMode != 0) {
- OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
- << NumModes << "][" << NumClassesByHwMode << "];\n";
- }
-
if (HasDeprecationFeatures)
OS << "extern const uint8_t " << TargetName
<< "InstrDeprecationFeatures[];\n";
More information about the llvm-commits
mailing list