[llvm] [TableGen] Add a backend generating SDNode descriptions (PR #123002)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 14 19:04:53 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-selectiondag

Author: Sergei Barannikov (s-barannikov)

<details>
<summary>Changes</summary>

This patch adds a simplistic backend that gathers all target-specific SelectionDAG nodes and emits descriptions for most of them.

This includes generating node enumeration, node names, and information about node "prototype" that can be used to verify that a node is valid.

The patch also extends SDNode by adding target-specific flags, which are also included in the generated tables.

Part of #<!-- -->119709, [RFC](https://discourse.llvm.org/t/rfc-tablegen-erating-sdnode-descriptions/83627).

---

Patch is 38.59 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/123002.diff


9 Files Affected:

- (modified) llvm/include/llvm/Target/TargetSelectionDAG.td (+2) 
- (added) llvm/test/TableGen/SDNodeInfoEmitter/ambiguous-constraints.td (+73) 
- (added) llvm/test/TableGen/SDNodeInfoEmitter/basic.td (+85) 
- (added) llvm/test/TableGen/SDNodeInfoEmitter/namespace.td (+62) 
- (added) llvm/test/TableGen/SDNodeInfoEmitter/skipped-nodes.td (+91) 
- (modified) llvm/utils/TableGen/CMakeLists.txt (+1) 
- (modified) llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp (+79-24) 
- (modified) llvm/utils/TableGen/Common/CodeGenDAGPatterns.h (+17-25) 
- (added) llvm/utils/TableGen/SDNodeInfoEmitter.cpp (+369) 


``````````diff
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index bee0a4298c786f..cd2ca3a08bd691 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -353,6 +353,8 @@ class SDNode<string opcode, SDTypeProfile typeprof,
   string SDClass = sdclass;
   let Properties = props;
   SDTypeProfile TypeProfile = typeprof;
+  bit IsStrictFP = false;
+  bits<64> TSFlags = 0;
 }
 
 // Special TableGen-recognized dag nodes
