[TableGen] Fix CodeGenRegisterClass::hasType for simple-type arguments

The `hasType` function may be given a type that has been modified from
its original form (in particular made "simple", due to a predicate).
Make sure that such a type is still recognized as associated with a
register class, if the class contains it under any hw-mode.
This is somewhat optimistic though, since there is no information as
to where that simple type originated from.
This commit is contained in:
Krzysztof Parzyszek 2022-07-06 11:02:04 -07:00
parent 6817031d0b
commit 8cadfdf8e7
2 changed files with 21 additions and 4 deletions

View File

@ -861,6 +861,26 @@ void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) {
Orders[i].push_back(Super.Orders[i][j]); Orders[i].push_back(Super.Orders[i][j]);
} }
bool CodeGenRegisterClass::hasType(const ValueTypeByHwMode &VT) const {
if (llvm::is_contained(VTs, VT))
return true;
// If VT is not identical to any of this class's types, but is a simple
// type, check if any of the types for this class contain it under some
// mode.
// The motivating example came from RISCV, where (likely because of being
// guarded by "64-bit" predicate), the type of X5 was {*:[i64]}, but the
// type in GRC was {*:[i32], m1:[i64]}.
if (VT.isSimple()) {
MVT T = VT.getSimple();
for (const ValueTypeByHwMode &OurVT : VTs) {
if (llvm::count_if(OurVT, [T](auto &&P) { return P.second == T; }))
return true;
}
}
return false;
}
bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const { bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const {
return std::binary_search(Members.begin(), Members.end(), Reg, return std::binary_search(Members.begin(), Members.end(), Reg,
deref<std::less<>>()); deref<std::less<>>());

View File

@ -351,10 +351,7 @@ namespace llvm {
std::string getQualifiedName() const; std::string getQualifiedName() const;
ArrayRef<ValueTypeByHwMode> getValueTypes() const { return VTs; } ArrayRef<ValueTypeByHwMode> getValueTypes() const { return VTs; }
unsigned getNumValueTypes() const { return VTs.size(); } unsigned getNumValueTypes() const { return VTs.size(); }
bool hasType(const ValueTypeByHwMode &VT) const;
bool hasType(const ValueTypeByHwMode &VT) const {
return llvm::is_contained(VTs, VT);
}
const ValueTypeByHwMode &getValueTypeNum(unsigned VTNum) const { const ValueTypeByHwMode &getValueTypeNum(unsigned VTNum) const {
if (VTNum < VTs.size()) if (VTNum < VTs.size())