[TableGen] Fix CodeGenRegisterClass::hasType for simple-type arguments
authorKrzysztof Parzyszek <kparzysz@quicinc.com>
Wed, 6 Jul 2022 18:02:04 +0000 (11:02 -0700)
committerKrzysztof Parzyszek <kparzysz@quicinc.com>
Thu, 7 Jul 2022 16:37:15 +0000 (09:37 -0700)
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.

llvm/utils/TableGen/CodeGenRegisters.cpp
llvm/utils/TableGen/CodeGenRegisters.h

index 2c61be7..93ed86c 100644 (file)
@@ -861,6 +861,26 @@ void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) {
         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 {
   return std::binary_search(Members.begin(), Members.end(), Reg,
                             deref<std::less<>>());
index 0fc8b3e..e5e92fc 100644 (file)
@@ -351,10 +351,7 @@ namespace llvm {
     std::string getQualifiedName() const;
     ArrayRef<ValueTypeByHwMode> getValueTypes() const { return VTs; }
     unsigned getNumValueTypes() const { return VTs.size(); }
-
-    bool hasType(const ValueTypeByHwMode &VT) const {
-      return llvm::is_contained(VTs, VT);
-    }
+    bool hasType(const ValueTypeByHwMode &VT) const;
 
     const ValueTypeByHwMode &getValueTypeNum(unsigned VTNum) const {
       if (VTNum < VTs.size())