Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions llvm/test/TableGen/RegClassByHwModeErrors.td
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
// RUN: %t/compress-regclass-by-hwmode.td -o /dev/null 2>&1 | FileCheck %t/compress-regclass-by-hwmode.td --implicit-check-not="error:"
// RUN: not llvm-tblgen --gen-compress-inst-emitter -I %p/../../include -I %t -I %S \
// 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:"
// RUN: not llvm-tblgen --gen-dag-isel -I %p/../../include -I %t -I %S \
// RUN: %t/vt-by-hwmode-missing.td -o /dev/null 2>&1 | FileCheck %t/vt-by-hwmode-missing.td --implicit-check-not="error:"

//--- Common.td
include "Common/RegClassByHwModeCommon.td"
Expand Down Expand Up @@ -86,3 +88,34 @@ def : CompressPat<(X_MOV_BIG XRegs:$dst, XRegs:$src),
// CHECK: [[#@LINE-2]]:1: error: Type mismatch between Input and Output Dag operand 'dst'
def MyTargetISA : InstrInfo;
def MyTarget : Target { let InstructionSet = MyTargetISA; }


//--- vt-by-hwmode-missing.td
include "Common.td"
/// This should fail since we are missing a DefaultMode entry for the
/// ValueTypeByHwMode and can't resolve it for the Ptr32 (default) case.
def BadVT : ValueTypeByHwMode<[Ptr64], [i64]>;
def BadVTRegClass : RegisterClass<"MyTarget", [i64, BadVT], 64, (add Y0, Y1)>;
/// NOTE: this error only occurs for RegClassByHwMode, normal RegisterClass
/// logic for VT resolution takes a different code path and does not error.
def TEST_OK : TestInstruction {
let OutOperandList = (outs BadVTRegClass:$dst);
let InOperandList = (ins BadVTRegClass:$src1, BadVTRegClass:$src2);
let AsmString = "test $dst, $src1, $src2";
let Pattern = [(set BadVTRegClass:$dst, (add BadVTRegClass:$src1, BadVTRegClass:$src2))];
}
/// Once we use RegClassByHwMode, we get an error about missing modes:
def BadPtrRC : RegClassByHwMode<[Ptr32, Ptr64], [BadVTRegClass, YRegs]>;
// CHECK: vt-by-hwmode-missing.td:[[#@LINE-1]]:5: error: Could not resolve VT for Mode DefaultMode
// CHECK: vt-by-hwmode-missing.td:4:5: note: ValueTypeByHwMode BadVT defined here
// CHECK: vt-by-hwmode-missing.td:[[#@LINE+1]]:5: note: pattern instantiated here
def TEST : TestInstruction {
let OutOperandList = (outs BadPtrRC:$dst);
let InOperandList = (ins BadPtrRC:$src1, BadPtrRC:$src2);
let AsmString = "test $dst, $src1, $src2";
let opcode = 0;
let Pattern = [(set BadPtrRC:$dst, (add BadPtrRC:$src1, BadPtrRC:$src2))];
}

