[llvm] b5812c0 - [LoongArch] TableGen-erate SDNode descriptions (#168129)

via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 20 07:29:51 PST 2025


Author: Sergei Barannikov
Date: 2025-11-20T15:29:46Z
New Revision: b5812c0cf789aa4cb60d42681cb2e46a417e1bc7

URL: https://github.com/llvm/llvm-project/commit/b5812c0cf789aa4cb60d42681cb2e46a417e1bc7
DIFF: https://github.com/llvm/llvm-project/commit/b5812c0cf789aa4cb60d42681cb2e46a417e1bc7.diff

LOG: [LoongArch] TableGen-erate SDNode descriptions (#168129)

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

I had to split `VSHUF4I` into two variants (`VSHUF4I` and `VSHUF4I_D`)
since `loongarch_vshuf4i` and `loongarch_vshuf4i_d` have different
number of operands, and this prevented the node from being imported.

There is just one node that currently fails validation, see
`LoongArchSelectionDAGInfo::verifyTargetNode()`.

Part of #119709.

Pull Request: https://github.com/llvm/llvm-project/pull/168129

Added: 
    llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.cpp
    llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.h

Modified: 
    llvm/lib/Target/LoongArch/CMakeLists.txt
    llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
    llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td
    llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h
    llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
    llvm/lib/Target/LoongArch/LoongArchISelLowering.h
    llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
    llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
    llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
    llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp
    llvm/lib/Target/LoongArch/LoongArchSubtarget.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/LoongArch/CMakeLists.txt b/llvm/lib/Target/LoongArch/CMakeLists.txt
index 0f674b1b0fa9e..8689d09140a1e 100644
--- a/llvm/lib/Target/LoongArch/CMakeLists.txt
+++ b/llvm/lib/Target/LoongArch/CMakeLists.txt
@@ -10,6 +10,7 @@ tablegen(LLVM LoongArchGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM LoongArchGenMCPseudoLowering.inc -gen-pseudo-lowering)
 tablegen(LLVM LoongArchGenMCCodeEmitter.inc -gen-emitter)
 tablegen(LLVM LoongArchGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM LoongArchGenSDNodeInfo.inc -gen-sd-node-info)
 tablegen(LLVM LoongArchGenSubtargetInfo.inc -gen-subtarget)
 
 add_public_tablegen_target(LoongArchCommonTableGen)
@@ -27,6 +28,7 @@ add_llvm_target(LoongArchCodeGen
   LoongArchMergeBaseOffset.cpp
   LoongArchOptWInstrs.cpp
   LoongArchRegisterInfo.cpp
+  LoongArchSelectionDAGInfo.cpp
   LoongArchSubtarget.cpp
   LoongArchTargetMachine.cpp
   LoongArchTargetTransformInfo.cpp

diff  --git a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
index e86b21cf849cb..32954b6c0d03f 100644
--- a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
@@ -30,13 +30,18 @@ def SDT_LoongArchFRSQRTE : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>;
 // ISD::BRCOND is custom-lowered to LoongArchISD::BRCOND for floating-point
 // comparisons to prevent recursive lowering.
 def loongarch_brcond : SDNode<"LoongArchISD::BRCOND", SDTBrcond, [SDNPHasChain]>;
+
+// FPR<->GPR transfer operations
 def loongarch_movgr2fr_w
     : SDNode<"LoongArchISD::MOVGR2FR_W", SDT_LoongArchMOVGR2FR_W>;
 def loongarch_movgr2fr_w_la64
     : SDNode<"LoongArchISD::MOVGR2FR_W_LA64", SDT_LoongArchMOVGR2FR_W_LA64>;
 def loongarch_movfr2gr_s_la64
     : SDNode<"LoongArchISD::MOVFR2GR_S_LA64", SDT_LoongArchMOVFR2GR_S_LA64>;
+
 def loongarch_ftint : SDNode<"LoongArchISD::FTINT", SDT_LoongArchFTINT>;
+
+// Floating point approximate reciprocal operation
 def loongarch_frecipe : SDNode<"LoongArchISD::FRECIPE", SDT_LoongArchFRECIPE>;
 def loongarch_frsqrte : SDNode<"LoongArchISD::FRSQRTE", SDT_LoongArchFRSQRTE>;
 

diff  --git a/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td
index 2e88254aab4d5..e6cad1b33aa23 100644
--- a/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td
@@ -20,6 +20,7 @@ def SDT_LoongArchMOVGR2FR_D_LO_HI
     : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>,
                            SDTCisSameAs<1, 2>]>;
 
+// FPR<->GPR transfer operations
 def loongarch_movgr2fr_d
     : SDNode<"LoongArchISD::MOVGR2FR_D", SDT_LoongArchMOVGR2FR_D>;
 def loongarch_movgr2fr_d_lo_hi

diff  --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h
index 1eed877dcef16..4c8dcb8fa48af 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h
@@ -14,6 +14,7 @@
 #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H
 
 #include "LoongArch.h"
+#include "LoongArchSelectionDAGInfo.h"
 #include "LoongArchTargetMachine.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 

diff  --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 83d841dba33e3..ac95ef5f30888 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -15,6 +15,7 @@
 #include "LoongArch.h"
 #include "LoongArchMachineFunctionInfo.h"
 #include "LoongArchRegisterInfo.h"
+#include "LoongArchSelectionDAGInfo.h"
 #include "LoongArchSubtarget.h"
 #include "MCTargetDesc/LoongArchBaseInfo.h"
 #include "MCTargetDesc/LoongArchMCTargetDesc.h"
@@ -1712,7 +1713,7 @@ lowerVECTOR_SHUFFLE_VSHUF4I(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
 
   // Return vshuf4i.d
   if (VT == MVT::v2f64 || VT == MVT::v2i64)
-    return DAG.getNode(LoongArchISD::VSHUF4I, DL, VT, V1, V2,
+    return DAG.getNode(LoongArchISD::VSHUF4I_D, DL, VT, V1, V2,
                        DAG.getConstant(Imm, DL, GRLenVT));
 
   return DAG.getNode(LoongArchISD::VSHUF4I, DL, VT, V1,
@@ -4459,7 +4460,7 @@ SDValue LoongArchTargetLowering::lowerShiftRightParts(SDValue Op,
 
 // Returns the opcode of the target-specific SDNode that implements the 32-bit
 // form of the given Opcode.
-static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode) {
+static unsigned getLoongArchWOpcode(unsigned Opcode) {
   switch (Opcode) {
   default:
     llvm_unreachable("Unexpected opcode");
@@ -4495,7 +4496,7 @@ static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode) {
 static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, int NumOp,
                                    unsigned ExtOpc = ISD::ANY_EXTEND) {
   SDLoc DL(N);
-  LoongArchISD::NodeType WOpcode = getLoongArchWOpcode(N->getOpcode());
+  unsigned WOpcode = getLoongArchWOpcode(N->getOpcode());
   SDValue NewOp0, NewRes;
 
   switch (NumOp) {
@@ -7483,123 +7484,6 @@ bool LoongArchTargetLowering::allowsMisalignedMemoryAccesses(
   return true;
 }
 
-const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch ((LoongArchISD::NodeType)Opcode) {
-  case LoongArchISD::FIRST_NUMBER:
-    break;
-
-#define NODE_NAME_CASE(node)                                                   \
-  case LoongArchISD::node:                                                     \
-    return "LoongArchISD::" #node;
-
-    // TODO: Add more target-dependent nodes later.
-    NODE_NAME_CASE(CALL)
-    NODE_NAME_CASE(CALL_MEDIUM)
-    NODE_NAME_CASE(CALL_LARGE)
-    NODE_NAME_CASE(RET)
-    NODE_NAME_CASE(TAIL)
-    NODE_NAME_CASE(TAIL_MEDIUM)
-    NODE_NAME_CASE(TAIL_LARGE)
-    NODE_NAME_CASE(SELECT_CC)
-    NODE_NAME_CASE(BR_CC)
-    NODE_NAME_CASE(BRCOND)
-    NODE_NAME_CASE(SLL_W)
-    NODE_NAME_CASE(SRA_W)
-    NODE_NAME_CASE(SRL_W)
-    NODE_NAME_CASE(BSTRINS)
-    NODE_NAME_CASE(BSTRPICK)
-    NODE_NAME_CASE(MOVGR2FR_W)
-    NODE_NAME_CASE(MOVGR2FR_W_LA64)
-    NODE_NAME_CASE(MOVGR2FR_D)
-    NODE_NAME_CASE(MOVGR2FR_D_LO_HI)
-    NODE_NAME_CASE(MOVFR2GR_S_LA64)
-    NODE_NAME_CASE(FTINT)
-    NODE_NAME_CASE(BUILD_PAIR_F64)
-    NODE_NAME_CASE(SPLIT_PAIR_F64)
-    NODE_NAME_CASE(REVB_2H)
-    NODE_NAME_CASE(REVB_2W)
-    NODE_NAME_CASE(BITREV_4B)
-    NODE_NAME_CASE(BITREV_8B)
-    NODE_NAME_CASE(BITREV_W)
-    NODE_NAME_CASE(ROTR_W)
-    NODE_NAME_CASE(ROTL_W)
-    NODE_NAME_CASE(DIV_W)
-    NODE_NAME_CASE(DIV_WU)
-    NODE_NAME_CASE(MOD_W)
-    NODE_NAME_CASE(MOD_WU)
-    NODE_NAME_CASE(CLZ_W)
-    NODE_NAME_CASE(CTZ_W)
-    NODE_NAME_CASE(DBAR)
-    NODE_NAME_CASE(IBAR)
-    NODE_NAME_CASE(BREAK)
-    NODE_NAME_CASE(SYSCALL)
-    NODE_NAME_CASE(CRC_W_B_W)
-    NODE_NAME_CASE(CRC_W_H_W)
-    NODE_NAME_CASE(CRC_W_W_W)
-    NODE_NAME_CASE(CRC_W_D_W)
-    NODE_NAME_CASE(CRCC_W_B_W)
-    NODE_NAME_CASE(CRCC_W_H_W)
-    NODE_NAME_CASE(CRCC_W_W_W)
-    NODE_NAME_CASE(CRCC_W_D_W)
-    NODE_NAME_CASE(CSRRD)
-    NODE_NAME_CASE(CSRWR)
-    NODE_NAME_CASE(CSRXCHG)
-    NODE_NAME_CASE(IOCSRRD_B)
-    NODE_NAME_CASE(IOCSRRD_H)
-    NODE_NAME_CASE(IOCSRRD_W)
-    NODE_NAME_CASE(IOCSRRD_D)
-    NODE_NAME_CASE(IOCSRWR_B)
-    NODE_NAME_CASE(IOCSRWR_H)
-    NODE_NAME_CASE(IOCSRWR_W)
-    NODE_NAME_CASE(IOCSRWR_D)
-    NODE_NAME_CASE(CPUCFG)
-    NODE_NAME_CASE(MOVGR2FCSR)
-    NODE_NAME_CASE(MOVFCSR2GR)
-    NODE_NAME_CASE(CACOP_D)
-    NODE_NAME_CASE(CACOP_W)
-    NODE_NAME_CASE(VSHUF)
-    NODE_NAME_CASE(VPICKEV)
-    NODE_NAME_CASE(VPICKOD)
-    NODE_NAME_CASE(VPACKEV)
-    NODE_NAME_CASE(VPACKOD)
-    NODE_NAME_CASE(VILVL)
-    NODE_NAME_CASE(VILVH)
-    NODE_NAME_CASE(VSHUF4I)
-    NODE_NAME_CASE(VREPLVEI)
-    NODE_NAME_CASE(VREPLGR2VR)
-    NODE_NAME_CASE(XVPERMI)
-    NODE_NAME_CASE(XVPERM)
-    NODE_NAME_CASE(XVREPLVE0)
-    NODE_NAME_CASE(XVREPLVE0Q)
-    NODE_NAME_CASE(XVINSVE0)
-    NODE_NAME_CASE(VPICK_SEXT_ELT)
-    NODE_NAME_CASE(VPICK_ZEXT_ELT)
-    NODE_NAME_CASE(VREPLVE)
-    NODE_NAME_CASE(VALL_ZERO)
-    NODE_NAME_CASE(VANY_ZERO)
-    NODE_NAME_CASE(VALL_NONZERO)
-    NODE_NAME_CASE(VANY_NONZERO)
-    NODE_NAME_CASE(FRECIPE)
-    NODE_NAME_CASE(FRSQRTE)
-    NODE_NAME_CASE(VSLLI)
-    NODE_NAME_CASE(VSRLI)
-    NODE_NAME_CASE(VBSLL)
-    NODE_NAME_CASE(VBSRL)
-    NODE_NAME_CASE(VLDREPL)
-    NODE_NAME_CASE(VMSKLTZ)
-    NODE_NAME_CASE(VMSKGEZ)
-    NODE_NAME_CASE(VMSKEQZ)
-    NODE_NAME_CASE(VMSKNEZ)
-    NODE_NAME_CASE(XVMSKLTZ)
-    NODE_NAME_CASE(XVMSKGEZ)
-    NODE_NAME_CASE(XVMSKEQZ)
-    NODE_NAME_CASE(XVMSKNEZ)
-    NODE_NAME_CASE(VHADDW)
-  }
-#undef NODE_NAME_CASE
-  return nullptr;
-}
-
 //===----------------------------------------------------------------------===//
 //                     Calling Convention Implementation
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index 8a4d7748467c7..232ac6092149d 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -21,179 +21,6 @@
 
 namespace llvm {
 class LoongArchSubtarget;
-namespace LoongArchISD {
-enum NodeType : unsigned {
-  FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-  // TODO: add more LoongArchISDs
-  CALL,
-  CALL_MEDIUM,
-  CALL_LARGE,
-  RET,
-  TAIL,
-  TAIL_MEDIUM,
-  TAIL_LARGE,
-
-  // Select
-  SELECT_CC,
-
-  // Branch
-  BR_CC,
-  BRCOND,
-
-  // 32-bit shifts, directly matching the semantics of the named LoongArch
-  // instructions.
-  SLL_W,
-  SRA_W,
-  SRL_W,
-
-  ROTL_W,
-  ROTR_W,
-
-  // unsigned 32-bit integer division
-  DIV_W,
-  MOD_W,
-  DIV_WU,
-  MOD_WU,
-
-  // FPR<->GPR transfer operations
-  MOVGR2FR_W,
-  MOVGR2FR_W_LA64,
-  MOVGR2FR_D,
-  MOVGR2FR_D_LO_HI,
-  MOVFR2GR_S_LA64,
-  MOVFCSR2GR,
-  MOVGR2FCSR,
-
-  FTINT,
-
-  // Build and split F64 pair
-  BUILD_PAIR_F64,
-  SPLIT_PAIR_F64,
-
-  // Bit counting operations
-  CLZ_W,
-  CTZ_W,
-
-  BSTRINS,
-  BSTRPICK,
-
-  // Byte-swapping and bit-reversal
-  REVB_2H,
-  REVB_2W,
-  BITREV_4B,
-  BITREV_8B,
-  BITREV_W,
-
-  // Intrinsic operations start ============================================
-  BREAK,
-  CACOP_D,
-  CACOP_W,
-  DBAR,
-  IBAR,
-  SYSCALL,
-
-  // CRC check operations
-  CRC_W_B_W,
-  CRC_W_H_W,
-  CRC_W_W_W,
-  CRC_W_D_W,
-  CRCC_W_B_W,
-  CRCC_W_H_W,
-  CRCC_W_W_W,
-  CRCC_W_D_W,
-
-  CSRRD,
-
-  // Write new value to CSR and return old value.
-  // Operand 0: A chain pointer.
-  // Operand 1: The new value to write.
-  // Operand 2: The address of the required CSR.
-  // Result 0: The old value of the CSR.
-  // Result 1: The new chain pointer.
-  CSRWR,
-
-  // Similar to CSRWR but with a write mask.
-  // Operand 0: A chain pointer.
-  // Operand 1: The new value to write.
-  // Operand 2: The write mask.
-  // Operand 3: The address of the required CSR.
-  // Result 0: The old value of the CSR.
-  // Result 1: The new chain pointer.
-  CSRXCHG,
-
-  // IOCSR access operations
-  IOCSRRD_B,
-  IOCSRRD_W,
-  IOCSRRD_H,
-  IOCSRRD_D,
-  IOCSRWR_B,
-  IOCSRWR_H,
-  IOCSRWR_W,
-  IOCSRWR_D,
-
-  // Read CPU configuration information operation
-  CPUCFG,
-
-  // Vector Shuffle
-  VREPLVE,
-  VSHUF,
-  VPICKEV,
-  VPICKOD,
-  VPACKEV,
-  VPACKOD,
-  VILVL,
-  VILVH,
-  VSHUF4I,
-  VREPLVEI,
-  VREPLGR2VR,
-  XVPERMI,
-  XVPERM,
-  XVREPLVE0,
-  XVREPLVE0Q,
-  XVINSVE0,
-
-  // Extended vector element extraction
-  VPICK_SEXT_ELT,
-  VPICK_ZEXT_ELT,
-
-  // Vector comparisons
-  VALL_ZERO,
-  VANY_ZERO,
-  VALL_NONZERO,
-  VANY_NONZERO,
-
-  // Floating point approximate reciprocal operation
-  FRECIPE,
-  FRSQRTE,
-
-  // Vector logicial left / right shift by immediate
-  VSLLI,
-  VSRLI,
-
-  // Vector byte logicial left / right shift
-  VBSLL,
-  VBSRL,
-
-  // Scalar load broadcast to vector
-  VLDREPL,
-
-  // Vector mask set by condition
-  VMSKLTZ,
-  VMSKGEZ,
-  VMSKEQZ,
-  VMSKNEZ,
-  XVMSKLTZ,
-  XVMSKGEZ,
-  XVMSKEQZ,
-  XVMSKNEZ,
-
-  // Vector Horizontal Addition with Widening‌
-  VHADDW
-
-  // Intrinsic operations end =============================================
-};
-} // end namespace LoongArchISD
 
 class LoongArchTargetLowering : public TargetLowering {
   const LoongArchSubtarget &Subtarget;
@@ -213,9 +40,6 @@ class LoongArchTargetLowering : public TargetLowering {
 
   SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
 
-  // This method returns the name of a target specific DAG node.
-  const char *getTargetNodeName(unsigned Opcode) const override;
-
   // Lower incoming arguments, copy physregs into vregs.
   SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
                                bool IsVarArg,

diff  --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index 9565a55e4c6c5..2e6653e1a09ac 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -100,14 +100,22 @@ def loongarch_tail_large : SDNode<"LoongArchISD::TAIL_LARGE", SDT_LoongArchCall,
 def loongarch_selectcc : SDNode<"LoongArchISD::SELECT_CC", SDT_LoongArchSelectCC>;
 def loongarch_brcc : SDNode<"LoongArchISD::BR_CC", SDT_LoongArchBrCC,
                             [SDNPHasChain]>;
+
+// 32-bit shifts, directly matching the semantics of the named LoongArch
+// instructions.
 def loongarch_sll_w : SDNode<"LoongArchISD::SLL_W", SDT_LoongArchIntBinOpW>;
 def loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>;
 def loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>;
+
 def loongarch_rotr_w : SDNode<"LoongArchISD::ROTR_W", SDT_LoongArchIntBinOpW>;
+
+// unsigned 32-bit integer division
 def loongarch_div_w : SDNode<"LoongArchISD::DIV_W", SDT_LoongArchIntBinOpW>;
 def loongarch_div_wu : SDNode<"LoongArchISD::DIV_WU", SDT_LoongArchIntBinOpW>;
 def loongarch_mod_w : SDNode<"LoongArchISD::MOD_W", SDT_LoongArchIntBinOpW>;
 def loongarch_mod_wu : SDNode<"LoongArchISD::MOD_WU", SDT_LoongArchIntBinOpW>;
+
+// CRC check operations
 def loongarch_crc_w_b_w
     : SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
 def loongarch_crc_w_h_w
@@ -124,37 +132,63 @@ def loongarch_crcc_w_w_w : SDNode<"LoongArchISD::CRCC_W_W_W",
                                   SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
 def loongarch_crcc_w_d_w : SDNode<"LoongArchISD::CRCC_W_D_W",
                                   SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
+
 def loongarch_bstrins
     : SDNode<"LoongArchISD::BSTRINS", SDT_LoongArchBStrIns>;
 def loongarch_bstrpick
     : SDNode<"LoongArchISD::BSTRPICK", SDT_LoongArchBStrPick>;
+
+// Byte-swapping and bit-reversal
 def loongarch_revb_2h : SDNode<"LoongArchISD::REVB_2H", SDTUnaryOp>;
 def loongarch_revb_2w : SDNode<"LoongArchISD::REVB_2W", SDTUnaryOp>;
 def loongarch_bitrev_4b : SDNode<"LoongArchISD::BITREV_4B", SDTUnaryOp>;
 def loongarch_bitrev_8b : SDNode<"LoongArchISD::BITREV_8B", SDTUnaryOp>;
 def loongarch_bitrev_w : SDNode<"LoongArchISD::BITREV_W", SDTUnaryOp>;
+
+// Bit counting operations
 def loongarch_clzw : SDNode<"LoongArchISD::CLZ_W", SDTIntBitCountUnaryOp>;
 def loongarch_ctzw : SDNode<"LoongArchISD::CTZ_W", SDTIntBitCountUnaryOp>;
+
 def loongarch_dbar : SDNode<"LoongArchISD::DBAR", SDT_LoongArchVI,
                              [SDNPHasChain, SDNPSideEffect]>;
 def loongarch_ibar : SDNode<"LoongArchISD::IBAR", SDT_LoongArchVI,
                              [SDNPHasChain, SDNPSideEffect]>;
 def loongarch_break : SDNode<"LoongArchISD::BREAK", SDT_LoongArchVI,
                               [SDNPHasChain, SDNPSideEffect]>;
+
+// FPR<->GPR transfer operations
 def loongarch_movfcsr2gr : SDNode<"LoongArchISD::MOVFCSR2GR",
                                   SDT_LoongArchMovfcsr2gr, [SDNPHasChain]>;
 def loongarch_movgr2fcsr : SDNode<"LoongArchISD::MOVGR2FCSR",
                                   SDT_LoongArchMovgr2fcsr,
                                   [SDNPHasChain, SDNPSideEffect]>;
+
 def loongarch_syscall : SDNode<"LoongArchISD::SYSCALL", SDT_LoongArchVI,
                                 [SDNPHasChain, SDNPSideEffect]>;
 def loongarch_csrrd : SDNode<"LoongArchISD::CSRRD", SDT_LoongArchCsrrd,
                               [SDNPHasChain, SDNPSideEffect]>;
+
+// Write new value to CSR and return old value.
+// Operand 0: A chain pointer.
+// Operand 1: The new value to write.
+// Operand 2: The address of the required CSR.
+// Result 0: The old value of the CSR.
+// Result 1: The new chain pointer.
 def loongarch_csrwr : SDNode<"LoongArchISD::CSRWR", SDT_LoongArchCsrwr,
                               [SDNPHasChain, SDNPSideEffect]>;
+
+// Similar to CSRWR but with a write mask.
+// Operand 0: A chain pointer.
+// Operand 1: The new value to write.
+// Operand 2: The write mask.
+// Operand 3: The address of the required CSR.
+// Result 0: The old value of the CSR.
+// Result 1: The new chain pointer.
 def loongarch_csrxchg : SDNode<"LoongArchISD::CSRXCHG",
                                 SDT_LoongArchCsrxchg,
                                 [SDNPHasChain, SDNPSideEffect]>;
+
+// IOCSR access operations
 def loongarch_iocsrrd_b : SDNode<"LoongArchISD::IOCSRRD_B", SDTUnaryOp,
                                   [SDNPHasChain, SDNPSideEffect]>;
 def loongarch_iocsrrd_h : SDNode<"LoongArchISD::IOCSRRD_H", SDTUnaryOp,
@@ -175,9 +209,12 @@ def loongarch_iocsrwr_w : SDNode<"LoongArchISD::IOCSRWR_W",
 def loongarch_iocsrwr_d : SDNode<"LoongArchISD::IOCSRWR_D",
                                   SDT_LoongArchIocsrwr,
                                   [SDNPHasChain, SDNPSideEffect]>;
+
+// Read CPU configuration information operation
 def loongarch_cpucfg : SDNode<"LoongArchISD::CPUCFG", SDTUnaryOp,
                                [SDNPHasChain]>;
 
+// Build and split F64 pair
 def loongarch_build_pair_f64 : SDNode<"LoongArchISD::BUILD_PAIR_F64",
                                       SDT_LoongArchBuildPairF64>;
 def loongarch_split_pair_f64 : SDNode<"LoongArchISD::SPLIT_PAIR_F64",

diff  --git a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
index 00d52870f1727..599cb4ac9aeef 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
@@ -16,11 +16,15 @@ def SDT_LoongArchXVREPLVE0 : SDTypeProfile<1, 1, [SDTCisVec<0>,
                                                   SDTCisSameAs<0, 1>]>;
 
 // Target nodes.
+
+// Vector Shuffle
 def loongarch_xvpermi: SDNode<"LoongArchISD::XVPERMI", SDT_LoongArchV1RUimm>;
 def loongarch_xvperm: SDNode<"LoongArchISD::XVPERM", SDT_LoongArchXVPERM>;
 def loongarch_xvreplve0: SDNode<"LoongArchISD::XVREPLVE0", SDT_LoongArchXVREPLVE0>;
 def loongarch_xvreplve0q: SDNode<"LoongArchISD::XVREPLVE0Q", SDT_LoongArchXVREPLVE0>;
 def loongarch_xvinsve0 : SDNode<"LoongArchISD::XVINSVE0", SDT_LoongArchV2RUimm>;
+
+// Vector mask set by condition
 def loongarch_xvmskltz: SDNode<"LoongArchISD::XVMSKLTZ", SDT_LoongArchVMSKCOND>;
 def loongarch_xvmskgez: SDNode<"LoongArchISD::XVMSKGEZ", SDT_LoongArchVMSKCOND>;
 def loongarch_xvmskeqz: SDNode<"LoongArchISD::XVMSKEQZ", SDT_LoongArchVMSKCOND>;

diff  --git a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
index 6b74a4b5e5f6f..58d5acfb40f41 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
@@ -34,7 +34,11 @@ def SDT_LoongArchVLDREPL : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisPtrTy<1>]>;
 def SDT_LoongArchVMSKCOND : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVec<1>]>;
 
 // Target nodes.
+
+// Vector Shuffle
 def loongarch_vreplve : SDNode<"LoongArchISD::VREPLVE", SDT_LoongArchVreplve>;
+
+// Vector comparisons
 def loongarch_vall_nonzero : SDNode<"LoongArchISD::VALL_NONZERO",
                                     SDT_LoongArchVecCond>;
 def loongarch_vany_nonzero : SDNode<"LoongArchISD::VANY_NONZERO",
@@ -44,11 +48,13 @@ def loongarch_vall_zero : SDNode<"LoongArchISD::VALL_ZERO",
 def loongarch_vany_zero : SDNode<"LoongArchISD::VANY_ZERO",
                                  SDT_LoongArchVecCond>;
 
+// Extended vector element extraction
 def loongarch_vpick_sext_elt : SDNode<"LoongArchISD::VPICK_SEXT_ELT",
                                       SDTypeProfile<1, 3, [SDTCisPtrTy<2>]>>;
 def loongarch_vpick_zext_elt : SDNode<"LoongArchISD::VPICK_ZEXT_ELT",
                                       SDTypeProfile<1, 3, [SDTCisPtrTy<2>]>>;
 
+// Vector Shuffle
 def loongarch_vshuf: SDNode<"LoongArchISD::VSHUF", SDT_LoongArchVShuf>;
 def loongarch_vpickev: SDNode<"LoongArchISD::VPICKEV", SDT_LoongArchV2R>;
 def loongarch_vpickod: SDNode<"LoongArchISD::VPICKOD", SDT_LoongArchV2R>;
@@ -58,25 +64,30 @@ def loongarch_vilvl: SDNode<"LoongArchISD::VILVL", SDT_LoongArchV2R>;
 def loongarch_vilvh: SDNode<"LoongArchISD::VILVH", SDT_LoongArchV2R>;
 
 def loongarch_vshuf4i: SDNode<"LoongArchISD::VSHUF4I", SDT_LoongArchV1RUimm>;
-def loongarch_vshuf4i_d : SDNode<"LoongArchISD::VSHUF4I", SDT_LoongArchV2RUimm>;
+def loongarch_vshuf4i_d : SDNode<"LoongArchISD::VSHUF4I_D", SDT_LoongArchV2RUimm>;
 def loongarch_vreplvei: SDNode<"LoongArchISD::VREPLVEI", SDT_LoongArchV1RUimm>;
 def loongarch_vreplgr2vr: SDNode<"LoongArchISD::VREPLGR2VR", SDT_LoongArchVreplgr2vr>;
 
 def loongarch_vfrecipe: SDNode<"LoongArchISD::FRECIPE", SDT_LoongArchVFRECIPE>;
 def loongarch_vfrsqrte: SDNode<"LoongArchISD::FRSQRTE", SDT_LoongArchVFRSQRTE>;
 
+// Vector logicial left / right shift by immediate
 def loongarch_vslli : SDNode<"LoongArchISD::VSLLI", SDT_LoongArchV1RUimm>;
 def loongarch_vsrli : SDNode<"LoongArchISD::VSRLI", SDT_LoongArchV1RUimm>;
 
+// Vector byte logicial left / right shift
 def loongarch_vbsll : SDNode<"LoongArchISD::VBSLL", SDT_LoongArchV1RUimm>;
 def loongarch_vbsrl : SDNode<"LoongArchISD::VBSRL", SDT_LoongArchV1RUimm>;
 
+// Vector Horizontal Addition with Widening
 def loongarch_vhaddw : SDNode<"LoongArchISD::VHADDW", SDT_LoongArchV2R>;
 
+// Scalar load broadcast to vector
 def loongarch_vldrepl
     : SDNode<"LoongArchISD::VLDREPL",
              SDT_LoongArchVLDREPL, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
 
+// Vector mask set by condition
 def loongarch_vmskltz: SDNode<"LoongArchISD::VMSKLTZ", SDT_LoongArchVMSKCOND>;
 def loongarch_vmskgez: SDNode<"LoongArchISD::VMSKGEZ", SDT_LoongArchVMSKCOND>;
 def loongarch_vmskeqz: SDNode<"LoongArchISD::VMSKEQZ", SDT_LoongArchVMSKCOND>;

diff  --git a/llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.cpp
new file mode 100644
index 0000000000000..11d05042c94f8
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchSelectionDAGInfo.h"
+
+#define GET_SDNODE_DESC
+#include "LoongArchGenSDNodeInfo.inc"
+
+using namespace llvm;
+
+LoongArchSelectionDAGInfo::LoongArchSelectionDAGInfo()
+    : SelectionDAGGenTargetInfo(LoongArchGenSDNodeInfo) {}
+
+LoongArchSelectionDAGInfo::~LoongArchSelectionDAGInfo() = default;
+
+void LoongArchSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
+                                                 const SDNode *N) const {
+  switch (N->getOpcode()) {
+  case LoongArchISD::VLDREPL:
+    // invalid number of operands; expected 2, got 3
+    return;
+  }
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
+}

diff  --git a/llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.h b/llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.h
new file mode 100644
index 0000000000000..ba5657080b3e4
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.h
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+
+#define GET_SDNODE_ENUM
+#include "LoongArchGenSDNodeInfo.inc"
+
+namespace llvm {
+
+class LoongArchSelectionDAGInfo : public SelectionDAGGenTargetInfo {
+public:
+  LoongArchSelectionDAGInfo();
+
+  ~LoongArchSelectionDAGInfo() override;
+
+  void verifyTargetNode(const SelectionDAG &DAG,
+                        const SDNode *N) const override;
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSELECTIONDAGINFO_H

diff  --git a/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp b/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp
index 76a8ba1c90e50..6293cbef23656 100644
--- a/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp
@@ -12,6 +12,7 @@
 
 #include "LoongArchSubtarget.h"
 #include "LoongArchFrameLowering.h"
+#include "LoongArchSelectionDAGInfo.h"
 #include "MCTargetDesc/LoongArchBaseInfo.h"
 
 using namespace llvm;
@@ -95,4 +96,12 @@ LoongArchSubtarget::LoongArchSubtarget(const Triple &TT, StringRef CPU,
     : LoongArchGenSubtargetInfo(TT, CPU, TuneCPU, FS),
       FrameLowering(
           initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
-      InstrInfo(*this), TLInfo(TM, *this) {}
+      InstrInfo(*this), TLInfo(TM, *this) {
+  TSInfo = std::make_unique<LoongArchSelectionDAGInfo>();
+}
+
+LoongArchSubtarget::~LoongArchSubtarget() = default;
+
+const SelectionDAGTargetInfo *LoongArchSubtarget::getSelectionDAGInfo() const {
+  return TSInfo.get();
+}

diff  --git a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
index 2beff07949daf..b90542cc04c32 100644
--- a/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
+++ b/llvm/lib/Target/LoongArch/LoongArchSubtarget.h
@@ -18,7 +18,6 @@
 #include "LoongArchInstrInfo.h"
 #include "LoongArchRegisterInfo.h"
 #include "MCTargetDesc/LoongArchBaseInfo.h"
-#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/Target/TargetMachine.h"
@@ -46,7 +45,7 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
   LoongArchFrameLowering FrameLowering;
   LoongArchInstrInfo InstrInfo;
   LoongArchTargetLowering TLInfo;
-  SelectionDAGTargetInfo TSInfo;
+  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
 
   Align PrefFunctionAlignment;
   Align PrefLoopAlignment;
@@ -68,6 +67,8 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
   LoongArchSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
                      StringRef FS, StringRef ABIName, const TargetMachine &TM);
 
+  ~LoongArchSubtarget() override;
+
   // Parses features string setting specified subtarget options. The
   // definition of this function is auto-generated by tblgen.
   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
@@ -82,9 +83,8 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
   const LoongArchTargetLowering *getTargetLowering() const override {
     return &TLInfo;
   }
-  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
-    return &TSInfo;
-  }
+
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
 
 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER)                    \
   bool GETTER() const { return ATTRIBUTE; }


        


More information about the llvm-commits mailing list