[llvm] fef2fc3 - [TableGen] Support non-def operators in !getdagop (#77531)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 10 06:59:42 PST 2024
Author: Visoiu Mistrih Francis
Date: 2024-01-10T06:59:38-08:00
New Revision: fef2fc3400eb5a22a5ccc96bd3862bec0058d305
URL: https://github.com/llvm/llvm-project/commit/fef2fc3400eb5a22a5ccc96bd3862bec0058d305
DIFF: https://github.com/llvm/llvm-project/commit/fef2fc3400eb5a22a5ccc96bd3862bec0058d305.diff
LOG: [TableGen] Support non-def operators in !getdagop (#77531)
`!getdagop` expects the dag operator to be a def, and errors out if it's
not.
While that's true in most cases, when multiclasses are involved, the
late resolution of the dag operator can result in it not being a def
yet, but still have a proper type, wich is required to check against the
optional parameter Ty in `!getdagop<Ty>`.
e.g, in the following dag:
```
(!cast<TestInstruction>(TestInstructionAndPattern::NAME) foo)
```
the operator is a UnOpInit, but all we need here is to check its type.
This fixes a bug where !getdagop is used to query the dag operator that
is dependent on the multiclass, which is not yet resolved to a def. Once
the folding is performed, the field becomes a record that can be
queried.
Added:
Modified:
llvm/lib/TableGen/Record.cpp
llvm/test/TableGen/getsetop.td
Removed:
################################################################################
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index aa981fdab4b3e6..2b3e8a0c7f848a 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -923,15 +923,16 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
case GETDAGOP:
if (DagInit *Dag = dyn_cast<DagInit>(LHS)) {
- DefInit *DI = DefInit::get(Dag->getOperatorAsDef({}));
- if (!DI->getType()->typeIsA(getType())) {
+ // TI is not necessarily a def due to the late resolution in multiclasses,
+ // but has to be a TypedInit.
+ auto *TI = cast<TypedInit>(Dag->getOperator());
+ if (!TI->getType()->typeIsA(getType())) {
PrintFatalError(CurRec->getLoc(),
- Twine("Expected type '") +
- getType()->getAsString() + "', got '" +
- DI->getType()->getAsString() + "' in: " +
- getAsString() + "\n");
+ Twine("Expected type '") + getType()->getAsString() +
+ "', got '" + TI->getType()->getAsString() +
+ "' in: " + getAsString() + "\n");
} else {
- return DI;
+ return Dag->getOperator();
}
}
break;
diff --git a/llvm/test/TableGen/getsetop.td b/llvm/test/TableGen/getsetop.td
index 0a91e1b2a583f3..aac644fe34cb28 100644
--- a/llvm/test/TableGen/getsetop.td
+++ b/llvm/test/TableGen/getsetop.td
@@ -8,6 +8,7 @@
// RUN: not llvm-tblgen -DERROR7 %s 2>&1 | FileCheck --check-prefix=ERROR7 %s
// RUN: not llvm-tblgen -DERROR8 %s 2>&1 | FileCheck --check-prefix=ERROR8 %s
// RUN: not llvm-tblgen -DERROR9 %s 2>&1 | FileCheck --check-prefix=ERROR9 %s
+// RUN: not llvm-tblgen -DERROR10 %s 2>&1 | FileCheck --check-prefix=ERROR10 %s
// !setop and !getop are deprecated in favor of !setdagop and !getdagop.
// Two tests retain the old names just to be sure they are still supported.
@@ -148,3 +149,32 @@ def test {
dag orig_out_of_range = !setdagarg(orig, foo, (foo qux:$a));
#endif
}
+
+// Copy a list (Predicates) that is a field in a dag operator
+// (TestInstruction), which is defined in the same multiclass
+// (TestInstructionAndPattern) as the destination of the copy
+// (TestPattern::Predicates).
+class TestInstruction<list<int> _Predicates> {
+ list<int> Predicates = _Predicates;
+}
+#ifdef ERROR10
+class OtherTestInstruction<list<int> _Predicates> {
+ list<int> Predicates = _Predicates;
+}
+// ERROR10: error: Expected type 'OtherTestInstruction', got 'TestInstruction'
+class TestPattern<dag D> {
+ list<int> Predicates = !getdagop<OtherTestInstruction>(D).Predicates;
+}
+#else
+class TestPattern<dag D> {
+ list<int> Predicates = !getdagop<TestInstruction>(D).Predicates;
+}
+#endif
+
+multiclass TestInstructionAndPattern<list<int> Predicates> {
+ def NAME : TestInstruction<Predicates>;
+ def : TestPattern<(!cast<TestInstruction>(NAME) foo)>;
+}
+// CHECK: def testInst0 { // TestInstruction
+// CHECK-NEXT: list<int> Predicates = [7];
+defm testInst0 : TestInstructionAndPattern<[7]>;
More information about the llvm-commits
mailing list