[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