[llvm-branch-commits] [TableGen] Support HwMode registers in CompressInstEmitter (PR #203599)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Jun 12 11:04:04 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Alexander Richardson (arichardson)
<details>
<summary>Changes</summary>
This patch introduces a small helper (HwModePredicates) in CodeGenHwModes
to resolve HwModeSelect records (like RegisterByHwMode/RegClassByHwMode)
using subtarget features.
If all the predicates ensure that a specific register class is selected
(or lack of all of them results in DefaultMode), we can correctly validate
compress patterns involving HwMode-dependent registers and types.
This allows using a single instruction for RVY C_ADDI4SPN/C_ADDI16SP
instead of having to duplicate it for both modes (which was the previous
approach).
Let me know if you think this complexity is worth adding or if I should
just use the duplicated instructions approach.
As you can probably tell, the `struct HwModePredicates` is fully AI
generated, but if this approach sounds good I'll clean it up and see if it
can be simplified futher.
Assisted-by: Gemini
---
Patch is 53.16 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/203599.diff
13 Files Affected:
- (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (-6)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoC.td (+8-14)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+6-4)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoY.td (+2-29)
- (modified) llvm/test/MC/RISCV/rvy/rvyc-valid-addi.s (+4-6)
- (modified) llvm/test/TableGen/RegClassByHwModeCompressPat.td (+106-1)
- (added) llvm/test/TableGen/RegClassByHwModeCompressPat4Modes.td (+116)
- (added) llvm/test/TableGen/RegClassByHwModeCompressPatError.td (+92)
- (modified) llvm/utils/TableGen/Common/CodeGenHwModes.cpp (+209)
- (modified) llvm/utils/TableGen/Common/CodeGenHwModes.h (+10)
- (modified) llvm/utils/TableGen/Common/SubtargetFeatureInfo.cpp (+43)
- (modified) llvm/utils/TableGen/Common/SubtargetFeatureInfo.h (+20)
- (modified) llvm/utils/TableGen/CompressInstEmitter.cpp (+51-63)
``````````diff
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index c7dbdcd5fab78..6afd894ada7ce 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -115,12 +115,6 @@ static DecodeStatus DecodeGPRX1RegisterClass(MCInst &Inst,
return MCDisassembler::Success;
}
-static DecodeStatus DecodeSP_XRegisterClass(MCInst &Inst,
- const MCDisassembler *Decoder) {
- Inst.addOperand(MCOperand::createReg(RISCV::X2));
- return MCDisassembler::Success;
-}
-
static DecodeStatus DecodeSP_XRegisterClass(MCInst &Inst, uint64_t RegNo,
uint32_t Address,
const MCDisassembler *Decoder) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
index b3b28cfc17813..8b0eb3a2e2d19 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
@@ -266,13 +266,9 @@ class CA_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr>
let Predicates = [HasStdExtZca] in {
-// Ideally we would reuse C_ADDI16SP for StdExtY, but since the CompressPat
-// uses instructions with different register classes (ADDI vs YADDI) we can't
-// do this yet. Instead, add a variant of the instruction in RISCVInstrInfoY.td.
-let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
- append Predicates = [NotStdExtYCapMode] in
-def C_ADDI4SPN : RVInst16CIW<0b000, OPC_C0, (outs GPRC:$rd),
- (ins SP_X:$rs1, uimm10_lsb00nonzero:$imm),
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def C_ADDI4SPN : RVInst16CIW<0b000, OPC_C0, (outs BasePtrCRegClass:$rd),
+ (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
"c.addi4spn", "$rd, $rs1, $imm">,
Sched<[WriteIALU, ReadIALU]> {
bits<0> rs1;
@@ -374,13 +370,9 @@ def C_LI : RVInst16CI<0b010, OPC_C1, (outs GPR:$rd), (ins simm6:$imm),
"c.li", "$rd, $imm">,
Sched<[WriteIALU]>;
-// Ideally we would reuse C_ADDI16SP for StdExtY, but since the CompressPat
-// uses instructions with different register classes (ADDI vs YADDI) we can't
-// do this yet. Instead, add a variant of the instruction in RISCVInstrInfoY.td.
-let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
- append Predicates = [NotStdExtYCapMode] in
-def C_ADDI16SP : RVInst16CI<0b011, OPC_C1, (outs SP_X:$rd_wb),
- (ins SP_X:$rd, simm10_lsb0000nonzero:$imm),
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def C_ADDI16SP : RVInst16CI<0b011, OPC_C1, (outs SP:$rd_wb),
+ (ins SP:$rd, simm10_lsb0000nonzero:$imm),
"c.addi16sp", "$rd, $imm">,
Sched<[WriteIALU, ReadIALU]> {
let Constraints = "$rd = $rd_wb";
@@ -753,6 +745,7 @@ def : InstAlias<".insn_cj $opcode, $funct3, $imm11",
// Quadrant 0
let Predicates = [HasStdExtZca] in {
+let append Predicates = [NotStdExtYCapMode] in
def : CompressPat<(ADDI GPRC:$rd, SP_X:$rs1, uimm10_lsb00nonzero:$imm),
(C_ADDI4SPN GPRC:$rd, SP_X:$rs1, uimm10_lsb00nonzero:$imm)>;
@@ -799,6 +792,7 @@ def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
(C_LI GPRNoX0:$rd, simm6:$imm)>;
+let append Predicates = [NotStdExtYCapMode] in
def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
(C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index c00acbcb6f40c..8866a1f6aa4d9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -623,7 +623,7 @@ class QCIMVCCI<bits<3> funct3, string opcodestr, DAGOperand immType>
opcodestr, "$rd, $rs1, $imm, $rs3">,
Sched<[WriteIALU, ReadIALU, ReadIALU, ReadIALU]> {
bits<5> imm;
-
+
let Constraints = "$rd = $rd_wb";
let rs2 = imm;
}
@@ -1992,10 +1992,12 @@ def : CompressPat<(QC_E_ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
(C_ANDI GPRC:$rs1, simm6:$imm)>;
def : CompressPat<(QC_E_ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
(C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
+let append Predicates = [NotStdExtYCapMode] in {
def : CompressPat<(QC_E_ADDAI X2, simm10_lsb0000nonzero:$imm),
(C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
def : CompressPat<(QC_E_ADDI X2, X2, simm10_lsb0000nonzero:$imm),
(C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
+}
def : CompressPat<(QC_E_ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, simm12_lo:$imm),
(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, simm12_lo:$imm)>;
@@ -2066,7 +2068,7 @@ def : CompressPat<(QC_E_BLTUI GPRNoX0:$rs1, uimm5nonzero:$imm5, bare_simm13_lsb0
// How the bug happens is:
// - QC.E.LI is parsed with a bare symbol, which is valid + expected, and can
// be handled by fixups/relocations.
-// - Compression turns this into a `C.LI` because the `simm6`
+// - Compression turns this into a `C.LI` because the `simm6`
// MCOperandPredicate accepts bare symbols.
// - Binary Code emission didn't know how to create a fixup for a CI-type
// instruction containing a bare symbol.
@@ -2077,7 +2079,7 @@ def : CompressPat<(QC_E_BLTUI GPRNoX0:$rs1, uimm5nonzero:$imm5, bare_simm13_lsb0
//
// This is good enough for emitting objects, but doesn't work for emitting
// assembly. Emitting assembly is why we need the following Hacks.
-//
+//
// Emitting an instruction to assembly proceeds as:
// - Compression (in emitInstruction)
// - Decompression (in RISCVInstPrinter::printInst)
@@ -2086,7 +2088,7 @@ def : CompressPat<(QC_E_BLTUI GPRNoX0:$rs1, uimm5nonzero:$imm5, bare_simm13_lsb0
// So in the case of `QC.E.LI` with a bare symbol, first it is compressed to
// `C.LI` with a bare symbol, and then it is decompressed to `ADDI` with a bare
// symbol for printing, which is printed via an alias as `li <reg>, <symbol>`.
-// Both the decompression and the alias use the MCOperandPredicate from
+// Both the decompression and the alias use the MCOperandPredicate from
// `simm12`, which accepts bare symbols.
//
// The problem here is that `li <reg>, <symbol>` fails to parse, because the
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoY.td b/llvm/lib/Target/RISCV/RISCVInstrInfoY.td
index 4f588a4a7c695..95554cebe8731 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoY.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoY.td
@@ -220,37 +220,10 @@ def : CompressPat<(SY YGPR:$rs2, SPMem:$rs1, uimm9_lsb000:$imm),
} // Predicates = [HasStdExtZca, IsStdExtYCapMode, IsRV32]
let Predicates = [HasStdExtZca, IsStdExtYCapMode] in {
-// Ideally, we would reuse C_ADDI4SPN/C_ADDI16SP with SP:$rs1, but since the
-// CompressPat uses instructions with different register classes (ADDI vs YADDI)
-// we can't do this until tablegen resolves predicates in CompressPat.
-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, DecoderNamespace = "RVY" in {
-def C_YADDI4SPN : RVInst16CIW<0b000, OPC_C0, (outs YGPRC:$rd),
- (ins SP_Y:$rs1, uimm10_lsb00nonzero:$imm),
- "c.addi4spn", "$rd, $rs1, $imm">,
- Sched<[WriteIALU, ReadIALU]> {
- bits<0> rs1;
- let Inst{12-11} = imm{5-4};
- let Inst{10-7} = imm{9-6};
- let Inst{6} = imm{2};
- let Inst{5} = imm{3};
-}
-def C_YADDI16SP : RVInst16CI<0b011, OPC_C1, (outs SP_Y:$rd_wb),
- (ins SP_Y:$rd, simm10_lsb0000nonzero:$imm),
- "c.addi16sp", "$rd, $imm">,
- Sched<[WriteIALU, ReadIALU]> {
- let Constraints = "$rd = $rd_wb";
- let rd = 2;
- let Inst{12} = imm{9};
- let Inst{6} = imm{4};
- let Inst{5} = imm{6};
- let Inst{4-3} = imm{8-7};
- let Inst{2} = imm{5};
-}
-} // hasSideEffects = 0, mayLoad = 0, mayStore = 0, DecoderNamespace = "RVY"
def : CompressPat<(YADDI YGPRC:$rd, SP_Y:$rs1, uimm10_lsb00nonzero:$imm),
- (C_YADDI4SPN YGPRC:$rd, SP_Y:$rs1, uimm10_lsb00nonzero:$imm)>;
+ (C_ADDI4SPN YGPRC:$rd, SP_Y:$rs1, uimm10_lsb00nonzero:$imm)>;
def : CompressPat<(YADDI X2_Y, X2_Y, simm10_lsb0000nonzero:$imm),
- (C_YADDI16SP X2_Y, simm10_lsb0000nonzero:$imm)>;
+ (C_ADDI16SP X2_Y, simm10_lsb0000nonzero:$imm)>;
} // Predicates = [HasStdExtZca, IsStdExtYCapMode]
let Predicates = [HasStdExtZca, IsStdExtYCapMode, IsRV64] in {
diff --git a/llvm/test/MC/RISCV/rvy/rvyc-valid-addi.s b/llvm/test/MC/RISCV/rvy/rvyc-valid-addi.s
index 88cf60884c966..bcbd67169da94 100644
--- a/llvm/test/MC/RISCV/rvy/rvyc-valid-addi.s
+++ b/llvm/test/MC/RISCV/rvy/rvyc-valid-addi.s
@@ -20,8 +20,7 @@
c.addi4spn a0, sp, 12
// CHECK-ASM-AND-OBJ: c.addi4spn a0, sp, 12
// CHECK-ASM-SAME: # encoding: [0x68,0x00]
-// CHECK-INT-NEXT: # <MCInst #[[#]] C_ADDI4SPN{{$}}
-// CHECK-CAP-NEXT: # <MCInst #[[#]] C_YADDI4SPN{{$}}
+// CHECK-ASM-NEXT: # <MCInst #[[#]] C_ADDI4SPN{{$}}
// CHECK-INT-NEXT: # <MCOperand Reg:X10>
// CHECK-CAP-NEXT: # <MCOperand Reg:X10_Y>
// CHECK-INT-NEXT: # <MCOperand Reg:X2>
@@ -31,8 +30,7 @@ c.addi4spn a0, sp, 12
c.addi16sp sp, 16
// CHECK-ASM-AND-OBJ: c.addi16sp sp, 16
// CHECK-ASM-SAME: # encoding: [0x41,0x61]
-// CHECK-INT-NEXT: # <MCInst #[[#]] C_ADDI16SP{{$}}
-// CHECK-CAP-NEXT: # <MCInst #[[#]] C_YADDI16SP{{$}}
+// CHECK-ASM-NEXT: # <MCInst #[[#]] C_ADDI16SP{{$}}
// CHECK-INT-NEXT: # <MCOperand Reg:X2>
// CHECK-CAP-NEXT: # <MCOperand Reg:X2_Y>
// CHECK-INT-NEXT: # <MCOperand Reg:X2>
@@ -56,7 +54,7 @@ yaddi a0, sp, 12
// CHECK-CAP-ASM-AND-OBJ: c.addi4spn a0, sp, 12
// CHECK-CAP-SAME: # encoding: [0x68,0x00]
// CHECK-INT-NEXT: # <MCInst #[[#]] YADDI{{$}}
-// CHECK-CAP-NEXT: # <MCInst #[[#]] C_YADDI4SPN{{$}}
+// CHECK-CAP-NEXT: # <MCInst #[[#]] C_ADDI4SPN{{$}}
// CHECK-ASM-NEXT: # <MCOperand Reg:X10_Y>
// CHECK-ASM-NEXT: # <MCOperand Reg:X2_Y>
// CHECK-ASM-NEXT: # <MCOperand Imm:12>>
@@ -67,7 +65,7 @@ yaddi sp, sp, 16
// CHECK-CAP-ASM-AND-OBJ: c.addi16sp sp, 16
// CHECK-CAP-SAME: # encoding: [0x41,0x61]
// CHECK-INT-NEXT: # <MCInst #[[#]] YADDI{{$}}
-// CHECK-CAP-NEXT: # <MCInst #[[#]] C_YADDI16SP{{$}}
+// CHECK-CAP-NEXT: # <MCInst #[[#]] C_ADDI16SP{{$}}
// CHECK-ASM-NEXT: # <MCOperand Reg:X2_Y>
// CHECK-ASM-NEXT: # <MCOperand Reg:X2_Y>
// CHECK-ASM-NEXT: # <MCOperand Imm:16>>
diff --git a/llvm/test/TableGen/RegClassByHwModeCompressPat.td b/llvm/test/TableGen/RegClassByHwModeCompressPat.td
index cbe686848c4c4..4837851f2a8e7 100644
--- a/llvm/test/TableGen/RegClassByHwModeCompressPat.td
+++ b/llvm/test/TableGen/RegClassByHwModeCompressPat.td
@@ -2,7 +2,12 @@
include "Common/RegClassByHwModeCommon.td"
-def IsPtr64 : Predicate<"Subtarget->isPtr64()">;
+def FeaturePtr64 : SubtargetFeature<"ptr64", "IsPtr64", "true", "Ptr64 mode">;
+
+def IsPtr64 : Predicate<"Subtarget->isPtr64()">,
+ AssemblerPredicate<(all_of FeaturePtr64)>;
+def NotPtr64 : Predicate<"!Subtarget->isPtr64()">,
+ AssemblerPredicate<(all_of (not FeaturePtr64))>;
defvar Ptr32 = DefaultMode;
def Ptr64 : HwMode<[IsPtr64]>;
def PtrRC : RegClassByHwMode<[Ptr32, Ptr64], [XRegs, YRegs]>;
@@ -38,6 +43,13 @@ def X_MOV_TIED : TestInstruction {
let Size = 1;
}
+def Y_MOV : TestInstruction {
+ let OutOperandList = (outs YRegs:$dst);
+ let InOperandList = (ins YRegs:$src);
+ let AsmString = "y_mov $dst, $src";
+ let opcode = 5;
+}
+
def PTR_MOV : TestInstruction {
let OutOperandList = (outs PtrRC:$dst);
let InOperandList = (ins PtrRC:$src);
@@ -81,6 +93,17 @@ def : CompressPat<(PTR_MOV PtrRC:$dst, PtrRC:$dst),
def : CompressPat<(PTR_MOV PtrRC:$dst, PtrRC:$src),
(PTR_MOV_SMALL PtrRC:$dst, PtrRC:$src)>;
+// Test compression/uncompression when HwMode can be resolved by pattern predicates.
+// X_MOV (XRegs) -> PTR_MOV_SMALL (PtrRC) is valid in 32-bit mode (NotPtr64).
+let Predicates = [NotPtr64] in
+def : CompressPat<(X_MOV XRegs:$dst, XRegs:$src),
+ (PTR_MOV_SMALL XRegs:$dst, XRegs:$src)>;
+
+// Y_MOV (YRegs) -> PTR_MOV_SMALL (PtrRC) is valid in 64-bit mode (IsPtr64).
+let Predicates = [IsPtr64] in
+def : CompressPat<(Y_MOV YRegs:$dst, YRegs:$src),
+ (PTR_MOV_SMALL YRegs:$dst, YRegs:$src)>;
+
// CHECK: static bool compressInst(MCInst &OutInst,
// CHECK-NEXT: const MCInst &MI,
// CHECK-NEXT: const MCSubtargetInfo &STI) {
@@ -165,8 +188,39 @@ def : CompressPat<(PTR_MOV PtrRC:$dst, PtrRC:$src),
// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
+// CHECK-NEXT: if (!STI.getFeatureBits()[MyTarget::FeaturePtr64] &&
+// CHECK-NEXT: 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: // 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 X_MOV
+// CHECK-NEXT: case MyTarget::Y_MOV: {
+// CHECK-NEXT: if (STI.getFeatureBits()[MyTarget::FeaturePtr64] &&
+// CHECK-NEXT: MI.getOperand(0).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::YRegsRegClassID].contains(MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::YRegsRegClassID].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 Y_MOV
// CHECK-NEXT: } // switch
// CHECK-NEXT: return false;
// CHECK-NEXT: }
@@ -191,6 +245,34 @@ def : CompressPat<(PTR_MOV PtrRC:$dst, PtrRC:$src),
// CHECK-NEXT: OutInst.setLoc(MI.getLoc());
// CHECK-NEXT: return true;
// CHECK-NEXT: } // if
+// CHECK-NEXT: if (!STI.getFeatureBits()[MyTarget::FeaturePtr64] &&
+// CHECK-NEXT: 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: if (STI.getFeatureBits()[MyTarget::FeaturePtr64] &&
+// CHECK-NEXT: MI.getOperand(0).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::YRegsRegClassID].contains(MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::YRegsRegClassID].contains(MI.getOperand(1).getReg())) {
+// CHECK-NEXT: // y_mov $dst, $src
+// CHECK-NEXT: OutInst.setOpcode(MyTarget::Y_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: {
@@ -308,6 +390,16 @@ def : CompressPat<(PTR_MOV PtrRC:$dst, PtrRC:$src),
// CHECK-NEXT: break;
// CHECK-NEXT: } // case PTR_MOV
// CHECK-NEXT: case MyTarget::X_MOV: {
+// CHECK-NEXT: if (!STI.getFeatureBits()[MyTarget::FeaturePtr64] &&
+// CHECK-NEXT: 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: // 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(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() &&
@@ -336,6 +428,19 @@ def : CompressPat<(PTR_MOV PtrRC:$dst, PtrRC:$src),
// CHECK-NEXT: } // if
// CHECK-NEXT: break;
// CHECK-NEXT: } // case X_MOV
+// CHECK-NEXT: case MyTarget::Y_MOV: {
+// CHECK-NEXT: if (STI.getFeatureBits()[MyTarget::FeaturePtr64] &&
+// CHECK-NEXT: MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isPhysical() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::YRegsRegClassID].contains(MI.getOperand(0).getReg()) &&
+// CHECK-NEXT: MI.getOperand(1).isReg() && MI.getOperand(1).getReg().isPhysical() &&
+// CHECK-NEXT: MyTargetMCRegisterClasses[MyTarget::YRegsRegClassID].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: break;
+// CHECK-NEXT: } // case Y_MOV
// CHECK-NEXT: } // switch
// CHECK-NEXT: return false;
// CHECK-NEXT: }
diff --git a/llvm/test/TableGen/RegClassByHwModeCompressPat4Modes.td b/llvm/test/TableGen/RegClassByHwModeCompressPat4Modes.td
new file mode 100644
index 0000000000000..d652973357cb8
--- /dev/null
+++ b/llvm/test/TableGen/RegClassByHwModeCompressPat4Modes.td
@@ -0,0 +1,116 @@
+// RUN: llvm-tblgen --gen-compress-inst-emitter -I %p/../../include -I %S %s -o - | FileCheck %s
+
+include "Common/RegClassByHwModeCommon.td"
+
+// Define features
+def Feature64Bit : SubtargetFeature<"64bit", "Is64Bit", "true", "64-bit mode">;
+def FeatureCap : SubtargetFeature<"cap", "IsCap", "true", "Capability mode">;
+
+// Define predicates
+def Is64Bit : Predicate<"Subtarget->is64Bit()">,
+ AssemblerPredicate<(all_of Feature64Bit)>;
+def Not64Bit : Predicate<"!Subtarget->is64Bit()">,
+ AssemblerPredicate<(all_of (not Feature64Bit))>;
+def IsCap : Predicate<"Subtarget->isCap()">,
+ AssemblerPredicate<(all_of FeatureCap)>;
+def NotCap : Predicate<"!Subtarget->isCap()">,
+ AssemblerPredicate<(all_of (not FeatureCap))>;
+
+// Define 4 modes (similar to RISC-V RV32I, RV64I, RV32Y, RV64Y)
+def Mode32I : HwMode<[Not64Bit, NotCap]>;
+def Mode64I : HwMode<[Is64Bit, NotCap]>;
+def Mode32C : HwMode<[Not64Bit, IsCap]>;
+def Mode64C : HwMode<[Is64Bit, IsCap]>;
+
+// Define mode-dependent register class (SP-like)
+// Resolves to XRegs in Integer modes, and YRegs in Capability modes
+def PtrRC : RegClassByHwMode<[Mode32I,...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/203599
More information about the llvm-branch-commits
mailing list