From dbe9300bddf25a592a123aa78c798cae8f40c784 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Sat, 16 Nov 2024 01:01:21 +0300 Subject: [PATCH 1/6] 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 &Results, SelectionDAG &DAG) const override; - const char *getTargetNodeName(unsigned Opcode) const override; std::pair 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(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 ff672b2fbefe30beae97a0ccf5541d9ef2415aaa Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Sun, 16 Nov 2025 17:08:58 +0300 Subject: [PATCH 2/6] 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(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 9d03bd52ca7506e02d5fc39100c2beae01395bde Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Sun, 16 Nov 2025 17:09:27 +0300 Subject: [PATCH 3/6] 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(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 e147bb5d8e8df2a23d92f2948642555559b76221 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Sun, 16 Nov 2025 17:14:26 +0300 Subject: [PATCH 4/6] 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, 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, 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)>; From d526fa328d219a59939d856fca7f219aa0d2505f Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Sun, 16 Nov 2025 17:18:33 +0300 Subject: [PATCH 5/6] clang-format --- llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h index 01ff8300956df..d1d5b0c7ac0ee 100644 --- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h +++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.h @@ -55,7 +55,6 @@ enum NodeType : unsigned { 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 @@ -77,6 +76,6 @@ class HexagonSelectionDAGInfo : public SelectionDAGGenTargetInfo { MachinePointerInfo SrcPtrInfo) const override; }; -} +} // namespace llvm #endif From 20effe5cda13bcb46fcf70ec386f5ebb609f8389 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Sun, 16 Nov 2025 19:14:50 +0300 Subject: [PATCH 6/6] Exclude one more node from verification --- llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp index a254584173e3c..4b9d2b92f451a 100644 --- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp @@ -54,6 +54,8 @@ void HexagonSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG, break; case HexagonISD::VALIGNADDR: // invalid number of operands; expected 1, got 2 + case HexagonISD::VINSERTW0: + // operand #1 must have type i32, but has type v4i8/v2i16 return; }