[llvm] d416289 - [TableGen] Eliminate the dependency on SDNode definition order (#168745)

via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 24 03:59:24 PST 2025


Author: Anatoly Trosinenko
Date: 2025-11-24T14:59:19+03:00
New Revision: d41628941743b778432e30d93f25028ffb375fbc

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

LOG: [TableGen] Eliminate the dependency on SDNode definition order (#168745)

Fix the dependency of `CodeGenDAGPatterns::ParseDefaultOperands()` on
the particular order of SDNode definitions. Implicit usage of the first
definition as a placeholder makes `llvm-tblgen -gen-dag-isel` fail if
that SDNode is not usable as an output pattern operator and an instance
of `OperandWithDefaultOps` is used in a pattern.

Presently, each `OperandWithDefaultOps` record is processed by
constructing an instance of TreePattern from its `DefaultOps` argument
that has the form `(ops ...)`. Even though the result of processing the
root operator of that DAG is not inspected by `ParseDefaultOperands()`
function itself, that operator has to be supported by the underlying
`TreePattern::ParseTreePattern()` function. For that reason, a temporary
DAG is created by replacing the root operator of `DefaultOps` argument
with the first SDNode defined, which is usually `def imm : ...` defined
in `TargetSelectionDAG.td` file.

This results in misleading errors being reported when implementing new
`SDNode` types, if the new definition happens to be added before the
`def imm : ...` line. The error is reported by several test cases
executed by `check-llvm` target, as well as by the regular build, if one
of the enabled targets inherit one of its operand types from
`OperandWithDefaultOps`:

    OptionalIntOperand: ../llvm/test/TableGen/DAGDefaultOps.td:28:5: error: In OptionalIntOperand: Cannot use 'unexpected_node' in an output pattern!
    def OptionalIntOperand: OperandWithDefaultOps<i32, (ops (i32 0))>;

This commit implements a dedicated constructor of `TreePattern` to be
used if the caller does not care about the particular root operator of
the pattern being processed.

Added: 
    

Modified: 
    llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
    llvm/utils/TableGen/Common/CodeGenDAGPatterns.h

Removed: 
    


################################################################################
diff  --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
index 2bea0ca2bfabb..8251c8983cc80 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
@@ -2922,6 +2922,14 @@ TreePattern::TreePattern(const Record *TheRec, const DagInit *Pat, bool isInput,
   Trees.push_back(ParseTreePattern(Pat, ""));
 }
 
+TreePattern::TreePattern(const Record *TheRec, ArrayRef<const Init *> Args,
+                         ArrayRef<const StringInit *> ArgNames, bool isInput,
+                         CodeGenDAGPatterns &cdp)
+    : TheRecord(TheRec), CDP(cdp), isInputPattern(isInput), HasError(false),
+      Infer(*this) {
+  Trees.push_back(ParseRootlessTreePattern(Args, ArgNames));
+}
+
 TreePattern::TreePattern(const Record *TheRec, TreePatternNodePtr Pat,
                          bool isInput, CodeGenDAGPatterns &cdp)
     : TheRecord(TheRec), CDP(cdp), isInputPattern(isInput), HasError(false),
@@ -2950,6 +2958,19 @@ void TreePattern::ComputeNamedNodes(TreePatternNode &N) {
     ComputeNamedNodes(Child);
 }
 
+TreePatternNodePtr
+TreePattern::ParseRootlessTreePattern(ArrayRef<const Init *> Args,
+                                      ArrayRef<const StringInit *> ArgNames) {
+  std::vector<TreePatternNodePtr> Children;
+
+  for (auto [Arg, ArgName] : llvm::zip_equal(Args, ArgNames)) {
+    StringRef NameStr = ArgName ? ArgName->getValue() : "";
+    Children.push_back(ParseTreePattern(Arg, NameStr));
+  }
+
+  return makeIntrusiveRefCnt<TreePatternNode>(nullptr, std::move(Children), 1);
+}
+
 TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
                                                  StringRef OpName) {
   RecordKeeper &RK = TheInit->getRecordKeeper();
@@ -3487,20 +3508,12 @@ void CodeGenDAGPatterns::ParseDefaultOperands() {
   ArrayRef<const Record *> DefaultOps =
       Records.getAllDerivedDefinitions("OperandWithDefaultOps");
 
-  // Find some SDNode.
-  assert(!SDNodes.empty() && "No SDNodes parsed?");
-  const Init *SomeSDNode = SDNodes.begin()->first->getDefInit();
-
   for (unsigned i = 0, e = DefaultOps.size(); i != e; ++i) {
     const DagInit *DefaultInfo = DefaultOps[i]->getValueAsDag("DefaultOps");
 
-    // Clone the DefaultInfo dag node, changing the operator from 'ops' to
-    // SomeSDnode so that we can parse this.
-    const DagInit *DI = DagInit::get(SomeSDNode, DefaultInfo->getArgs(),
-                                     DefaultInfo->getArgNames());
-
     // Create a TreePattern to parse this.
-    TreePattern P(DefaultOps[i], DI, false, *this);
+    TreePattern P(DefaultOps[i], DefaultInfo->getArgs(),
+                  DefaultInfo->getArgNames(), false, *this);
     assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
 
     // Copy the operands over into a DAGDefaultOperand.

diff  --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
index 633327e2f74e5..9a67933013c1c 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
@@ -917,6 +917,9 @@ class TreePattern {
               CodeGenDAGPatterns &ise);
   TreePattern(const Record *TheRec, const DagInit *Pat, bool isInput,
               CodeGenDAGPatterns &ise);
+  TreePattern(const Record *TheRec, ArrayRef<const Init *> Args,
+              ArrayRef<const StringInit *> ArgNames, bool isInput,
+              CodeGenDAGPatterns &ise);
   TreePattern(const Record *TheRec, TreePatternNodePtr Pat, bool isInput,
               CodeGenDAGPatterns &ise);
 
@@ -981,6 +984,9 @@ class TreePattern {
 
 private:
   TreePatternNodePtr ParseTreePattern(const Init *DI, StringRef OpName);
+  TreePatternNodePtr
+  ParseRootlessTreePattern(ArrayRef<const Init *> Args,
+                           ArrayRef<const StringInit *> ArgNames);
   void ComputeNamedNodes();
   void ComputeNamedNodes(TreePatternNode &N);
 };


        


More information about the llvm-commits mailing list