diff --git a/llvm/test/TableGen/SDNodeInfoEmitter/ambiguous-constraints.td b/llvm/test/TableGen/SDNodeInfoEmitter/ambiguous-constraints.td
new file mode 100644
index 00000000000000..668464190e6d89
--- /dev/null
+++ b/llvm/test/TableGen/SDNodeInfoEmitter/ambiguous-constraints.td
@@ -0,0 +1,73 @@
+// RUN: split-file %s %t
+
+//--- test1.td
+// RUN: llvm-tblgen -gen-sd-node-info -I %p/../../../include %t/test1.td | FileCheck %t/test1.td
+
+include "llvm/Target/Target.td"
+
+def MyTarget : Target;
+
+def my_node_a : SDNode<"MyTargetISD::NODE", SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>>;
+def my_node_b : SDNode<"MyTargetISD::NODE", SDTypeProfile<1, 0, [SDTCisVT<0, f32>]>>;
+
+// CHECK:       enum GenNodeType : unsigned {
+// CHECK-NEXT:    NODE = ISD::BUILTIN_OP_END,
+// CHECK-NEXT:  };
+
+// CHECK:       static const char MyTargetSDNodeNames[] =
+// CHECK-NEXT:    "MyTargetISD::NODE\0"
+// CHECK-NEXT:    "\0";
+
+// CHECK:       static const SDTypeConstraint MyTargetSDTypeConstraints[] = {
+// CHECK-NEXT:    /* dummy */ {SDTCisVT, 0, 0, MVT::INVALID_SIMPLE_VALUE_TYPE}
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static const SDNodeDesc MyTargetSDNodeDescs[] = {
+// CHECK-NEXT:      {1, 0, 0, 0, 0, 0, 0, 0}, // NODE
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static const SDNodeInfo MyTargetGenSDNodeInfo(
+// CHECK-NEXT:      /*NumOpcodes=*/1, MyTargetSDNodeDescs,
+// CHECK-NEXT:      MyTargetSDNodeNames, MyTargetSDTypeConstraints);
+
+
+//--- test2.td
+// RUN: llvm-tblgen -gen-sd-node-info -I %p/../../../include %t/test2.td | FileCheck %t/test2.td
+
+include "llvm/Target/Target.td"
+
+def MyTarget : Target;
+
+def my_node_1a : SDNode<"MyTargetISD::NODE_1", SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>>;
+def my_node_1b : SDNode<"MyTargetISD::NODE_1", SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>>;
+def my_node_2a : SDNode<"MyTargetISD::NODE_2", SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>>;
+def my_node_2b : SDNode<"MyTargetISD::NODE_2", SDTypeProfile<1, 0, [SDTCisVT<0, untyped>]>>;
+
+// CHECK:       namespace llvm::MyTargetISD {
+// CHECK-EMPTY:
+// CHECK-NEXT:  enum GenNodeType : unsigned {
+// CHECK-NEXT:    NODE_1 = ISD::BUILTIN_OP_END,
+// CHECK-NEXT:    NODE_2,
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static constexpr unsigned GENERATED_OPCODE_END = NODE_2 + 1;
+// CHECK-EMPTY:
+// CHECK-NEXT:  } // namespace llvm::MyTargetISD
+
+// CHECK:       static const char MyTargetSDNodeNames[] =
+// CHECK-NEXT:    "MyTargetISD::NODE_1\0"
+// CHECK-NEXT:    "MyTargetISD::NODE_2\0"
+// CHECK-NEXT:    "\0";
+
+// CHECK:       static const SDTypeConstraint MyTargetSDTypeConstraints[] = {
+// CHECK-NEXT:    /* 0 */ {SDTCisVT, 0, 0, MVT::i32},
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static const SDNodeDesc MyTargetSDNodeDescs[] = {
+// CHECK-NEXT:      {1, 0, 0, 0, 0, 0, 0, 1}, // NODE_1
+// CHECK-NEXT:      {1, 0, 0, 0, 0, 20, 0, 0}, // NODE_2
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static const SDNodeInfo MyTargetGenSDNodeInfo(
+// CHECK-NEXT:      /*NumOpcodes=*/2, MyTargetSDNodeDescs,
+// CHECK-NEXT:      MyTargetSDNodeNames, MyTargetSDTypeConstraints);
diff --git a/llvm/test/TableGen/SDNodeInfoEmitter/basic.td b/llvm/test/TableGen/SDNodeInfoEmitter/basic.td
new file mode 100644
index 00000000000000..7f5085e31e02c4
--- /dev/null
+++ b/llvm/test/TableGen/SDNodeInfoEmitter/basic.td
@@ -0,0 +1,85 @@
+// RUN: split-file %s %t
+
+//--- no-nodes.td
+// RUN: llvm-tblgen -gen-sd-node-info -I %p/../../../include %t/no-nodes.td \
+// RUN:   | FileCheck %t/no-nodes.td
+
+include "llvm/Target/Target.td"
+
+def MyTarget : Target;
+
+// CHECK:       #ifdef GET_SDNODE_ENUM
+// CHECK-NEXT:  #undef GET_SDNODE_ENUM
+// CHECK-EMPTY:
+// CHECK-NEXT:  namespace llvm::MyTargetISD {
+// CHECK-EMPTY:
+// CHECK-NEXT:  static constexpr unsigned GENERATED_OPCODE_END = ISD::BUILTIN_OP_END;
+// CHECK-EMPTY:
+// CHECK-NEXT:  } // namespace llvm::MyTargetISD
+// CHECK-EMPTY:
+// CHECK-NEXT:  #endif // GET_SDNODE_ENUM
+// CHECK-EMPTY:
+// CHECK-NEXT:  #ifdef GET_SDNODE_DESC
+// CHECK-NEXT:  #undef GET_SDNODE_DESC
+// CHECK-EMPTY:
+// CHECK-NEXT:  namespace llvm {
+// CHECK-EMPTY:
+// CHECK-NEXT:  #ifdef __GNUC__
+// CHECK-NEXT:  #pragma GCC diagnostic push
+// CHECK-NEXT:  #pragma GCC diagnostic ignored "-Woverlength-strings"
+// CHECK-NEXT:  #endif
+// CHECK-NEXT:  static const char MyTargetSDNodeNames[] =
+// CHECK-NEXT:    "\0";
+// CHECK-NEXT:  #ifdef __GNUC__
+// CHECK-NEXT:  #pragma GCC diagnostic pop
+// CHECK-NEXT:  #endif
+// CHECK-EMPTY:
+// CHECK-NEXT:  static const SDTypeConstraint MyTargetSDTypeConstraints[] = {
+// CHECK-NEXT:    /* dummy */ {SDTCisVT, 0, 0, MVT::INVALID_SIMPLE_VALUE_TYPE}
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static const SDNodeDesc MyTargetSDNodeDescs[] = {
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static const SDNodeInfo MyTargetGenSDNodeInfo(
+// CHECK-NEXT:      /*NumOpcodes=*/0, MyTargetSDNodeDescs,
+// CHECK-NEXT:      MyTargetSDNodeNames, MyTargetSDTypeConstraints);
+// CHECK-EMPTY:
+// CHECK-NEXT:  } // namespace llvm
+
+
+//--- trivial-node.td
+// RUN: llvm-tblgen -gen-sd-node-info -I %p/../../../include %t/trivial-node.td \
+// RUN:   | FileCheck %t/trivial-node.td
+
+include "llvm/Target/Target.td"
+
+def MyTarget : Target;
+
+def my_noop : SDNode<"MyTargetISD::NOOP", SDTypeProfile<0, 0, []>>;
+
+// CHECK:       namespace llvm::MyTargetISD {
+// CHECK-EMPTY:
+// CHECK-NEXT:  enum GenNodeType : unsigned {
+// CHECK-NEXT:    NOOP = ISD::BUILTIN_OP_END,
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static constexpr unsigned GENERATED_OPCODE_END = NOOP + 1;
+// CHECK-EMPTY:
+// CHECK-NEXT:  } // namespace llvm::MyTargetISD
+
+// CHECK:       static const char MyTargetSDNodeNames[] =
+// CHECK-NEXT:    "MyTargetISD::NOOP\0"
+// CHECK-NEXT:    "\0";
+
+// CHECK:       static const SDTypeConstraint MyTargetSDTypeConstraints[] = {
+// CHECK-NEXT:    /* dummy */ {SDTCisVT, 0, 0, MVT::INVALID_SIMPLE_VALUE_TYPE}
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static const SDNodeDesc MyTargetSDNodeDescs[] = {
+// CHECK-NEXT:      {0, 0, 0, 0, 0, 0, 0, 0}, // NOOP
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static const SDNodeInfo MyTargetGenSDNodeInfo(
+// CHECK-NEXT:      /*NumOpcodes=*/1, MyTargetSDNodeDescs,
+// CHECK-NEXT:      MyTargetSDNodeNames, MyTargetSDTypeConstraints);
diff --git a/llvm/test/TableGen/SDNodeInfoEmitter/namespace.td b/llvm/test/TableGen/SDNodeInfoEmitter/namespace.td
new file mode 100644
index 00000000000000..844c12bd182fc6
--- /dev/null
+++ b/llvm/test/TableGen/SDNodeInfoEmitter/namespace.td
@@ -0,0 +1,62 @@
+// RUN: llvm-tblgen -gen-sd-node-info -I %p/../../../include %s -sdnode-namespace=EmptyISD \
+// RUN:   | FileCheck %s -check-prefix=EMPTY
+
+// RUN: llvm-tblgen -gen-sd-node-info -I %p/../../../include %s \
+// RUN:   | FileCheck %s --check-prefixes=COMMON,TARGET -DNS=MyTargetISD
+// RUN: llvm-tblgen -gen-sd-node-info -I %p/../../../include %s -sdnode-namespace=MyCustomISD \
+// RUN:   | FileCheck %s -check-prefixes=COMMON,CUSTOM -DNS=MyCustomISD
+
+include "llvm/Target/Target.td"
+
+def MyTarget : Target;
+
+def node_1 : SDNode<"MyTargetISD::NODE", SDTypeProfile<1, 0, [SDTCisVT<0, i1>]>>;
+def node_2 : SDNode<"MyCustomISD::NODE", SDTypeProfile<0, 1, [SDTCisVT<0, i2>]>>;
+
+// EMPTY:        namespace llvm::EmptyISD {
+// EMPTY-EMPTY:
+// EMPTY-NEXT:   static constexpr unsigned GENERATED_OPCODE_END = ISD::BUILTIN_OP_END;
+// EMPTY-EMPTY:
+// EMPTY-NEXT:   } // namespace llvm::EmptyISD
+
+// EMPTY:        static const char MyTargetSDNodeNames[] =
+// EMPTY-NEXT:     "\0";
+
+// EMPTY:        static const SDTypeConstraint MyTargetSDTypeConstraints[] = {
+// EMPTY-NEXT:     /* dummy */ {SDTCisVT, 0, 0, MVT::INVALID_SIMPLE_VALUE_TYPE}
+// EMPTY-NEXT:   };
+// EMPTY-EMPTY:
+// EMPTY-NEXT:   static const SDNodeDesc MyTargetSDNodeDescs[] = {
+// EMPTY-NEXT:   };
+// EMPTY-EMPTY:
+// EMPTY-NEXT:   static const SDNodeInfo MyTargetGenSDNodeInfo(
+// EMPTY-NEXT:       /*NumOpcodes=*/0, MyTargetSDNodeDescs,
+// EMPTY-NEXT:       MyTargetSDNodeNames, MyTargetSDTypeConstraints);
+
+// COMMON:       namespace llvm::[[NS]] {
+// COMMON-EMPTY:
+// COMMON-NEXT:  enum GenNodeType : unsigned {
+// COMMON-NEXT:    NODE = ISD::BUILTIN_OP_END,
+// COMMON-NEXT:  };
+// COMMON-EMPTY:
+// COMMON-NEXT:  static constexpr unsigned GENERATED_OPCODE_END = NODE + 1;
+// COMMON-EMPTY:
+// COMMON-NEXT:  } // namespace llvm::[[NS]]
+
+// COMMON:       static const char MyTargetSDNodeNames[] =
+// COMMON-NEXT:    "[[NS]]::NODE\0"
+// COMMON-NEXT:    "\0";
+
+// COMMON:       static const SDTypeConstraint MyTargetSDTypeConstraints[] = {
+// TARGET-NEXT:    /* 0 */ {SDTCisVT, 0, 0, MVT::i1},
+// CUSTOM-NEXT:    /* 0 */ {SDTCisVT, 0, 0, MVT::i2},
+// COMMON-NEXT:  };
+// COMMON-EMPTY:
+// COMMON-NEXT:  static const SDNodeDesc MyTargetSDNodeDescs[] = {
+// TARGET-NEXT:      {1, 0, 0, 0, 0, 0, 0, 1}, // NODE
+// CUSTOM-NEXT:      {0, 1, 0, 0, 0, 0, 0, 1}, // NODE
+// COMMON-NEXT:  };
+// COMMON-EMPTY:
+// COMMON-NEXT:  static const SDNodeInfo MyTargetGenSDNodeInfo(
+// COMMON-NEXT:      /*NumOpcodes=*/1, MyTargetSDNodeDescs,
+// COMMON-NEXT:      MyTargetSDNodeNames, MyTargetSDTypeConstraints);
diff --git a/llvm/test/TableGen/SDNodeInfoEmitter/skipped-nodes.td b/llvm/test/TableGen/SDNodeInfoEmitter/skipped-nodes.td
new file mode 100644
index 00000000000000..ed278f262ca8f7
--- /dev/null
+++ b/llvm/test/TableGen/SDNodeInfoEmitter/skipped-nodes.td
@@ -0,0 +1,91 @@
+// RUN: llvm-tblgen -gen-sd-node-info -I %p/../../../include %s 2> %t.warn | FileCheck %s
+// RUN: FileCheck --check-prefix=WARN --implicit-check-not=warning %s < %t.warn
+
+// RUN: llvm-tblgen -gen-sd-node-info -warn-on-skipped-nodes=false \
+// RUN:   -I %p/../../../include %s 2> %t.nowarn | FileCheck %s
+// RUN: not test -s %t.nowarn
+
+include "llvm/Target/Target.td"
+
+def MyTarget : Target;
+
+// WARN: [[#@LINE+1]]:5: warning: skipped node: invalid enum name
+def bad_name_1 : SDNode<"", SDTypeProfile<0, 0, []>>;
+
+// WARN: [[#@LINE+1]]:5: warning: skipped node: invalid enum name
+def bad_name_2 : SDNode<"NODE", SDTypeProfile<0, 0, []>>;
+
+// WARN: [[#@LINE+1]]:5: warning: skipped node: invalid enum name
+def bad_name_3 : SDNode<"MyTargetISD::", SDTypeProfile<0, 0, []>>;
+
+// WARN: [[#@LINE+1]]:5: warning: skipped node: invalid enum name
+def bad_name_4 : SDNode<"MyISD::", SDTypeProfile<0, 0, []>>;
+
+// WARN: [[#@LINE+1]]:5: warning: skipped node: invalid enum name
+def bad_name_5 : SDNode<"::NODE", SDTypeProfile<0, 0, []>>;
+
+
+// Standard namespace.
+def silent_1 : SDNode<"ISD::SILENT", SDTypeProfile<0, 0, []>>;
+
+// Different namespace.
+def silent_2 : SDNode<"MyISD::SILENT", SDTypeProfile<0, 0, []>>;
+
+
+// Different number of results.
+// WARN: [[#@LINE+2]]:5: warning: skipped node: incompatible description
+// WARN: [[#@LINE+2]]:5: warning: skipped node: incompatible description
+def node_1a : SDNode<"MyTargetISD::NODE_1", SDTypeProfile<0, 0, []>>;
+def node_1b : SDNode<"MyTargetISD::NODE_1", SDTypeProfile<1, 0, []>>;
+
+// Different number of operands.
+// WARN: [[#@LINE+2]]:5: warning: skipped node: incompatible description
+// WARN: [[#@LINE+2]]:5: warning: skipped node: incompatible description
+def node_2a : SDNode<"MyTargetISD::NODE_2", SDTypeProfile<0, 0, []>>;
+def node_2b : SDNode<"MyTargetISD::NODE_2", SDTypeProfile<0, 1, []>>;
+
+// Different value of IsStrictFP.
+// WARN: [[#@LINE+3]]:5: warning: skipped node: incompatible description
+// WARN: [[#@LINE+3]]:5: warning: skipped node: incompatible description
+let IsStrictFP = true in
+def node_3a : SDNode<"MyTargetISD::NODE_3", SDTypeProfile<0, 0, []>>;
+def node_3b : SDNode<"MyTargetISD::NODE_3", SDTypeProfile<0, 0, []>>;
+
+// Different value of TSFlags.
+// WARN: [[#@LINE+3]]:5: warning: skipped node: incompatible description
+// WARN: [[#@LINE+3]]:5: warning: skipped node: incompatible description
+let TSFlags = 1 in
+def node_4a : SDNode<"MyTargetISD::NODE_4", SDTypeProfile<0, 0, []>>;
+def node_4b : SDNode<"MyTargetISD::NODE_4", SDTypeProfile<0, 0, []>>;
+
+// Different properties.
+// WARN: [[#@LINE+2]]:5: warning: skipped node: incompatible description
+// WARN: [[#@LINE+2]]:5: warning: skipped node: incompatible description
+def node_5a : SDNode<"MyTargetISD::NODE_5", SDTypeProfile<0, 0, []>>;
+def node_5b : SDNode<"MyTargetISD::NODE_5", SDTypeProfile<0, 0, []>, [SDNPHasChain]>;
+
+
+// CHECK:       enum GenNodeType : unsigned {
+// CHECK-NEXT:    COMPAT = ISD::BUILTIN_OP_END,
+// CHECK-NEXT:  };
+
+// CHECK:       static const char MyTargetSDNodeNames[] =
+// CHECK-NEXT:    "MyTargetISD::COMPAT\0"
+// CHECK-NEXT:    "\0";
+
+// CHECK:       static const SDTypeConstraint MyTargetSDTypeConstraints[] = {
+// CHECK-NEXT:    /* dummy */ {SDTCisVT, 0, 0, MVT::INVALID_SIMPLE_VALUE_TYPE}
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static const SDNodeDesc MyTargetSDNodeDescs[] = {
+// CHECK-NEXT:      {1, -1, 0, 0, 0, 0, 0, 0}, // COMPAT
+// CHECK-NEXT:  };
+// CHECK-EMPTY:
+// CHECK-NEXT:  static const SDNodeInfo MyTargetGenSDNodeInfo(
+// CHECK-NEXT:      /*NumOpcodes=*/1, MyTargetSDNodeDescs,
+// CHECK-NEXT:      MyTargetSDNodeNames, MyTargetSDTypeConstraints);
+
+def compat_a : SDNode<"MyTargetISD::COMPAT", SDTypeProfile<1, -1, []>>;
+def compat_b : SDNode<"MyTargetISD::COMPAT", SDTypeProfile<1, -1, [SDTCisVT<0, untyped>]>>;
+def compat_c : SDNode<"MyTargetISD::COMPAT", SDTypeProfile<1, -1, [SDTCisVT<0, untyped>]>,
+    [SDNPCommutative, SDNPAssociative, SDNPMayStore, SDNPMayLoad, SDNPSideEffect]>;
diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt
index 96a74c6fd89f73..67291214c14e60 100644
--- a/llvm/utils/TableGen/CMakeLists.txt
+++ b/llvm/utils/TableGen/CMakeLists.txt
@@ -60,6 +60,7 @@ add_tablegen(llvm-tblgen LLVM
   PseudoLoweringEmitter.cpp
   RegisterBankEmitter.cpp
   RegisterInfoEmitter.cpp
+  SDNodeInfoEmitter.cpp
   SearchableTableEmitter.cpp
   SubtargetEmitter.cpp
   WebAssemblyDisassemblerEmitter.cpp
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
index 1a61d32b4869a4..6629baa6e071ea 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
@@ -1537,21 +1537,19 @@ SDTypeConstraint::SDTypeConstraint(const Record *R, const CodeGenHwModes &CGH) {
     ConstraintType = SDTCisVec;
   } else if (R->isSubClassOf("SDTCisSameAs")) {
     ConstraintType = SDTCisSameAs;
-    x.SDTCisSameAs_Info.OtherOperandNum = R->getValueAsInt("OtherOperandNum");
+    OtherOperandNo = R->getValueAsInt("OtherOperandNum");
   } else if (R->isSubClassOf("SDTCisVTSmallerThanOp")) {
     ConstraintType = SDTCisVTSmallerThanOp;
-    x.SDTCisVTSmallerThanOp_Info.OtherOperandNum =
-        R->getValueAsInt("OtherOperandNum");
+    OtherOperandNo = R->getValueAsInt("OtherOperandNum");
   } else if (R->isSubClassOf("SDTCisOpSmallerThanOp")) {
     ConstraintType = SDTCisOpSmallerThanOp;
-    x.SDTCisOpSmallerThanOp_Info.BigOperandNum =
-        R->getValueAsInt("BigOperandNum");
+    OtherOperandNo = R->getValueAsInt("BigOperandNum");
   } else if (R->isSubClassOf("SDTCisEltOfVec")) {
     ConstraintType = SDTCisEltOfVec;
-    x.SDTCisEltOfVec_Info.OtherOperandNum = R->getValueAsInt("OtherOpNum");
+    OtherOperandNo = R->getValueAsInt("OtherOpNum");
   } else if (R->isSubClassOf("SDTCisSubVecOfVec")) {
     ConstraintType = SDTCisSubVecOfVec;
-    x.SDTCisSubVecOfVec_Info.OtherOperandNum = R->getValueAsInt("OtherOpNum");
+    OtherOperandNo = R->getValueAsInt("OtherOpNum");
   } else if (R->isSubClassOf("SDTCVecEltisVT")) {
     ConstraintType = SDTCVecEltisVT;
     VVT = getValueTypeByHwMode(R->getValueAsDef("VT"), CGH);
@@ -1566,12 +1564,10 @@ SDTypeConstraint::SDTypeConstraint(const Record *R, const CodeGenHwModes &CGH) {
     }
   } else if (R->isSubClassOf("SDTCisSameNumEltsAs")) {
     ConstraintType = SDTCisSameNumEltsAs;
-    x.SDTCisSameNumEltsAs_Info.OtherOperandNum =
-        R->getValueAsInt("OtherOperandNum");
+    OtherOperandNo = R->getValueAsInt("OtherOperandNum");
   } else if (R->isSubClassOf("SDTCisSameSizeAs")) {
     ConstraintType = SDTCisSameSizeAs;
-    x.SDTCisSameSizeAs_Info.OtherOperandNum =
-        R->getValueAsInt("OtherOperandNum");
+    OtherOperandNo = R->getValueAsInt("OtherOperandNum");
   } else {
     PrintFatalError(R->getLoc(),
                     "Unrecognized SDTypeConstraint '" + R->getName() + "'!\n");
@@ -1632,7 +1628,7 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode &N,
   case SDTCisSameAs: {
     unsigned OResNo = 0;
     TreePatternNode &OtherNode =
-        getOperandNum(x.SDTCisSameAs_Info.OtherOperandNum, N, NodeInfo, OResNo);
+        getOperandNum(OtherOperandNo, N, NodeInfo, OResNo);
     return (int)NodeToApply.UpdateNodeType(ResNo, OtherNode.getExtType(OResNo),
                                            TP) |
            (int)OtherNode.UpdateNodeType(OResNo, NodeToApply.getExtType(ResNo),
@@ -1654,23 +1650,23 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode &N,
     TypeSetByHwMode TypeListTmp(VVT);
 
     unsigned OResNo = 0;
-    TreePatternNode &OtherNode = getOperandNum(
-        x.SDTCisVTSmallerThanOp_Info.OtherOperandNum, N, NodeInfo, OResNo);
+    TreePatternNode &OtherNode =
+        getOperandNum(OtherOperandNo, N, NodeInfo, OResNo);
 
     return TI.EnforceSmallerThan(TypeListTmp, OtherNode.getExtType(OResNo),
                                  /*SmallIsVT*/ true);
   }
   case SDTCisOpSmallerThanOp: {
     unsigned BResNo = 0;
-    TreePatternNode &BigOperand = getOperandNum(
-        x.SDTCisOpSmallerThanOp_Info.BigOperandNum, N, NodeInfo, BResNo);
+    TreePatternNode &BigOperand =
+        getOperandNum(OtherOperandNo, N, NodeInfo, BResNo);
     return TI.EnforceSmallerThan(NodeToApply.getExtType(ResNo),
                                  BigOperand.getExtType(BResNo));
   }
   case SDTCisEltOfVec: {
     unsigned VResNo = 0;
-    TreePatternNode &VecOperand = getOperandNum(
-        x.SDTCisEltOfVec_Info.OtherOperandNum, N, NodeInfo, VResNo);
+    TreePatternNode &VecOperand =
+        getOperandNum(OtherOperandNo, N, NodeInfo, VResNo);
     // Filter vector types out of VecOperand that don't have the right element
     // type.
     return TI.EnforceVectorEltTypeIs(VecOperand.getExtType(VResNo),
@@ -1678,8 +1674,8 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode &N,
   }
   case SDTCisSubVecOfVec: {
     unsigned VResNo = 0;
-    TreePatternNode &BigVecOperand = getOperandNum(
-        x.SDTCisSubVecOfVec_Info.OtherOperandNum, N, NodeInfo, VResNo);
+    TreePatternNode &BigVecOperand =
+        getOperandNum(OtherOperandNo, N, NodeInfo, VResNo);
 
     // Filter vector types out of BigVecOperand that don't have the
     // right subvector type.
@@ -1691,15 +1687,15 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode &N,
   }
   case SDTCisSameNumEltsAs: {
     unsigned OResNo = 0;
-    TreePatternNode &OtherNode = getOperandNum(
-        x.SDTCisSameNumEltsAs_Info.OtherOperandNum, N, NodeInfo, OResNo);
+    TreePatternNode &OtherNode =
+        getOperandNum(OtherOperandNo, N, NodeInfo, OResNo);
     return TI.EnforceSameNumElts(OtherNode.getExtType(OResNo),
                                  NodeToApply.getExtType(ResNo));
   }
   case SDTCisSameSizeAs: {
     unsigned OResNo = 0;
-    TreePatternNode &OtherNode = getOperandNum(
-        x.SDTCisSameSizeAs_Info.OtherOperandNum, N, NodeInfo, OResNo);
+    TreePatternNode &OtherNode =
+        getOperandNum(OtherOperandNo, N, NodeInfo, OResNo);
     return TI.EnforceSameSize(OtherNode.getExtType(OResNo),
                               NodeToApply.getExtType(ResNo));
   }
@@ -1707,6 +1703,58 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode &N,
   llvm_unreachable("Invalid ConstraintType!");
 }
 
+bool llvm::operator==(cons...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/123002


More information about the llvm-commits mailing list