def MyTargetISA : InstrInfo;
def MyTarget : Target { let InstructionSet = MyTargetISA; }
24 changes: 19 additions & 5 deletions llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1798,15 +1798,27 @@ bool llvm::operator<(const SDTypeConstraint &LHS, const SDTypeConstraint &RHS) {
/// RegClassByHwMode acts like ValueTypeByHwMode, taking the type of the
/// register class from the active mode.
static TypeSetByHwMode getTypeForRegClassByHwMode(const CodeGenTarget &T,
const Record *R) {
const Record *R,
ArrayRef<SMLoc> Loc) {
TypeSetByHwMode TypeSet;
RegClassByHwMode Helper(R, T.getHwModes(), T.getRegBank());

for (auto [ModeID, RegClass] : Helper) {
ArrayRef<ValueTypeByHwMode> RegClassVTs = RegClass->getValueTypes();
MachineValueTypeSet &ModeTypeSet = TypeSet.getOrCreate(ModeID);
for (const ValueTypeByHwMode &VT : RegClassVTs)
for (const ValueTypeByHwMode &VT : RegClassVTs) {
if (!VT.hasMode(ModeID) && !VT.hasDefault()) {
PrintError(R->getLoc(), "Could not resolve VT for Mode " +
T.getHwModes().getModeName(ModeID, true));
if (VT.getRecord())
PrintNote(VT.getRecord()->getLoc(), "ValueTypeByHwMode " +
VT.getRecord()->getName() +
" defined here");
PrintFatalNote(Loc, "pattern instantiated here");
continue;
}
ModeTypeSet.insert(VT.getType(ModeID));
}
}

return TypeSet;
Expand Down Expand Up @@ -1841,7 +1853,9 @@ bool TreePatternNode::UpdateNodeTypeFromInst(unsigned ResNo,
assert(RC && "Unknown operand type");
CodeGenTarget &Tgt = TP.getDAGPatterns().getTargetInfo();
if (RC->isSubClassOf("RegClassByHwMode"))
return UpdateNodeType(ResNo, getTypeForRegClassByHwMode(Tgt, RC), TP);
return UpdateNodeType(
ResNo, getTypeForRegClassByHwMode(Tgt, RC, TP.getRecord()->getLoc()),
TP);

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

if (RegClass->isSubClassOf("RegClassByHwMode"))
return getTypeForRegClassByHwMode(T, RegClass);
return getTypeForRegClassByHwMode(T, RegClass, TP.getRecord()->getLoc());

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

if (R->isSubClassOf("RegClassByHwMode")) {
const CodeGenTarget &T = CDP.getTargetInfo();
return getTypeForRegClassByHwMode(T, R);
return getTypeForRegClassByHwMode(T, R, TP.getRecord()->getLoc());
}

if (R->isSubClassOf("PatFrags")) {
Expand Down
16 changes: 10 additions & 6 deletions llvm/utils/TableGen/Common/InfoByHwMode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ std::string llvm::getModeName(unsigned Mode) {
return (Twine('m') + Twine(Mode)).str();
}

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

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

RegClassByHwMode::RegClassByHwMode(const Record *R, const CodeGenHwModes &CGH,
const CodeGenRegBank &RegBank) {
const CodeGenRegBank &RegBank)
: InfoByHwMode<const llvm::CodeGenRegisterClass *>(R) {
const HwModeSelect &MS = CGH.getHwModeSelect(R);

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

SubRegRangeByHwMode::SubRegRangeByHwMode(const Record *R,
const CodeGenHwModes &CGH) {
const CodeGenHwModes &CGH)
: InfoByHwMode<llvm::SubRegRange>(R) {
const HwModeSelect &MS = CGH.getHwModeSelect(R);
for (const HwModeSelect::PairType &P : MS.Items) {
auto I = Map.try_emplace(P.first, SubRegRange(P.second));
Expand All @@ -216,7 +219,8 @@ SubRegRangeByHwMode::SubRegRangeByHwMode(const Record *R,
}

EncodingInfoByHwMode::EncodingInfoByHwMode(const Record *R,
const CodeGenHwModes &CGH) {
const CodeGenHwModes &CGH)
: InfoByHwMode<const llvm::Record *>(R) {
const HwModeSelect &MS = CGH.getHwModeSelect(R);
for (const HwModeSelect::PairType &P : MS.Items) {
assert(P.second && P.second->isSubClassOf("InstructionEncoding") &&
Expand Down
5 changes: 4 additions & 1 deletion llvm/utils/TableGen/Common/InfoByHwMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ template <typename InfoT> struct InfoByHwMode {
using iterator = typename MapType::iterator;
using const_iterator = typename MapType::const_iterator;

InfoByHwMode() = default;
explicit InfoByHwMode(const Record *Def = nullptr) : Def(Def) {};
InfoByHwMode(const MapType &M) : Map(M) {}

LLVM_ATTRIBUTE_ALWAYS_INLINE
Expand Down Expand Up @@ -150,8 +150,11 @@ template <typename InfoT> struct InfoByHwMode {
Map.try_emplace(DefaultMode, I);
}

const Record *getRecord() const { return Def; }

protected:
MapType Map;
const Record *Def;
};

struct ValueTypeByHwMode : public InfoByHwMode<MVT> {
Expand Down
Loading