Skip to content

Conversation

@s-barannikov
Copy link
Contributor

@s-barannikov s-barannikov commented Nov 16, 2025

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

There are nodes that currently fail validation, see HexagonSelectionDAGInfo::verifyTargetNode().

Part of #119709.

@s-barannikov s-barannikov requested review from aankit-ca and androm3da and removed request for androm3da November 16, 2025 14:19
@s-barannikov s-barannikov marked this pull request as ready for review November 16, 2025 14:21
@llvmbot
Copy link
Member

llvmbot commented Nov 16, 2025

@llvm/pr-subscribers-backend-hexagon

Author: Sergei Barannikov (s-barannikov)

Changes

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, see HexagonSelectionDAGInfo::verifyTargetNode().

Part of #119709.


Full diff: https://github.com/llvm/llvm-project/pull/168272.diff

6 Files Affected:

  • (modified) llvm/lib/Target/Hexagon/CMakeLists.txt (+1)
  • (modified) llvm/lib/Target/Hexagon/HexagonISelLowering.cpp (-62)
  • (modified) llvm/lib/Target/Hexagon/HexagonISelLowering.h (-97)
  • (modified) llvm/lib/Target/Hexagon/HexagonPatterns.td (+46)
  • (modified) llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp (+44)
  • (modified) llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h (+50-3)
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/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td
index e40dbd251b5b7..b4ad58d4c2f84 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatterns.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td
@@ -92,16 +92,47 @@ 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>]>;
+
+// 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)>;
@@ -408,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, [{
@@ -1430,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>;
@@ -3291,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]>;
 
@@ -3314,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))>;
@@ -3395,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)>;
diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
index 33aa6e4a26145..a254584173e3c 100644
--- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
@@ -10,12 +10,56 @@
 //
 //===----------------------------------------------------------------------===//
 
+#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 {
+#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(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);
+}
+
+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..d1d5b0c7ac0ee 100644
--- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
+++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
@@ -15,11 +15,58 @@
 
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 
+#define GET_SDNODE_ENUM
+#include "HexagonGenSDNodeInfo.inc"
+
 namespace llvm {
+namespace HexagonISD {
+
+enum NodeType : unsigned {
+  CALLR = GENERATED_OPCODE_END,
+
+  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.
 
-class HexagonSelectionDAGInfo : public SelectionDAGTargetInfo {
+  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.
+  ISEL,     // Marker for nodes that were created during ISel, and
+            // which need explicit selection (would have been left
+            // unselected otherwise).
+};
+
+} // 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,
@@ -29,6 +76,6 @@ class HexagonSelectionDAGInfo : public SelectionDAGTargetInfo {
                                   MachinePointerInfo SrcPtrInfo) const override;
 };
 
-}
+} // namespace llvm
 
 #endif

def HexagonUMUL_LOHI: SDNode<"HexagonISD::UMUL_LOHI", SDTIntBinHiLoOp>;

// Like SMUL_LOHI, but unsigned*signed.
def HexagonUSMUL_LOHI: SDNode<"HexagonISD::USMUL_LOHI", SDTIntBinHiLoOp>;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a few more nodes here so that they can be "imported". These ones were very straightforward to add, I didn't try to add the remaining ones (listed in HexagonSelectionDAGInfo.h).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants