Skip to content

Conversation

@s-barannikov
Copy link
Contributor

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

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.

@llvmbot
Copy link
Member

llvmbot commented Nov 14, 2025

@llvm/pr-subscribers-backend-loongarch

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.

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 prevents the node from being imported.

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

Part of #119709.


Patch is 27.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/168129.diff

13 Files Affected:

  • (modified) llvm/lib/Target/LoongArch/CMakeLists.txt (+2)
  • (modified) llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td (+5)
  • (modified) llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td (+1)
  • (modified) llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h (+1)
  • (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+4-120)
  • (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.h (-176)
  • (modified) llvm/lib/Target/LoongArch/LoongArchInstrInfo.td (+37)
  • (modified) llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td (+4)
  • (modified) llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td (+12-1)
  • (added) llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.cpp (+29)
  • (added) llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.h (+31)
  • (modified) llvm/lib/Target/LoongArch/LoongArchSubtarget.cpp (+10-1)
  • (modified) llvm/lib/Target/LoongArch/LoongArchSubtarget.h (+5-5)
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 cf4ffc82f6009..ccffb7913d127 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", ... [truncated] 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

2 participants