Skip to content

Commit f672f32

Browse files
authored
[TableGen] Improve error message for bad VTByHwMode in RegisterByHwMode
Previously we would assert when a ValueTypeByHwMode was missing a case for the current mode, now we report an error instead. Interestingly this error only ocurrs when the DAG patterns use RegClassByHwMode, but not normal RegisterClass instances. Found while I added RegClassByHwMode to RISC-V and was getting an assertion due to `XLenFVT`/`XLenVecI32VT` not having an entry for the default mode. Reviewed By: arsenm Pull Request: #171254
1 parent 182c61d commit f672f32

File tree

4 files changed

+66
-12
lines changed

4 files changed

+66
-12
lines changed

llvm/test/TableGen/RegClassByHwModeErrors.td

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
// RUN: %t/compress-regclass-by-hwmode.td -o /dev/null 2>&1 | FileCheck %t/compress-regclass-by-hwmode.td --implicit-check-not="error:"
88
// RUN: not llvm-tblgen --gen-compress-inst-emitter -I %p/../../include -I %t -I %S \
99
// RUN: %t/compress-regclass-by-hwmode-2.td -o /dev/null 2>&1 | FileCheck %t/compress-regclass-by-hwmode-2.td --implicit-check-not="error:"
10+
// RUN: not llvm-tblgen --gen-dag-isel -I %p/../../include -I %t -I %S \
11+
// RUN: %t/vt-by-hwmode-missing.td -o /dev/null 2>&1 | FileCheck %t/vt-by-hwmode-missing.td --implicit-check-not="error:"
1012

1113
//--- Common.td
1214
include "Common/RegClassByHwModeCommon.td"
@@ -86,3 +88,34 @@ def : CompressPat<(X_MOV_BIG XRegs:$dst, XRegs:$src),
8688
// CHECK: [[#@LINE-2]]:1: error: Type mismatch between Input and Output Dag operand 'dst'
8789
def MyTargetISA : InstrInfo;
8890
def MyTarget : Target { let InstructionSet = MyTargetISA; }
91+
92+
93+
//--- vt-by-hwmode-missing.td
94+
include "Common.td"
95+
/// This should fail since we are missing a DefaultMode entry for the
96+
/// ValueTypeByHwMode and can't resolve it for the Ptr32 (default) case.
97+
def BadVT : ValueTypeByHwMode<[Ptr64], [i64]>;
98+
def BadVTRegClass : RegisterClass<"MyTarget", [i64, BadVT], 64, (add Y0, Y1)>;
99+
/// NOTE: this error only occurs for RegClassByHwMode, normal RegisterClass
100+
/// logic for VT resolution takes a different code path and does not error.
101+
def TEST_OK : TestInstruction {
102+
let OutOperandList = (outs BadVTRegClass:$dst);
103+
let InOperandList = (ins BadVTRegClass:$src1, BadVTRegClass:$src2);
104+
let AsmString = "test $dst, $src1, $src2";
105+
let Pattern = [(set BadVTRegClass:$dst, (add BadVTRegClass:$src1, BadVTRegClass:$src2))];
106+
}
107+
/// Once we use RegClassByHwMode, we get an error about missing modes:
108+
def BadPtrRC : RegClassByHwMode<[Ptr32, Ptr64], [BadVTRegClass, YRegs]>;
109+
// CHECK: vt-by-hwmode-missing.td:[[#@LINE-1]]:5: error: Could not resolve VT for Mode DefaultMode
110+
// CHECK: vt-by-hwmode-missing.td:4:5: note: ValueTypeByHwMode BadVT defined here
111+
// CHECK: vt-by-hwmode-missing.td:[[#@LINE+1]]:5: note: pattern instantiated here
112+
def TEST : TestInstruction {
113+
let OutOperandList = (outs BadPtrRC:$dst);
114+
let InOperandList = (ins BadPtrRC:$src1, BadPtrRC:$src2);
115+
let AsmString = "test $dst, $src1, $src2";
116+
let opcode = 0;
117+
let Pattern = [(set BadPtrRC:$dst, (add BadPtrRC:$src1, BadPtrRC:$src2))];
118+
}
119+
120+
def MyTargetISA : InstrInfo;
121+
def MyTarget : Target { let InstructionSet = MyTargetISA; }

llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,15 +1798,27 @@ bool llvm::operator<(const SDTypeConstraint &LHS, const SDTypeConstraint &RHS) {
17981798
/// RegClassByHwMode acts like ValueTypeByHwMode, taking the type of the
17991799
/// register class from the active mode.
18001800
static TypeSetByHwMode getTypeForRegClassByHwMode(const CodeGenTarget &T,
1801-
const Record *R) {
1801+
const Record *R,
1802+
ArrayRef<SMLoc> Loc) {
18021803
TypeSetByHwMode TypeSet;
18031804
RegClassByHwMode Helper(R, T.getHwModes(), T.getRegBank());
18041805

18051806
for (auto [ModeID, RegClass] : Helper) {
18061807
ArrayRef<ValueTypeByHwMode> RegClassVTs = RegClass->getValueTypes();
18071808
MachineValueTypeSet &ModeTypeSet = TypeSet.getOrCreate(ModeID);
1808-
for (const ValueTypeByHwMode &VT : RegClassVTs)
1809+
for (const ValueTypeByHwMode &VT : RegClassVTs) {
1810+
if (!VT.hasMode(ModeID) && !VT.hasDefault()) {
1811+
PrintError(R->getLoc(), "Could not resolve VT for Mode " +
1812+
T.getHwModes().getModeName(ModeID, true));
1813+
if (VT.getRecord())
1814+
PrintNote(VT.getRecord()->getLoc(), "ValueTypeByHwMode " +
1815+
VT.getRecord()->getName() +
1816+
" defined here");
1817+
PrintFatalNote(Loc, "pattern instantiated here");
1818+
continue;
1819+
}
18091820
ModeTypeSet.insert(VT.getType(ModeID));
1821+
}
18101822
}
18111823

18121824
return TypeSet;
@@ -1841,7 +1853,9 @@ bool TreePatternNode::UpdateNodeTypeFromInst(unsigned ResNo,
18411853
assert(RC && "Unknown operand type");
18421854
CodeGenTarget &Tgt = TP.getDAGPatterns().getTargetInfo();
18431855
if (RC->isSubClassOf("RegClassByHwMode"))
1844-
return UpdateNodeType(ResNo, getTypeForRegClassByHwMode(Tgt, RC), TP);
1856+
return UpdateNodeType(
1857+
ResNo, getTypeForRegClassByHwMode(Tgt, RC, TP.getRecord()->getLoc()),
1858+
TP);
18451859

18461860
return UpdateNodeType(ResNo, Tgt.getRegisterClass(RC).getValueTypes(), TP);
18471861
}
@@ -2331,7 +2345,7 @@ static TypeSetByHwMode getImplicitType(const Record *R, unsigned ResNo,
23312345
const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
23322346

23332347
if (RegClass->isSubClassOf("RegClassByHwMode"))
2334-
return getTypeForRegClassByHwMode(T, RegClass);
2348+
return getTypeForRegClassByHwMode(T, RegClass, TP.getRecord()->getLoc());
23352349

23362350
return TypeSetByHwMode(T.getRegisterClass(RegClass).getValueTypes());
23372351
}
@@ -2354,7 +2368,7 @@ static TypeSetByHwMode getImplicitType(const Record *R, unsigned ResNo,
23542368

23552369
if (R->isSubClassOf("RegClassByHwMode")) {
23562370
const CodeGenTarget &T = CDP.getTargetInfo();
2357-
return getTypeForRegClassByHwMode(T, R);
2371+
return getTypeForRegClassByHwMode(T, R, TP.getRecord()->getLoc());
23582372
}
23592373

23602374
if (R->isSubClassOf("PatFrags")) {

llvm/utils/TableGen/Common/InfoByHwMode.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ std::string llvm::getModeName(unsigned Mode) {
2929
return (Twine('m') + Twine(Mode)).str();
3030
}
3131

32-
ValueTypeByHwMode::ValueTypeByHwMode(const Record *R,
33-
const CodeGenHwModes &CGH) {
32+
ValueTypeByHwMode::ValueTypeByHwMode(const Record *R, const CodeGenHwModes &CGH)
33+
: InfoByHwMode<llvm::MVT>(R) {
3434
const HwModeSelect &MS = CGH.getHwModeSelect(R);
3535
for (const HwModeSelect::PairType &P : MS.Items) {
3636
auto I = Map.try_emplace(P.first, MVT(llvm::getValueType(P.second)));
@@ -140,7 +140,8 @@ void RegSizeInfo::writeToStream(raw_ostream &OS) const {
140140
}
141141

142142
RegSizeInfoByHwMode::RegSizeInfoByHwMode(const Record *R,
143-
const CodeGenHwModes &CGH) {
143+
const CodeGenHwModes &CGH)
144+
: InfoByHwMode<llvm::RegSizeInfo>(R) {
144145
const HwModeSelect &MS = CGH.getHwModeSelect(R);
145146
for (const HwModeSelect::PairType &P : MS.Items) {
146147
auto I = Map.try_emplace(P.first, RegSizeInfo(P.second));
@@ -188,7 +189,8 @@ void RegSizeInfoByHwMode::writeToStream(raw_ostream &OS) const {
188189
}
189190

190191
RegClassByHwMode::RegClassByHwMode(const Record *R, const CodeGenHwModes &CGH,
191-
const CodeGenRegBank &RegBank) {
192+
const CodeGenRegBank &RegBank)
193+
: InfoByHwMode<const llvm::CodeGenRegisterClass *>(R) {
192194
const HwModeSelect &MS = CGH.getHwModeSelect(R);
193195

194196
for (auto [ModeID, RegClassRec] : MS.Items) {
@@ -206,7 +208,8 @@ SubRegRange::SubRegRange(const Record *R) {
206208
}
207209

208210
SubRegRangeByHwMode::SubRegRangeByHwMode(const Record *R,
209-
const CodeGenHwModes &CGH) {
211+
const CodeGenHwModes &CGH)
212+
: InfoByHwMode<llvm::SubRegRange>(R) {
210213
const HwModeSelect &MS = CGH.getHwModeSelect(R);
211214
for (const HwModeSelect::PairType &P : MS.Items) {
212215
auto I = Map.try_emplace(P.first, SubRegRange(P.second));
@@ -216,7 +219,8 @@ SubRegRangeByHwMode::SubRegRangeByHwMode(const Record *R,
216219
}
217220

218221
EncodingInfoByHwMode::EncodingInfoByHwMode(const Record *R,
219-
const CodeGenHwModes &CGH) {
222+
const CodeGenHwModes &CGH)
223+
: InfoByHwMode<const llvm::Record *>(R) {
220224
const HwModeSelect &MS = CGH.getHwModeSelect(R);
221225
for (const HwModeSelect::PairType &P : MS.Items) {
222226
assert(P.second && P.second->isSubClassOf("InstructionEncoding") &&

llvm/utils/TableGen/Common/InfoByHwMode.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ template <typename InfoT> struct InfoByHwMode {
9191
using iterator = typename MapType::iterator;
9292
using const_iterator = typename MapType::const_iterator;
9393

94-
InfoByHwMode() = default;
94+
explicit InfoByHwMode(const Record *Def = nullptr) : Def(Def) {};
9595
InfoByHwMode(const MapType &M) : Map(M) {}
9696

9797
LLVM_ATTRIBUTE_ALWAYS_INLINE
@@ -150,8 +150,11 @@ template <typename InfoT> struct InfoByHwMode {
150150
Map.try_emplace(DefaultMode, I);
151151
}
152152

153+
const Record *getRecord() const { return Def; }
154+
153155
protected:
154156
MapType Map;
157+
const Record *Def;
155158
};
156159

157160
struct ValueTypeByHwMode : public InfoByHwMode<MVT> {

0 commit comments

Comments
 (0)