Skip to content

Commit 625d535

Browse files
authored
[TableGen] Handle RegClassByHwMode in AsmWriter
Previously, we were emitting a broken AliasPatternCond array, outputting `MyTarget::RegClassByHwModeRegClassID` which does not exist. Instead, we now add a new predicate and pass the RegClassByHwMode index as the value argument. Pull Request: #171264
1 parent f672f32 commit 625d535

File tree

4 files changed

+81
-21
lines changed

4 files changed

+81
-21
lines changed

llvm/include/llvm/MC/MCInstPrinter.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -201,17 +201,18 @@ struct AliasPattern {
201201

202202
struct AliasPatternCond {
203203
enum CondKind : uint8_t {
204-
K_Feature, // Match only if a feature is enabled.
205-
K_NegFeature, // Match only if a feature is disabled.
206-
K_OrFeature, // Match only if one of a set of features is enabled.
207-
K_OrNegFeature, // Match only if one of a set of features is disabled.
208-
K_EndOrFeatures, // Note end of list of K_Or(Neg)?Features.
209-
K_Ignore, // Match any operand.
210-
K_Reg, // Match a specific register.
211-
K_TiedReg, // Match another already matched register.
212-
K_Imm, // Match a specific immediate.
213-
K_RegClass, // Match registers in a class.
214-
K_Custom, // Call custom matcher by index.
204+
K_Feature, // Match only if a feature is enabled.
205+
K_NegFeature, // Match only if a feature is disabled.
206+
K_OrFeature, // Match only if one of a set of features is enabled.
207+
K_OrNegFeature, // Match only if one of a set of features is disabled.
208+
K_EndOrFeatures, // Note end of list of K_Or(Neg)?Features.
209+
K_Ignore, // Match any operand.
210+
K_Reg, // Match a specific register.
211+
K_TiedReg, // Match another already matched register.
212+
K_Imm, // Match a specific immediate.
213+
K_RegClass, // Match registers in a class.
214+
K_RegClassByHwMode, // Match registers in a class (by HwMode)
215+
K_Custom, // Call custom matcher by index.
215216
};
216217

217218
CondKind Kind;

llvm/lib/MC/MCInstPrinter.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ void MCInstPrinter::printAnnotation(raw_ostream &OS, StringRef Annot) {
6161
}
6262

6363
static bool matchAliasCondition(const MCInst &MI, const MCSubtargetInfo *STI,
64+
const MCInstrInfo &MII,
6465
const MCRegisterInfo &MRI, unsigned &OpIdx,
6566
const AliasMatchingData &M,
6667
const AliasPatternCond &C,
@@ -102,6 +103,12 @@ static bool matchAliasCondition(const MCInst &MI, const MCSubtargetInfo *STI,
102103
case AliasPatternCond::K_TiedReg:
103104
// Operand must match the register of another operand.
104105
return Opnd.isReg() && Opnd.getReg() == MI.getOperand(C.Value).getReg();
106+
case AliasPatternCond::K_RegClassByHwMode: {
107+
// Operand must be RegisterByHwMode. Value is RegClassByHwMode index.
108+
unsigned HwModeId = STI->getHwMode(MCSubtargetInfo::HwMode_RegInfo);
109+
int16_t RCID = MII.getRegClassByHwModeTable(HwModeId)[C.Value];
110+
return Opnd.isReg() && MRI.getRegClass(RCID).contains(Opnd.getReg());
111+
}
105112
case AliasPatternCond::K_RegClass:
106113
// Operand must be a register in this class. Value is a register class id.
107114
return Opnd.isReg() && MRI.getRegClass(C.Value).contains(Opnd.getReg());
@@ -148,7 +155,7 @@ const char *MCInstPrinter::matchAliasPatterns(const MCInst *MI,
148155
unsigned OpIdx = 0;
149156
bool OrPredicateResult = false;
150157
if (llvm::all_of(Conds, [&](const AliasPatternCond &C) {
151-
return matchAliasCondition(*MI, STI, MRI, OpIdx, M, C,
158+
return matchAliasCondition(*MI, STI, MII, MRI, OpIdx, M, C,
152159
OrPredicateResult);
153160
})) {
154161
// If all conditions matched, use this asm string.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// RUN: llvm-tblgen -gen-asm-writer -I %S -I %p/../../include %s -o - | FileCheck %s
2+
3+
include "Common/RegClassByHwModeCommon.td"
4+
5+
def IsPtrY : Predicate<"Subtarget->isPtrY()">;
6+
defvar PtrX = DefaultMode;
7+
def PtrY : HwMode<[IsPtrY]>;
8+
9+
// Define more restrictive subset classes to check that those are handled.
10+
def EvenXRegs : RegisterClass<"MyTarget", [i64], 64, (add X0, X2, X4, X6)>;
11+
def EvenYRegs : RegisterClass<"MyTarget", [i64], 64, (add Y0, Y2, Y4, Y6)>;
12+
def PtrRC : RegClassByHwMode<[PtrX, PtrY], [XRegs, YRegs]>;
13+
def EvenPtrRC : RegClassByHwMode<[PtrX, PtrY], [EvenXRegs, EvenYRegs]>;
14+
15+
def TEST_XREG : TestInstruction {
16+
let OutOperandList = (outs XRegs:$dst);
17+
let InOperandList = (ins XRegs:$src);
18+
let AsmString = "t_x $dst, $src";
19+
let opcode = 0;
20+
}
21+
def TEST_PTR : TestInstruction {
22+
let OutOperandList = (outs PtrRC:$dst);
23+
let InOperandList = (ins PtrRC:$src);
24+
let AsmString = "t_ptr $dst, $src";
25+
let opcode = 0;
26+
}
27+
28+
def MY_T_X : InstAlias<"t_x $src", (TEST_XREG X0, XRegs:$src)>;
29+
def MY_T_X_EVEN : InstAlias<"t_x.even $src", (TEST_XREG EvenXRegs:$dst, EvenXRegs:$src)>;
30+
31+
// TODO: Can't use a fixed register for this instruction, would need RegisterByHwMode.
32+
// def MY_T_PTR : InstAlias<"t_ptr $src", (TEST_PTR X0, XRegs:$src)>;
33+
def MY_T_PTR_EVEN : InstAlias<"t_ptr.even $src", (TEST_PTR EvenPtrRC:$dst, EvenPtrRC:$src)>;
34+
35+
// CHECK-LABEL: static const AliasPatternCond Conds[] = {
36+
// CHECK-NEXT: // (TEST_PTR EvenPtrRC:$dst, EvenPtrRC:$src) - 0
37+
// CHECK-NEXT: {AliasPatternCond::K_RegClassByHwMode, MyTarget::EvenPtrRC},
38+
// CHECK-NEXT: {AliasPatternCond::K_RegClassByHwMode, MyTarget::EvenPtrRC},
39+
// CHECK-NEXT: // (TEST_XREG X0, XRegs:$src) - 2
40+
// CHECK-NEXT: {AliasPatternCond::K_Reg, MyTarget::X0},
41+
// CHECK-NEXT: {AliasPatternCond::K_RegClass, MyTarget::XRegsRegClassID},
42+
// CHECK-NEXT: // (TEST_XREG EvenXRegs:$dst, EvenXRegs:$src) - 4
43+
// CHECK-NEXT: {AliasPatternCond::K_RegClass, MyTarget::EvenXRegsRegClassID},
44+
// CHECK-NEXT: {AliasPatternCond::K_RegClass, MyTarget::EvenXRegsRegClassID},
45+
// CHECK-NEXT: };
46+
47+
def MyTargetISA : InstrInfo;
48+
def MyTarget : Target { let InstructionSet = MyTargetISA; }

llvm/utils/TableGen/AsmWriterEmitter.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -943,17 +943,21 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
943943
}
944944
}
945945

946-
if (Rec->isSubClassOf("RegisterOperand"))
947-
Rec = Rec->getValueAsDef("RegClass");
948-
if (Rec->isSubClassOf("RegisterClassLike")) {
946+
if (Target.getAsRegClassLike(Rec)) {
949947
if (!IAP.isOpMapped(ROName)) {
950948
IAP.addOperand(ROName, MIOpNum, PrintMethodIdx);
951-
const Record *R = CGA.ResultOperands[i].getRecord();
952-
if (R->isSubClassOf("RegisterOperand"))
953-
R = R->getValueAsDef("RegClass");
954-
IAP.addCond(std::string(
955-
formatv("AliasPatternCond::K_RegClass, {}::{}RegClassID",
956-
Namespace, R->getName())));
949+
const Record *R =
950+
Target.getAsRegClassLike(CGA.ResultOperands[i].getRecord());
951+
assert(R && "Not a valid register class?");
952+
if (R->isSubClassOf("RegClassByHwMode")) {
953+
IAP.addCond(std::string(
954+
formatv("AliasPatternCond::K_RegClassByHwMode, {}::{}",
955+
Namespace, R->getName())));
956+
} else {
957+
IAP.addCond(std::string(
958+
formatv("AliasPatternCond::K_RegClass, {}::{}RegClassID",
959+
Namespace, R->getName())));
960+
}
957961
} else {
958962
IAP.addCond(std::string(formatv("AliasPatternCond::K_TiedReg, {}",
959963
IAP.getOpIndex(ROName))));

0 commit comments

Comments
 (0)