[llvm] [Hexagon] TableGen-erate SDNode descriptions (PR #168272)

Sergei Barannikov via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 16 06:17:29 PST 2025


https://github.com/s-barannikov created https://github.com/llvm/llvm-project/pull/168272

This allows SDNodes to be validated against their expected type profiles
and reduces the number of changes required to add a new node.

There is just one node that currently fails validation, VALIGNADDR.

Part of #119709.


>From 92eea513ad46e5ddd43680458b243e203ecc66fd Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 16 Nov 2024 01:01:21 +0300
Subject: [PATCH 1/4] Hexagon

---
 llvm/lib/Target/Hexagon/CMakeLists.txt        |  1 +
 .../Target/Hexagon/HexagonISelLowering.cpp    | 62 ------------
 llvm/lib/Target/Hexagon/HexagonISelLowering.h | 97 -------------------
 .../Hexagon/HexagonSelectionDAGInfo.cpp       | 59 +++++++++++
 .../Target/Hexagon/HexagonSelectionDAGInfo.h  | 61 +++++++++++-
 5 files changed, 119 insertions(+), 161 deletions(-)

diff --git a/llvm/lib/Target/Hexagon/CMakeLists.txt b/llvm/lib/Target/Hexagon/CMakeLists.txt
index 1a5f09642ea66..85ec5c7c2d45e 100644
--- a/llvm/lib/Target/Hexagon/CMakeLists.txt
+++ b/llvm/lib/Target/Hexagon/CMakeLists.txt
@@ -11,6 +11,7 @@ tablegen(LLVM HexagonGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM HexagonGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM HexagonGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM HexagonGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM HexagonGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM HexagonGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(HexagonCommonTableGen)
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index 894a07e6b68c2..87fbcfec600e7 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -1914,66 +1914,6 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
   computeRegisterProperties(&HRI);
 }
 
-const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch ((HexagonISD::NodeType)Opcode) {
-  case HexagonISD::ADDC:          return "HexagonISD::ADDC";
-  case HexagonISD::SUBC:          return "HexagonISD::SUBC";
-  case HexagonISD::ALLOCA:        return "HexagonISD::ALLOCA";
-  case HexagonISD::AT_GOT:        return "HexagonISD::AT_GOT";
-  case HexagonISD::AT_PCREL:      return "HexagonISD::AT_PCREL";
-  case HexagonISD::BARRIER:       return "HexagonISD::BARRIER";
-  case HexagonISD::CALL:          return "HexagonISD::CALL";
-  case HexagonISD::CALLnr:        return "HexagonISD::CALLnr";
-  case HexagonISD::CALLR:         return "HexagonISD::CALLR";
-  case HexagonISD::COMBINE:       return "HexagonISD::COMBINE";
-  case HexagonISD::CONST32_GP:    return "HexagonISD::CONST32_GP";
-  case HexagonISD::CONST32:       return "HexagonISD::CONST32";
-  case HexagonISD::CP:            return "HexagonISD::CP";
-  case HexagonISD::DCFETCH:       return "HexagonISD::DCFETCH";
-  case HexagonISD::EH_RETURN:     return "HexagonISD::EH_RETURN";
-  case HexagonISD::TSTBIT:        return "HexagonISD::TSTBIT";
-  case HexagonISD::EXTRACTU:      return "HexagonISD::EXTRACTU";
-  case HexagonISD::INSERT:        return "HexagonISD::INSERT";
-  case HexagonISD::JT:            return "HexagonISD::JT";
-  case HexagonISD::RET_GLUE:      return "HexagonISD::RET_GLUE";
-  case HexagonISD::TC_RETURN:     return "HexagonISD::TC_RETURN";
-  case HexagonISD::VASL:          return "HexagonISD::VASL";
-  case HexagonISD::VASR:          return "HexagonISD::VASR";
-  case HexagonISD::VLSR:          return "HexagonISD::VLSR";
-  case HexagonISD::MFSHL:         return "HexagonISD::MFSHL";
-  case HexagonISD::MFSHR:         return "HexagonISD::MFSHR";
-  case HexagonISD::SSAT:          return "HexagonISD::SSAT";
-  case HexagonISD::USAT:          return "HexagonISD::USAT";
-  case HexagonISD::SMUL_LOHI:     return "HexagonISD::SMUL_LOHI";
-  case HexagonISD::UMUL_LOHI:     return "HexagonISD::UMUL_LOHI";
-  case HexagonISD::USMUL_LOHI:    return "HexagonISD::USMUL_LOHI";
-  case HexagonISD::VEXTRACTW:     return "HexagonISD::VEXTRACTW";
-  case HexagonISD::VINSERTW0:     return "HexagonISD::VINSERTW0";
-  case HexagonISD::VROR:          return "HexagonISD::VROR";
-  case HexagonISD::READCYCLE:     return "HexagonISD::READCYCLE";
-  case HexagonISD::READTIMER:     return "HexagonISD::READTIMER";
-  case HexagonISD::THREAD_POINTER:
-    return "HexagonISD::THREAD_POINTER";
-  case HexagonISD::PTRUE:         return "HexagonISD::PTRUE";
-  case HexagonISD::PFALSE:        return "HexagonISD::PFALSE";
-  case HexagonISD::D2P:           return "HexagonISD::D2P";
-  case HexagonISD::P2D:           return "HexagonISD::P2D";
-  case HexagonISD::V2Q:           return "HexagonISD::V2Q";
-  case HexagonISD::Q2V:           return "HexagonISD::Q2V";
-  case HexagonISD::QCAT:          return "HexagonISD::QCAT";
-  case HexagonISD::QTRUE:         return "HexagonISD::QTRUE";
-  case HexagonISD::QFALSE:        return "HexagonISD::QFALSE";
-  case HexagonISD::TL_EXTEND:     return "HexagonISD::TL_EXTEND";
-  case HexagonISD::TL_TRUNCATE:   return "HexagonISD::TL_TRUNCATE";
-  case HexagonISD::TYPECAST:      return "HexagonISD::TYPECAST";
-  case HexagonISD::VALIGN:        return "HexagonISD::VALIGN";
-  case HexagonISD::VALIGNADDR:    return "HexagonISD::VALIGNADDR";
-  case HexagonISD::ISEL:          return "HexagonISD::ISEL";
-  case HexagonISD::OP_END:        break;
-  }
-  return nullptr;
-}
-
 bool
 HexagonTargetLowering::validateConstPtrAlignment(SDValue Ptr, Align NeedAlign,
       const SDLoc &dl, SelectionDAG &DAG) const {
@@ -3368,8 +3308,6 @@ HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
     default:
 #ifndef NDEBUG
       Op.getNode()->dumpr(&DAG);
-      if (Opc > HexagonISD::OP_BEGIN && Opc < HexagonISD::OP_END)
-        errs() << "Error: check for a non-legal type in this operation\n";
 #endif
       llvm_unreachable("Should not custom lower this!");
 
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
index f4d2a79051c10..580cb48e37465 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
@@ -29,102 +29,6 @@
 
 namespace llvm {
 
-namespace HexagonISD {
-
-// clang-format off
-enum NodeType : unsigned {
-  OP_BEGIN = ISD::BUILTIN_OP_END,
-
-  CONST32 = OP_BEGIN,
-  CONST32_GP,  // For marking data present in GP.
-  ADDC,        // Add with carry: (X, Y, Cin) -> (X+Y, Cout).
-  SUBC,        // Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
-  ALLOCA,
-
-  AT_GOT,      // Index in GOT.
-  AT_PCREL,    // Offset relative to PC.
-
-  CALL,        // Function call.
-  CALLnr,      // Function call that does not return.
-  CALLR,
-
-  RET_GLUE,    // Return with a glue operand.
-  BARRIER,     // Memory barrier.
-  JT,          // Jump table.
-  CP,          // Constant pool.
-
-  COMBINE,
-  VASL,        // Vector shifts by a scalar value
-  VASR,
-  VLSR,
-  MFSHL,       // Funnel shifts with the shift amount guaranteed to be
-  MFSHR,       // within the range of the bit width of the element.
-
-  SSAT,        // Signed saturate.
-  USAT,        // Unsigned saturate.
-  SMUL_LOHI,   // Same as ISD::SMUL_LOHI, but opaque to the combiner.
-  UMUL_LOHI,   // Same as ISD::UMUL_LOHI, but opaque to the combiner.
-               // We want to legalize MULH[SU] to [SU]MUL_LOHI, but the
-               // combiner will keep rewriting it back to MULH[SU].
-  USMUL_LOHI,  // Like SMUL_LOHI, but unsigned*signed.
-
-  TSTBIT,
-  INSERT,
-  EXTRACTU,
-  VEXTRACTW,
-  VINSERTW0,
-  VROR,
-  TC_RETURN,
-  EH_RETURN,
-  DCFETCH,
-  READCYCLE,
-  READTIMER,
-  THREAD_POINTER,
-  PTRUE,
-  PFALSE,
-  D2P,         // Convert 8-byte value to 8-bit predicate register. [*]
-  P2D,         // Convert 8-bit predicate register to 8-byte value. [*]
-  V2Q,         // Convert HVX vector to a vector predicate reg. [*]
-  Q2V,         // Convert vector predicate to an HVX vector. [*]
-               // [*] The equivalence is defined as "Q <=> (V != 0)",
-               //     where the != operation compares bytes.
-               // Note: V != 0 is implemented as V >u 0.
-  QCAT,
-  QTRUE,
-  QFALSE,
-
-  TL_EXTEND,   // Wrappers for ISD::*_EXTEND and ISD::TRUNCATE to prevent DAG
-  TL_TRUNCATE, // from auto-folding operations, e.g.
-               // (i32 ext (i16 ext i8)) would be folded to (i32 ext i8).
-               // To simplify the type legalization, we want to keep these
-               // single steps separate during type legalization.
-               // TL_[EXTEND|TRUNCATE] Inp, i128 _, i32 Opc
-               // * Inp is the original input to extend/truncate,
-               // * _ is a dummy operand with an illegal type (can be undef),
-               // * Opc is the original opcode.
-               // The legalization process (in Hexagon lowering code) will
-               // first deal with the "real" types (i.e. Inp and the result),
-               // and once all of them are processed, the wrapper node will
-               // be replaced with the original ISD node. The dummy illegal
-               // operand is there to make sure that the legalization hooks
-               // are called again after everything else is legal, giving
-               // us the opportunity to undo the wrapping.
-
-  TYPECAST,    // No-op that's used to convert between different legal
-               // types in a register.
-  VALIGN,      // Align two vectors (in Op0, Op1) to one that would have
-               // been loaded from address in Op2.
-  VALIGNADDR,  // Align vector address: Op0 & -Op1, except when it is
-               // an address in a vector load, then it's a no-op.
-  ISEL,        // Marker for nodes that were created during ISel, and
-               // which need explicit selection (would have been left
-               // unselected otherwise).
-  OP_END
-};
-
-} // end namespace HexagonISD
-// clang-format on
-
 class HexagonSubtarget;
 
 class HexagonTargetLowering : public TargetLowering {
@@ -189,7 +93,6 @@ class HexagonTargetLowering : public TargetLowering {
   void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
                           SelectionDAG &DAG) const override;
 
-  const char *getTargetNodeName(unsigned Opcode) const override;
   std::pair<MVT, unsigned>
   handleMaskRegisterForCallingConv(const HexagonSubtarget &Subtarget,
                                    EVT VT) const;
diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
index 33aa6e4a26145..ef8951cb43126 100644
--- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
@@ -10,12 +10,71 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "HexagonSelectionDAGInfo.h"
 #include "HexagonTargetMachine.h"
 #include "llvm/CodeGen/SelectionDAG.h"
+
+#define GET_SDNODE_DESC
+#include "HexagonGenSDNodeInfo.inc"
+
 using namespace llvm;
 
 #define DEBUG_TYPE "hexagon-selectiondag-info"
 
+HexagonSelectionDAGInfo::HexagonSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(HexagonGenSDNodeInfo) {}
+
+const char *HexagonSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+  // These nodes don't have corresponding entries in *.td files yet.
+  switch (static_cast<HexagonISD::NodeType>(Opcode)) {
+  case HexagonISD::ADDC:
+    return "HexagonISD::ADDC";
+  case HexagonISD::SUBC:
+    return "HexagonISD::SUBC";
+  case HexagonISD::CALLR:
+    return "HexagonISD::CALLR";
+  case HexagonISD::SMUL_LOHI:
+    return "HexagonISD::SMUL_LOHI";
+  case HexagonISD::UMUL_LOHI:
+    return "HexagonISD::UMUL_LOHI";
+  case HexagonISD::USMUL_LOHI:
+    return "HexagonISD::USMUL_LOHI";
+  case HexagonISD::VROR:
+    return "HexagonISD::VROR";
+  case HexagonISD::D2P:
+    return "HexagonISD::D2P";
+  case HexagonISD::P2D:
+    return "HexagonISD::P2D";
+  case HexagonISD::V2Q:
+    return "HexagonISD::V2Q";
+  case HexagonISD::Q2V:
+    return "HexagonISD::Q2V";
+  case HexagonISD::TL_EXTEND:
+    return "HexagonISD::TL_EXTEND";
+  case HexagonISD::TL_TRUNCATE:
+    return "HexagonISD::TL_TRUNCATE";
+  case HexagonISD::TYPECAST:
+    return "HexagonISD::TYPECAST";
+  case HexagonISD::ISEL:
+    return "HexagonISD::ISEL";
+  }
+
+  return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
+}
+
+void HexagonSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                               const SDNode *N) const {
+  switch (N->getOpcode()) {
+  default:
+    break;
+  case HexagonISD::VALIGNADDR:
+    // invalid number of operands; expected 1, got 2
+    return;
+  }
+
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
+}
+
 SDValue HexagonSelectionDAGInfo::EmitTargetCodeForMemcpy(
     SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
     SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
index 0d3b1725d1bc4..c62be58901034 100644
--- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
+++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
@@ -15,11 +15,68 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "HexagonGenSDNodeInfo.inc"
+
 namespace llvm {
+namespace HexagonISD {
+
+enum NodeType : unsigned {
+  ADDC = GENERATED_OPCODE_END, // Add with carry: (X, Y, Cin) -> (X+Y, Cout).
+  SUBC, // Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
+
+  CALLR,
+
+  SMUL_LOHI,  // Same as ISD::SMUL_LOHI, but opaque to the combiner.
+  UMUL_LOHI,  // Same as ISD::UMUL_LOHI, but opaque to the combiner.
+              // We want to legalize MULH[SU] to [SU]MUL_LOHI, but the
+              // combiner will keep rewriting it back to MULH[SU].
+  USMUL_LOHI, // Like SMUL_LOHI, but unsigned*signed.
+
+  VROR,
+  D2P, // Convert 8-byte value to 8-bit predicate register. [*]
+  P2D, // Convert 8-bit predicate register to 8-byte value. [*]
+  V2Q, // Convert HVX vector to a vector predicate reg. [*]
+  Q2V, // Convert vector predicate to an HVX vector. [*]
+       // [*] The equivalence is defined as "Q <=> (V != 0)",
+       //     where the != operation compares bytes.
+       // Note: V != 0 is implemented as V >u 0.
+
+  TL_EXTEND,   // Wrappers for ISD::*_EXTEND and ISD::TRUNCATE to prevent DAG
+  TL_TRUNCATE, // from auto-folding operations, e.g.
+               // (i32 ext (i16 ext i8)) would be folded to (i32 ext i8).
+               // To simplify the type legalization, we want to keep these
+               // single steps separate during type legalization.
+               // TL_[EXTEND|TRUNCATE] Inp, i128 _, i32 Opc
+               // * Inp is the original input to extend/truncate,
+               // * _ is a dummy operand with an illegal type (can be undef),
+               // * Opc is the original opcode.
+               // The legalization process (in Hexagon lowering code) will
+               // first deal with the "real" types (i.e. Inp and the result),
+               // and once all of them are processed, the wrapper node will
+               // be replaced with the original ISD node. The dummy illegal
+               // operand is there to make sure that the legalization hooks
+               // are called again after everything else is legal, giving
+               // us the opportunity to undo the wrapping.
 
-class HexagonSelectionDAGInfo : public SelectionDAGTargetInfo {
+  TYPECAST, // No-op that's used to convert between different legal
+            // types in a register.
+  ISEL,     // Marker for nodes that were created during ISel, and
+            // which need explicit selection (would have been left
+            // unselected otherwise).
+  // clang-format on
+};
+
+} // namespace HexagonISD
+
+class HexagonSelectionDAGInfo : public SelectionDAGGenTargetInfo {
 public:
-  explicit HexagonSelectionDAGInfo() = default;
+  HexagonSelectionDAGInfo();
+
+  const char *getTargetNodeName(unsigned Opcode) const override;
+
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
 
   SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
                                   SDValue Chain, SDValue Dst, SDValue Src,

>From ae93d21587dbda367272f3dcdc0a9a4eb0902606 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sun, 16 Nov 2025 17:08:58 +0300
Subject: [PATCH 2/4] Add a few node definitions

---
 llvm/lib/Target/Hexagon/HexagonPatterns.td          | 10 ++++++++++
 llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp | 10 ----------
 llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h   | 11 +----------
 3 files changed, 11 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td
index e40dbd251b5b7..39b60cbbad134 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatterns.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td
@@ -92,6 +92,16 @@ def SDTVecLeaf:
 def SDTVecVecIntOp:
   SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<1,2>,
                        SDTCisVT<3,i32>]>;
+def SDTIntBinOpWithCarryInOut:
+  SDTypeProfile<2, 3, [SDTCisInt<0>, SDTCisVT<1, i1>, SDTCisSameAs<2, 0>,
+                       SDTCisSameAs<3, 0>, SDTCisVT<4, i1>]>;
+
+def HexagonADDC: SDNode<"HexagonISD::ADDC", SDTIntBinOpWithCarryInOut>;
+def HexagonSUBC: SDNode<"HexagonISD::SUBC", SDTIntBinOpWithCarryInOut>;
+
+def HexagonSMUL_LOHI: SDNode<"HexagonISD::SMUL_LOHI", SDTIntBinHiLoOp>;
+def HexagonUMUL_LOHI: SDNode<"HexagonISD::UMUL_LOHI", SDTIntBinHiLoOp>;
+def HexagonUSMUL_LOHI: SDNode<"HexagonISD::USMUL_LOHI", SDTIntBinHiLoOp>;
 
 def HexagonPTRUE:      SDNode<"HexagonISD::PTRUE",      SDTVecLeaf>;
 def HexagonPFALSE:     SDNode<"HexagonISD::PFALSE",     SDTVecLeaf>;
diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
index ef8951cb43126..3681343a81010 100644
--- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
@@ -27,18 +27,8 @@ HexagonSelectionDAGInfo::HexagonSelectionDAGInfo()
 const char *HexagonSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
   // These nodes don't have corresponding entries in *.td files yet.
   switch (static_cast<HexagonISD::NodeType>(Opcode)) {
-  case HexagonISD::ADDC:
-    return "HexagonISD::ADDC";
-  case HexagonISD::SUBC:
-    return "HexagonISD::SUBC";
   case HexagonISD::CALLR:
     return "HexagonISD::CALLR";
-  case HexagonISD::SMUL_LOHI:
-    return "HexagonISD::SMUL_LOHI";
-  case HexagonISD::UMUL_LOHI:
-    return "HexagonISD::UMUL_LOHI";
-  case HexagonISD::USMUL_LOHI:
-    return "HexagonISD::USMUL_LOHI";
   case HexagonISD::VROR:
     return "HexagonISD::VROR";
   case HexagonISD::D2P:
diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
index c62be58901034..01ff8300956df 100644
--- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
+++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
@@ -22,16 +22,7 @@ namespace llvm {
 namespace HexagonISD {
 
 enum NodeType : unsigned {
-  ADDC = GENERATED_OPCODE_END, // Add with carry: (X, Y, Cin) -> (X+Y, Cout).
-  SUBC, // Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
-
-  CALLR,
-
-  SMUL_LOHI,  // Same as ISD::SMUL_LOHI, but opaque to the combiner.
-  UMUL_LOHI,  // Same as ISD::UMUL_LOHI, but opaque to the combiner.
-              // We want to legalize MULH[SU] to [SU]MUL_LOHI, but the
-              // combiner will keep rewriting it back to MULH[SU].
-  USMUL_LOHI, // Like SMUL_LOHI, but unsigned*signed.
+  CALLR = GENERATED_OPCODE_END,
 
   VROR,
   D2P, // Convert 8-byte value to 8-bit predicate register. [*]

>From dd294e35d7c1c11e99a64282fb263626b20b19f8 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sun, 16 Nov 2025 17:09:27 +0300
Subject: [PATCH 3/4] Use macro in getTargetNodeName

---
 .../Hexagon/HexagonSelectionDAGInfo.cpp       | 35 ++++++++-----------
 1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
index 3681343a81010..a254584173e3c 100644
--- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
@@ -25,29 +25,24 @@ HexagonSelectionDAGInfo::HexagonSelectionDAGInfo()
     : SelectionDAGGenTargetInfo(HexagonGenSDNodeInfo) {}
 
 const char *HexagonSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
+#define CASE(NAME)                                                             \
+  case HexagonISD::NAME:                                                       \
+    return "HexagonISD::" #NAME
+
   // These nodes don't have corresponding entries in *.td files yet.
   switch (static_cast<HexagonISD::NodeType>(Opcode)) {
-  case HexagonISD::CALLR:
-    return "HexagonISD::CALLR";
-  case HexagonISD::VROR:
-    return "HexagonISD::VROR";
-  case HexagonISD::D2P:
-    return "HexagonISD::D2P";
-  case HexagonISD::P2D:
-    return "HexagonISD::P2D";
-  case HexagonISD::V2Q:
-    return "HexagonISD::V2Q";
-  case HexagonISD::Q2V:
-    return "HexagonISD::Q2V";
-  case HexagonISD::TL_EXTEND:
-    return "HexagonISD::TL_EXTEND";
-  case HexagonISD::TL_TRUNCATE:
-    return "HexagonISD::TL_TRUNCATE";
-  case HexagonISD::TYPECAST:
-    return "HexagonISD::TYPECAST";
-  case HexagonISD::ISEL:
-    return "HexagonISD::ISEL";
+    CASE(CALLR);
+    CASE(VROR);
+    CASE(D2P);
+    CASE(P2D);
+    CASE(V2Q);
+    CASE(Q2V);
+    CASE(TL_EXTEND);
+    CASE(TL_TRUNCATE);
+    CASE(TYPECAST);
+    CASE(ISEL);
   }
+#undef CASE
 
   return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
 }

>From b87a1b35eab49c02e57bd94f40ab88efbb8bc48c Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sun, 16 Nov 2025 17:14:26 +0300
Subject: [PATCH 4/4] Move comments

---
 llvm/lib/Target/Hexagon/HexagonPatterns.td | 36 ++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td
index 39b60cbbad134..b4ad58d4c2f84 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatterns.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td
@@ -96,22 +96,43 @@ def SDTIntBinOpWithCarryInOut:
   SDTypeProfile<2, 3, [SDTCisInt<0>, SDTCisVT<1, i1>, SDTCisSameAs<2, 0>,
                        SDTCisSameAs<3, 0>, SDTCisVT<4, i1>]>;
 
+// Add with carry: (X, Y, Cin) -> (X+Y, Cout).
 def HexagonADDC: SDNode<"HexagonISD::ADDC", SDTIntBinOpWithCarryInOut>;
+
+// Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
 def HexagonSUBC: SDNode<"HexagonISD::SUBC", SDTIntBinOpWithCarryInOut>;
 
+// Same as ISD::SMUL_LOHI, but opaque to the combiner.
+// We want to legalize MULH[SU] to [SU]MUL_LOHI, but the
+// combiner will keep rewriting it back to MULH[SU].
 def HexagonSMUL_LOHI: SDNode<"HexagonISD::SMUL_LOHI", SDTIntBinHiLoOp>;
+
+// Same as ISD::UMUL_LOHI, but opaque to the combiner.
 def HexagonUMUL_LOHI: SDNode<"HexagonISD::UMUL_LOHI", SDTIntBinHiLoOp>;
+
+// Like SMUL_LOHI, but unsigned*signed.
 def HexagonUSMUL_LOHI: SDNode<"HexagonISD::USMUL_LOHI", SDTIntBinHiLoOp>;
 
 def HexagonPTRUE:      SDNode<"HexagonISD::PTRUE",      SDTVecLeaf>;
 def HexagonPFALSE:     SDNode<"HexagonISD::PFALSE",     SDTVecLeaf>;
+
+// Align two vectors (in Op0, Op1) to one that would have
+// been loaded from address in Op2.
 def HexagonVALIGN:     SDNode<"HexagonISD::VALIGN",     SDTVecVecIntOp>;
+
+// Align vector address: Op0 & -Op1, except when it is
+// an address in a vector load, then it's a no-op.
 def HexagonVALIGNADDR: SDNode<"HexagonISD::VALIGNADDR", SDTIntUnaryOp>;
+
 def HexagonMULHUS:     SDNode<"HexagonISD::MULHUS",     SDTIntBinOp>;
 
 def SDTSaturate:
   SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>, SDTCisVT<2, OtherVT>]>;
+
+// Signed saturate.
 def HexagonSSAT: SDNode<"HexagonISD::SSAT", SDTSaturate>;
+
+// Unsigned saturate.
 def HexagonUSAT: SDNode<"HexagonISD::USAT", SDTSaturate>;
 
 def ptrue:  PatFrag<(ops), (HexagonPTRUE)>;
@@ -418,9 +439,15 @@ def Imm64Hi: SDNodeXForm<imm, [{
 def SDTHexagonCONST32
   : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisPtrTy<0>]>;
 
+// Jump table.
 def HexagonJT:          SDNode<"HexagonISD::JT",          SDTIntUnaryOp>;
+
+// Constant pool.
 def HexagonCP:          SDNode<"HexagonISD::CP",          SDTIntUnaryOp>;
+
 def HexagonCONST32:     SDNode<"HexagonISD::CONST32",     SDTHexagonCONST32>;
+
+// For marking data present in GP.
 def HexagonCONST32_GP:  SDNode<"HexagonISD::CONST32_GP",  SDTHexagonCONST32>;
 
 def TruncI64ToI32: SDNodeXForm<imm, [{
@@ -1440,6 +1467,7 @@ let AddedComplexity = 200 in {
 def SDTHexagonVShift
   : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisVec<0>, SDTCisVT<2, i32>]>;
 
+// Vector shifts by a scalar value
 def HexagonVASL: SDNode<"HexagonISD::VASL", SDTHexagonVShift>;
 def HexagonVASR: SDNode<"HexagonISD::VASR", SDTHexagonVShift>;
 def HexagonVLSR: SDNode<"HexagonISD::VLSR", SDTHexagonVShift>;
@@ -3301,8 +3329,12 @@ def SDT_SPCall: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
 
 def HexagonTCRet: SDNode<"HexagonISD::TC_RETURN", SDT_SPCall,
                          [SDNPHasChain,  SDNPOptInGlue, SDNPVariadic]>;
+
+// Function call.
 def callv3: SDNode<"HexagonISD::CALL", SDT_SPCall,
                    [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
+
+// Function call that does not return.
 def callv3nr: SDNode<"HexagonISD::CALLnr", SDT_SPCall,
                      [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
 
@@ -3324,8 +3356,10 @@ def: Pat<(callv3nr I32:$dst),               (PS_callr_nr I32:$dst)>;
 def: Pat<(callv3nr tglobaladdr:$dst),       (PS_call_nr tglobaladdr:$dst)>;
 def: Pat<(callv3nr texternalsym:$dst),      (PS_call_nr texternalsym:$dst)>;
 
+// Return with a glue operand.
 def retglue : SDNode<"HexagonISD::RET_GLUE", SDTNone,
                      [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
+
 def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, [SDNPHasChain]>;
 
 def: Pat<(retglue),   (PS_jmpret (i32 R31))>;
@@ -3405,7 +3439,9 @@ def HexagonALLOCA
 def: Pat<(HexagonALLOCA I32:$Rs, (i32 imm:$A)),
          (PS_alloca IntRegs:$Rs, imm:$A)>;
 
+// Memory barrier.
 def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDTNone, [SDNPHasChain]>;
+
 def: Pat<(HexagonBARRIER), (Y2_barrier)>;
 
 def: Pat<(trap), (PS_crash)>;



More information about the llvm-commits mailing list