[llvm] cac6a26 - [TableGen] Fix register class handling in TableGen's DAG ISel Matcher Generator

Victor Campos via llvm-commits llvm-commits at lists.llvm.org
Wed May 13 02:17:11 PDT 2020


Author: Victor Campos
Date: 2020-05-13T10:17:03+01:00
New Revision: cac6a26f38131371450b6fb55e75ba7299228afe

URL: https://github.com/llvm/llvm-project/commit/cac6a26f38131371450b6fb55e75ba7299228afe
DIFF: https://github.com/llvm/llvm-project/commit/cac6a26f38131371450b6fb55e75ba7299228afe.diff

LOG: [TableGen] Fix register class handling in TableGen's DAG ISel Matcher Generator

Summary:
In TableGen's instruction selection table generator, references to
register classes were handled by generating a matcher table entry in the
form of "EmitStringInteger, MVT::i32, 'RegisterClassID'". This ID is in
fact the enum integer value corresponding to the register class.

However, both the table generator and the table consumer
(SelectionDAGISel) assume that this ID is less than or equal to 127,
i.e. at most 7 bits. Values greater than this threshold cause completely
wrong behaviours in the instruction selection process.

This patch adds a check to determine if the enum integer value is
greater than the limit of 127. In finding so, the generator emits an
"EmitInteger" instead, which properly supports values with arbitrary
sizes.

Commit f8d044bbcfdc9e1ddc02247ffb86fe39e1f277f0 fixed the very same bug
for register subindices. The present patch now extends this cover to
register classes.

Reviewers: rampitec

Reviewed By: rampitec

Subscribers: llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D79705

Added: 
    llvm/test/TableGen/dag-isel-regclass-emit-enum.td

Modified: 
    llvm/utils/TableGen/DAGISelMatcherGen.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/TableGen/dag-isel-regclass-emit-enum.td b/llvm/test/TableGen/dag-isel-regclass-emit-enum.td
new file mode 100644
index 000000000000..0002614fd574
--- /dev/null
+++ b/llvm/test/TableGen/dag-isel-regclass-emit-enum.td
@@ -0,0 +1,39 @@
+// RUN: llvm-tblgen -gen-dag-isel -I %p/../../include %s | FileCheck %s
+
+include "llvm/Target/Target.td"
+
+def TestTargetInstrInfo : InstrInfo;
+
+def TestTarget : Target {
+  let InstructionSet = TestTargetInstrInfo;
+}
+
+let Namespace = "TestNamespace" in {
+
+def R0 : Register<"r0">;
+
+foreach i = 0-127 in {
+def GPR#i : RegisterClass<"TestTarget", [i32], 32,
+                          (add R0)>;
+}
+
+def GPRAbove127 : RegisterClass<"TestTarget", [i32], 32,
+                                (add R0)>;
+} // end Namespace TestNamespace
+
+// CHECK:      OPC_CheckOpcode, TARGET_VAL(ISD::ADD),
+// CHECK-NEXT: OPC_RecordChild0, // #0 = $src
+// CHECK-NEXT: OPC_Scope, 14, /*->20*/ // 2 children in Scope
+// CHECK-NEXT: OPC_CheckChild1Integer, 0,
+// CHECK-NEXT: OPC_EmitInteger, MVT::i32, 0|128,1/*128*/,
+// CHECK-NEXT: OPC_MorphNodeTo1, TARGET_VAL(TargetOpcode::COPY_TO_REGCLASS), 0,
+// CHECK-NEXT:     MVT::i32, 2/*#Ops*/, 1, 0,
+def : Pat<(i32 (add i32:$src, (i32 0))),
+          (COPY_TO_REGCLASS GPRAbove127, GPR0:$src)>;
+
+// CHECK:      OPC_CheckChild1Integer, 1,
+// CHECK-NEXT: OPC_EmitInteger, MVT::i32, TestNamespace::GPR127RegClassID,
+// CHECK-NEXT: OPC_MorphNodeTo1, TARGET_VAL(TargetOpcode::COPY_TO_REGCLASS), 0,
+// CHECK-NEXT:     MVT::i32, 2/*#Ops*/, 1, 0,
+def : Pat<(i32 (add i32:$src, (i32 1))),
+          (COPY_TO_REGCLASS GPR127, GPR0:$src)>;

diff  --git a/llvm/utils/TableGen/DAGISelMatcherGen.cpp b/llvm/utils/TableGen/DAGISelMatcherGen.cpp
index 8db9aa6bf8a3..123ea3374c74 100644
--- a/llvm/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/llvm/utils/TableGen/DAGISelMatcherGen.cpp
@@ -707,9 +707,19 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
     if (Def->isSubClassOf("RegisterOperand"))
       Def = Def->getValueAsDef("RegClass");
     if (Def->isSubClassOf("RegisterClass")) {
-      std::string Value = getQualifiedName(Def) + "RegClassID";
-      AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
-      ResultOps.push_back(NextRecordedOperandNo++);
+      // If the register class has an enum integer value greater than 127, the
+      // encoding overflows the limit of 7 bits, which precludes the use of
+      // StringIntegerMatcher. In this case, fallback to using IntegerMatcher.
+      const CodeGenRegisterClass &RC =
+          CGP.getTargetInfo().getRegisterClass(Def);
+      if (RC.EnumValue <= 127) {
+        std::string Value = getQualifiedName(Def) + "RegClassID";
+        AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
+        ResultOps.push_back(NextRecordedOperandNo++);
+      } else {
+        AddMatcher(new EmitIntegerMatcher(RC.EnumValue, MVT::i32));
+        ResultOps.push_back(NextRecordedOperandNo++);
+      }
       return;
     }
 


        


More information about the llvm-commits mailing list