Skip to content

Conversation

@s-barannikov
Copy link
Contributor

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

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

Some nodes fail validation, those are enumerated in ARMSelectionDAGInfo::verifyTargetNode(). Some of the bugs are easy to fix, but probably they should be fixed separately, this patch is already non-trivial.

Part of #119709.

@github-actions
Copy link

github-actions bot commented Nov 15, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

let Predicates = [IsThumb2, HasV8_1MMainline, HasLOB];
}

// Setup for the iteration count of a WLS. See t2WhileLoopSetup.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is done in #168209.

Comment on lines +338 to +345
// 64bit Unsigned Accumulate Multiply
def ARMumlal : SDNode<"ARMISD::UMLAL", SDT_LongMac>;

// 64bit Signed Accumulate Multiply
def ARMsmlal : SDNode<"ARMISD::SMLAL", SDT_LongMac>;

// 64-bit Unsigned Accumulate Accumulate Multiply
def ARMumaal : SDNode<"ARMISD::UMAAL", SDT_LongMac>;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to use these nodes in patterns (and remove custom selection in ARMISelDAGToDAG.cpp), but unfortunately it didn't work -- predicates used custom selection and predicates on the corresponding instructions are different. I don't know if this is a bug or not.

@s-barannikov
Copy link
Contributor Author

I moved the node comments to *.td almost unchanged. Let me know if I need to do anything smarter, like reflow the comments or reformat SDNode definitions (remove extra spaces used to be used for aligning nodes in a group).

@s-barannikov s-barannikov marked this pull request as ready for review November 15, 2025 17:54
@llvmbot
Copy link
Member

llvmbot commented Nov 15, 2025

@llvm/pr-subscribers-backend-arm

Author: Sergei Barannikov (s-barannikov)

Changes

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

13 Files Affected:

  • (modified) llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp (-36)
  • (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+3-217)
  • (modified) llvm/lib/Target/ARM/ARMISelLowering.h (-315)
  • (modified) llvm/lib/Target/ARM/ARMInstrInfo.td (+138-4)
  • (modified) llvm/lib/Target/ARM/ARMInstrMVE.td (+100-9)
  • (modified) llvm/lib/Target/ARM/ARMInstrNEON.td (+17)
  • (modified) llvm/lib/Target/ARM/ARMInstrThumb.td (+1)
  • (modified) llvm/lib/Target/ARM/ARMInstrThumb2.td (+29-7)
  • (modified) llvm/lib/Target/ARM/ARMInstrVFP.td (+16)
  • (modified) llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp (+43-3)
  • (modified) llvm/lib/Target/ARM/ARMSelectionDAGInfo.h (+29-4)
  • (modified) llvm/lib/Target/ARM/CMakeLists.txt (+1)
  • (modified) llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp (+1-1)
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 847b7af5a9b11..26b5e5a22386e 100644
--- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -3965,31 +3965,6 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
       return;
     // Other cases are autogenerated.
     break;
-  case ARMISD::WLSSETUP: {
-    SDNode *New = CurDAG->getMachineNode(ARM::t2WhileLoopSetup, dl, MVT::i32,
-                                         N->getOperand(0));
-    ReplaceUses(N, New);
-    CurDAG->RemoveDeadNode(N);
-    return;
-  }
-  case ARMISD::WLS: {
-    SDNode *New = CurDAG->getMachineNode(ARM::t2WhileLoopStart, dl, MVT::Other,
-                                         N->getOperand(1), N->getOperand(2),
-                                         N->getOperand(0));
-    ReplaceUses(N, New);
-    CurDAG->RemoveDeadNode(N);
-    return;
-  }
-  case ARMISD::LE: {
-    SDValue Ops[] = { N->getOperand(1),
-                      N->getOperand(2),
-                      N->getOperand(0) };
-    unsigned Opc = ARM::t2LoopEnd;
-    SDNode *New = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
-    ReplaceUses(N, New);
-    CurDAG->RemoveDeadNode(N);
-    return;
-  }
   case ARMISD::LDRD: {
     if (Subtarget->isThumb2())
       break; // TableGen handles isel in this case.
@@ -4043,17 +4018,6 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
     CurDAG->RemoveDeadNode(N);
     return;
   }
-  case ARMISD::LOOP_DEC: {
-    SDValue Ops[] = { N->getOperand(1),
-                      N->getOperand(2),
-                      N->getOperand(0) };
-    SDNode *Dec =
-      CurDAG->getMachineNode(ARM::t2LoopDec, dl,
-                             CurDAG->getVTList(MVT::i32, MVT::Other), Ops);
-    ReplaceUses(N, Dec);
-    CurDAG->RemoveDeadNode(N);
-    return;
-  }
   case ARMISD::BRCOND: {
     // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
     // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc)
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index f28640ce7b107..cd8d7a0bee5e3 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -1556,220 +1556,6 @@ ARMTargetLowering::findRepresentativeClass(const TargetRegisterInfo *TRI,
   return std::make_pair(RRC, Cost);
 }
 
-const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
-#define MAKE_CASE(V)                                                           \
-  case V:                                                                      \
-    return #V;
-  switch ((ARMISD::NodeType)Opcode) {
-  case ARMISD::FIRST_NUMBER:
-    break;
-    MAKE_CASE(ARMISD::Wrapper)
-    MAKE_CASE(ARMISD::WrapperPIC)
-    MAKE_CASE(ARMISD::WrapperJT)
-    MAKE_CASE(ARMISD::COPY_STRUCT_BYVAL)
-    MAKE_CASE(ARMISD::CALL)
-    MAKE_CASE(ARMISD::CALL_PRED)
-    MAKE_CASE(ARMISD::CALL_NOLINK)
-    MAKE_CASE(ARMISD::tSECALL)
-    MAKE_CASE(ARMISD::t2CALL_BTI)
-    MAKE_CASE(ARMISD::BRCOND)
-    MAKE_CASE(ARMISD::BR_JT)
-    MAKE_CASE(ARMISD::BR2_JT)
-    MAKE_CASE(ARMISD::RET_GLUE)
-    MAKE_CASE(ARMISD::SERET_GLUE)
-    MAKE_CASE(ARMISD::INTRET_GLUE)
-    MAKE_CASE(ARMISD::PIC_ADD)
-    MAKE_CASE(ARMISD::CMP)
-    MAKE_CASE(ARMISD::CMN)
-    MAKE_CASE(ARMISD::CMPZ)
-    MAKE_CASE(ARMISD::CMPFP)
-    MAKE_CASE(ARMISD::CMPFPE)
-    MAKE_CASE(ARMISD::CMPFPw0)
-    MAKE_CASE(ARMISD::CMPFPEw0)
-    MAKE_CASE(ARMISD::BCC_i64)
-    MAKE_CASE(ARMISD::FMSTAT)
-    MAKE_CASE(ARMISD::CMOV)
-    MAKE_CASE(ARMISD::SSAT)
-    MAKE_CASE(ARMISD::USAT)
-    MAKE_CASE(ARMISD::ASRL)
-    MAKE_CASE(ARMISD::LSRL)
-    MAKE_CASE(ARMISD::LSLL)
-    MAKE_CASE(ARMISD::LSLS)
-    MAKE_CASE(ARMISD::LSRS1)
-    MAKE_CASE(ARMISD::ASRS1)
-    MAKE_CASE(ARMISD::RRX)
-    MAKE_CASE(ARMISD::ADDC)
-    MAKE_CASE(ARMISD::ADDE)
-    MAKE_CASE(ARMISD::SUBC)
-    MAKE_CASE(ARMISD::SUBE)
-    MAKE_CASE(ARMISD::VMOVRRD)
-    MAKE_CASE(ARMISD::VMOVDRR)
-    MAKE_CASE(ARMISD::VMOVhr)
-    MAKE_CASE(ARMISD::VMOVrh)
-    MAKE_CASE(ARMISD::VMOVSR)
-    MAKE_CASE(ARMISD::EH_SJLJ_SETJMP)
-    MAKE_CASE(ARMISD::EH_SJLJ_LONGJMP)
-    MAKE_CASE(ARMISD::EH_SJLJ_SETUP_DISPATCH)
-    MAKE_CASE(ARMISD::TC_RETURN)
-    MAKE_CASE(ARMISD::THREAD_POINTER)
-    MAKE_CASE(ARMISD::DYN_ALLOC)
-    MAKE_CASE(ARMISD::MEMBARRIER_MCR)
-    MAKE_CASE(ARMISD::PRELOAD)
-    MAKE_CASE(ARMISD::LDRD)
-    MAKE_CASE(ARMISD::STRD)
-    MAKE_CASE(ARMISD::WIN__CHKSTK)
-    MAKE_CASE(ARMISD::WIN__DBZCHK)
-    MAKE_CASE(ARMISD::PREDICATE_CAST)
-    MAKE_CASE(ARMISD::VECTOR_REG_CAST)
-    MAKE_CASE(ARMISD::MVESEXT)
-    MAKE_CASE(ARMISD::MVEZEXT)
-    MAKE_CASE(ARMISD::MVETRUNC)
-    MAKE_CASE(ARMISD::VCMP)
-    MAKE_CASE(ARMISD::VCMPZ)
-    MAKE_CASE(ARMISD::VTST)
-    MAKE_CASE(ARMISD::VSHLs)
-    MAKE_CASE(ARMISD::VSHLu)
-    MAKE_CASE(ARMISD::VSHLIMM)
-    MAKE_CASE(ARMISD::VSHRsIMM)
-    MAKE_CASE(ARMISD::VSHRuIMM)
-    MAKE_CASE(ARMISD::VRSHRsIMM)
-    MAKE_CASE(ARMISD::VRSHRuIMM)
-    MAKE_CASE(ARMISD::VRSHRNIMM)
-    MAKE_CASE(ARMISD::VQSHLsIMM)
-    MAKE_CASE(ARMISD::VQSHLuIMM)
-    MAKE_CASE(ARMISD::VQSHLsuIMM)
-    MAKE_CASE(ARMISD::VQSHRNsIMM)
-    MAKE_CASE(ARMISD::VQSHRNuIMM)
-    MAKE_CASE(ARMISD::VQSHRNsuIMM)
-    MAKE_CASE(ARMISD::VQRSHRNsIMM)
-    MAKE_CASE(ARMISD::VQRSHRNuIMM)
-    MAKE_CASE(ARMISD::VQRSHRNsuIMM)
-    MAKE_CASE(ARMISD::VSLIIMM)
-    MAKE_CASE(ARMISD::VSRIIMM)
-    MAKE_CASE(ARMISD::VGETLANEu)
-    MAKE_CASE(ARMISD::VGETLANEs)
-    MAKE_CASE(ARMISD::VMOVIMM)
-    MAKE_CASE(ARMISD::VMVNIMM)
-    MAKE_CASE(ARMISD::VMOVFPIMM)
-    MAKE_CASE(ARMISD::VDUP)
-    MAKE_CASE(ARMISD::VDUPLANE)
-    MAKE_CASE(ARMISD::VEXT)
-    MAKE_CASE(ARMISD::VREV64)
-    MAKE_CASE(ARMISD::VREV32)
-    MAKE_CASE(ARMISD::VREV16)
-    MAKE_CASE(ARMISD::VZIP)
-    MAKE_CASE(ARMISD::VUZP)
-    MAKE_CASE(ARMISD::VTRN)
-    MAKE_CASE(ARMISD::VTBL1)
-    MAKE_CASE(ARMISD::VTBL2)
-    MAKE_CASE(ARMISD::VMOVN)
-    MAKE_CASE(ARMISD::VQMOVNs)
-    MAKE_CASE(ARMISD::VQMOVNu)
-    MAKE_CASE(ARMISD::VCVTN)
-    MAKE_CASE(ARMISD::VCVTL)
-    MAKE_CASE(ARMISD::VIDUP)
-    MAKE_CASE(ARMISD::VMULLs)
-    MAKE_CASE(ARMISD::VMULLu)
-    MAKE_CASE(ARMISD::VQDMULH)
-    MAKE_CASE(ARMISD::VADDVs)
-    MAKE_CASE(ARMISD::VADDVu)
-    MAKE_CASE(ARMISD::VADDVps)
-    MAKE_CASE(ARMISD::VADDVpu)
-    MAKE_CASE(ARMISD::VADDLVs)
-    MAKE_CASE(ARMISD::VADDLVu)
-    MAKE_CASE(ARMISD::VADDLVAs)
-    MAKE_CASE(ARMISD::VADDLVAu)
-    MAKE_CASE(ARMISD::VADDLVps)
-    MAKE_CASE(ARMISD::VADDLVpu)
-    MAKE_CASE(ARMISD::VADDLVAps)
-    MAKE_CASE(ARMISD::VADDLVApu)
-    MAKE_CASE(ARMISD::VMLAVs)
-    MAKE_CASE(ARMISD::VMLAVu)
-    MAKE_CASE(ARMISD::VMLAVps)
-    MAKE_CASE(ARMISD::VMLAVpu)
-    MAKE_CASE(ARMISD::VMLALVs)
-    MAKE_CASE(ARMISD::VMLALVu)
-    MAKE_CASE(ARMISD::VMLALVps)
-    MAKE_CASE(ARMISD::VMLALVpu)
-    MAKE_CASE(ARMISD::VMLALVAs)
-    MAKE_CASE(ARMISD::VMLALVAu)
-    MAKE_CASE(ARMISD::VMLALVAps)
-    MAKE_CASE(ARMISD::VMLALVApu)
-    MAKE_CASE(ARMISD::VMINVu)
-    MAKE_CASE(ARMISD::VMINVs)
-    MAKE_CASE(ARMISD::VMAXVu)
-    MAKE_CASE(ARMISD::VMAXVs)
-    MAKE_CASE(ARMISD::UMAAL)
-    MAKE_CASE(ARMISD::UMLAL)
-    MAKE_CASE(ARMISD::SMLAL)
-    MAKE_CASE(ARMISD::SMLALBB)
-    MAKE_CASE(ARMISD::SMLALBT)
-    MAKE_CASE(ARMISD::SMLALTB)
-    MAKE_CASE(ARMISD::SMLALTT)
-    MAKE_CASE(ARMISD::SMULWB)
-    MAKE_CASE(ARMISD::SMULWT)
-    MAKE_CASE(ARMISD::SMLALD)
-    MAKE_CASE(ARMISD::SMLALDX)
-    MAKE_CASE(ARMISD::SMLSLD)
-    MAKE_CASE(ARMISD::SMLSLDX)
-    MAKE_CASE(ARMISD::SMMLAR)
-    MAKE_CASE(ARMISD::SMMLSR)
-    MAKE_CASE(ARMISD::QADD16b)
-    MAKE_CASE(ARMISD::QSUB16b)
-    MAKE_CASE(ARMISD::QADD8b)
-    MAKE_CASE(ARMISD::QSUB8b)
-    MAKE_CASE(ARMISD::UQADD16b)
-    MAKE_CASE(ARMISD::UQSUB16b)
-    MAKE_CASE(ARMISD::UQADD8b)
-    MAKE_CASE(ARMISD::UQSUB8b)
-    MAKE_CASE(ARMISD::BUILD_VECTOR)
-    MAKE_CASE(ARMISD::BFI)
-    MAKE_CASE(ARMISD::VORRIMM)
-    MAKE_CASE(ARMISD::VBICIMM)
-    MAKE_CASE(ARMISD::VBSP)
-    MAKE_CASE(ARMISD::MEMCPY)
-    MAKE_CASE(ARMISD::VLD1DUP)
-    MAKE_CASE(ARMISD::VLD2DUP)
-    MAKE_CASE(ARMISD::VLD3DUP)
-    MAKE_CASE(ARMISD::VLD4DUP)
-    MAKE_CASE(ARMISD::VLD1_UPD)
-    MAKE_CASE(ARMISD::VLD2_UPD)
-    MAKE_CASE(ARMISD::VLD3_UPD)
-    MAKE_CASE(ARMISD::VLD4_UPD)
-    MAKE_CASE(ARMISD::VLD1x2_UPD)
-    MAKE_CASE(ARMISD::VLD1x3_UPD)
-    MAKE_CASE(ARMISD::VLD1x4_UPD)
-    MAKE_CASE(ARMISD::VLD2LN_UPD)
-    MAKE_CASE(ARMISD::VLD3LN_UPD)
-    MAKE_CASE(ARMISD::VLD4LN_UPD)
-    MAKE_CASE(ARMISD::VLD1DUP_UPD)
-    MAKE_CASE(ARMISD::VLD2DUP_UPD)
-    MAKE_CASE(ARMISD::VLD3DUP_UPD)
-    MAKE_CASE(ARMISD::VLD4DUP_UPD)
-    MAKE_CASE(ARMISD::VST1_UPD)
-    MAKE_CASE(ARMISD::VST2_UPD)
-    MAKE_CASE(ARMISD::VST3_UPD)
-    MAKE_CASE(ARMISD::VST4_UPD)
-    MAKE_CASE(ARMISD::VST1x2_UPD)
-    MAKE_CASE(ARMISD::VST1x3_UPD)
-    MAKE_CASE(ARMISD::VST1x4_UPD)
-    MAKE_CASE(ARMISD::VST2LN_UPD)
-    MAKE_CASE(ARMISD::VST3LN_UPD)
-    MAKE_CASE(ARMISD::VST4LN_UPD)
-    MAKE_CASE(ARMISD::WLS)
-    MAKE_CASE(ARMISD::WLSSETUP)
-    MAKE_CASE(ARMISD::LE)
-    MAKE_CASE(ARMISD::LOOP_DEC)
-    MAKE_CASE(ARMISD::CSINV)
-    MAKE_CASE(ARMISD::CSNEG)
-    MAKE_CASE(ARMISD::CSINC)
-    MAKE_CASE(ARMISD::MEMCPYLOOP)
-    MAKE_CASE(ARMISD::MEMSETLOOP)
-#undef MAKE_CASE
-  }
-  return nullptr;
-}
-
 EVT ARMTargetLowering::getSetCCResultType(const DataLayout &DL, LLVMContext &,
                                           EVT VT) const {
   if (!VT.isVector())
@@ -3344,8 +3130,8 @@ ARMTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
     return LowerInterruptReturn(RetOps, dl, DAG);
   }
 
-  ARMISD::NodeType RetNode = AFI->isCmseNSEntryFunction() ? ARMISD::SERET_GLUE :
-                                                            ARMISD::RET_GLUE;
+  unsigned RetNode =
+      AFI->isCmseNSEntryFunction() ? ARMISD::SERET_GLUE : ARMISD::RET_GLUE;
   return DAG.getNode(RetNode, dl, MVT::Other, RetOps);
 }
 
@@ -4861,7 +4647,7 @@ SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
     }
   }
 
-  ARMISD::NodeType CompareType;
+  unsigned CompareType;
   switch (CondCode) {
   default:
     CompareType = ARMISD::CMP;
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index bc2fec3c1bdb5..8191eb40a712a 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -51,319 +51,6 @@ class TargetMachine;
 class TargetRegisterInfo;
 class VectorType;
 
-  namespace ARMISD {
-
-  // ARM Specific DAG Nodes
-  enum NodeType : unsigned {
-    // Start the numbering where the builtin ops and target ops leave off.
-    FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-    Wrapper,    // Wrapper - A wrapper node for TargetConstantPool,
-                // TargetExternalSymbol, and TargetGlobalAddress.
-    WrapperPIC, // WrapperPIC - A wrapper node for TargetGlobalAddress in
-                // PIC mode.
-    WrapperJT,  // WrapperJT - A wrapper node for TargetJumpTable
-
-    // Add pseudo op to model memcpy for struct byval.
-    COPY_STRUCT_BYVAL,
-
-    CALL,        // Function call.
-    CALL_PRED,   // Function call that's predicable.
-    CALL_NOLINK, // Function call with branch not branch-and-link.
-    tSECALL,     // CMSE non-secure function call.
-    t2CALL_BTI,  // Thumb function call followed by BTI instruction.
-    BRCOND,      // Conditional branch.
-    BR_JT,       // Jumptable branch.
-    BR2_JT,      // Jumptable branch (2 level - jumptable entry is a jump).
-    RET_GLUE,    // Return with a flag operand.
-    SERET_GLUE,  // CMSE Entry function return with a flag operand.
-    INTRET_GLUE, // Interrupt return with an LR-offset and a flag operand.
-
-    PIC_ADD, // Add with a PC operand and a PIC label.
-
-    ASRL, // MVE long arithmetic shift right.
-    LSRL, // MVE long shift right.
-    LSLL, // MVE long shift left.
-
-    CMP,      // ARM compare instructions.
-    CMN,      // ARM CMN instructions.
-    CMPZ,     // ARM compare that sets only Z flag.
-    CMPFP,    // ARM VFP compare instruction, sets FPSCR.
-    CMPFPE,   // ARM VFP signalling compare instruction, sets FPSCR.
-    CMPFPw0,  // ARM VFP compare against zero instruction, sets FPSCR.
-    CMPFPEw0, // ARM VFP signalling compare against zero instruction, sets
-              // FPSCR.
-    FMSTAT,   // ARM fmstat instruction.
-
-    CMOV, // ARM conditional move instructions.
-
-    SSAT, // Signed saturation
-    USAT, // Unsigned saturation
-
-    BCC_i64,
-
-    LSLS,  // Flag-setting shift left.
-    LSRS1, // Flag-setting logical shift right by one bit.
-    ASRS1, // Flag-setting arithmetic shift right by one bit.
-    RRX,   // Shift right one bit with carry in.
-
-    ADDC, // Add with carry
-    ADDE, // Add using carry
-    SUBC, // Sub with carry
-    SUBE, // Sub using carry
-
-    VMOVRRD, // double to two gprs.
-    VMOVDRR, // Two gprs to double.
-    VMOVSR,  // move gpr to single, used for f32 literal constructed in a gpr
-
-    EH_SJLJ_SETJMP,         // SjLj exception handling setjmp.
-    EH_SJLJ_LONGJMP,        // SjLj exception handling longjmp.
-    EH_SJLJ_SETUP_DISPATCH, // SjLj exception handling setup_dispatch.
-
-    TC_RETURN, // Tail call return pseudo.
-
-    THREAD_POINTER,
-
-    DYN_ALLOC, // Dynamic allocation on the stack.
-
-    MEMBARRIER_MCR, // Memory barrier (MCR)
-
-    PRELOAD, // Preload
-
-    WIN__CHKSTK, // Windows' __chkstk call to do stack probing.
-    WIN__DBZCHK, // Windows' divide by zero check
-
-    WLS, // Low-overhead loops, While Loop Start branch. See t2WhileLoopStart
-    WLSSETUP, // Setup for the iteration count of a WLS. See t2WhileLoopSetup.
-    LOOP_DEC, // Really a part of LE, performs the sub
-    LE,       // Low-overhead loops, Loop End
-
-    PREDICATE_CAST,  // Predicate cast for MVE i1 types
-    VECTOR_REG_CAST, // Reinterpret the current contents of a vector register
-
-    MVESEXT,  // Legalization aids for extending a vector into two/four vectors.
-    MVEZEXT,  //  or truncating two/four vectors into one. Eventually becomes
-    MVETRUNC, //  stack store/load sequence, if not optimized to anything else.
-
-    VCMP,  // Vector compare.
-    VCMPZ, // Vector compare to zero.
-    VTST,  // Vector test bits.
-
-    // Vector shift by vector
-    VSHLs, // ...left/right by signed
-    VSHLu, // ...left/right by unsigned
-
-    // Vector shift by immediate:
-    VSHLIMM,  // ...left
-    VSHRsIMM, // ...right (signed)
-    VSHRuIMM, // ...right (unsigned)
-
-    // Vector rounding shift by immediate:
-    VRSHRsIMM, // ...right (signed)
-    VRSHRuIMM, // ...right (unsigned)
-    VRSHRNIMM, // ...right narrow
-
-    // Vector saturating shift by immediate:
-    VQSHLsIMM,   // ...left (signed)
-    VQSHLuIMM,   // ...left (unsigned)
-    VQSHLsuIMM,  // ...left (signed to unsigned)
-    VQSHRNsIMM,  // ...right narrow (signed)
-    VQSHRNuIMM,  // ...right narrow (unsigned)
-    VQSHRNsuIMM, // ...right narrow (signed to unsigned)
-
-    // Vector saturating rounding shift by immediate:
-    VQRSHRNsIMM,  // ...right narrow (signed)
-    VQRSHRNuIMM,  // ...right narrow (unsigned)
-    VQRSHRNsuIMM, // ...right narrow (signed to unsigned)
-
-    // Vector shift and insert:
-    VSLIIMM, // ...left
-    VSRIIMM, // ...right
-
-    // Vector get lane (VMOV scalar to ARM core register)
-    // (These are used for 8- and 16-bit element types only.)
-    VGETLANEu, // zero-extend vector extract element
-    VGETLANEs, // sign-extend vector extract element
-
-    // Vector move immediate and move negated immediate:
-    VMOVIMM,
-    VMVNIMM,
-
-    // Vector move f32 immediate:
-    VMOVFPIMM,
-
-    // Move H <-> R, clearing top 16 bits
-    VMOVrh,
-    VMOVhr,
-
-    // Vector duplicate:
-    VDUP,
-    VDUPLANE,
-
-    // Vector shuffles:
-    VEXT,   // extract
-    VREV64, // reverse elements within 64-bit doublewords
-    VREV32, // reverse elements within 32-bit words
-    VREV16, // reverse elements within 16-bit halfwords
-    VZIP,   // zip (interleave)
-    VUZP,   // unzip (deinterleave)
-    VTRN,   // transpose
-    VTBL1,  // 1-register shuffle with mask
-    VTBL2,  // 2-register shuffle with mask
-    VMOVN,  // MVE vmovn
-
-    // MVE Saturating truncates
-    VQMOVNs, // Vector (V) Saturating (Q) Move and Narrow (N), signed (s)
-    VQMOVNu, // Vector (V) Saturating (Q) Move and Narrow (N), unsigned (u)
-
-    // MVE float <> half converts
-    VCVTN, // MVE vcvt f32 -> f16, truncating into either the bottom or top
-           // lanes
-    VCVTL, // MVE vcvt f16 -> f32, extending from either the bottom or top lanes
-
-    // MVE VIDUP instruction, taking a start value and increment.
-    VIDUP,
-
-    // Vector multiply long:
-    VMULLs, // ...signed
-    VMULLu, // ...unsigned
-
-    VQDMULH, // MVE vqdmulh instruction
-
-    // MVE reductions
-    VADDVs,  // sign- or zero-extend the elements of a vector to i32,
-    VADDVu,  //   add them all together, and return an i32 of their sum
-    VADDVps, // Same as VADDV[su] but with a v4i1 predicate mask
-    VADDVpu,
-    VADDLVs,  // sign- or zero-extend elements to i64 and sum, returning
-    VADDLVu,  //   the low and high 32-bit halves of the sum
-    VADDLVAs, // Same as VADDLV[su] but also add an input accumulator
-    VADDLVAu, //   provided as low and high halves
-    VADDLVps, // Same as VADDLV[su] but with a v4i1 predicate mask
-    VADDLVpu,
-    VADDLVAps, // Same as VADDLVp[su] but with a v4i1 predicate mask
-    VADDLVApu,
-    VMLAVs, // sign- or zero-extend the elements of two vectors to i32, multiply
-    VMLAVu, //   them and add the results together, returning an i32 of the sum
-    VMLAVps, // Same as VMLAV[su] with a v4i1 predicate mask
-    VMLAVpu,
-    VMLALVs,  // Same as VMLAV but with i64, returning the low and
-    VMLALVu,  //   high 32-bit halves of the sum
-    VMLALVps, // Same as VMLALV[su] with a v4i1 predicate mask
-    VMLALVpu,
-    VMLALVAs,  // Same as VMLALV but also add an input accumulator
-    VMLALVAu,  //   provided as low and high halves
-    VMLALVAps, // Same as VMLALVA[su] with a v4i1 predicate mask
-    VMLALVApu,
-    VMINVu, // Find minimum unsigned value of a vector and register
-    VMINVs, // Find minimum signed value of a vector and register
-    VMAXVu, // Find maximum unsigned value of a vector and register
-    VMAXVs, // Find maximum signed value of a vector and register
-
-    SMULWB,  // Signed multiply word by half word, bottom
-    SMULWT,  // Signed multiply word by half word, top
-    UMLAL,   // 64bit Unsigned Accumulate Multiply
-    SMLAL,   // 64bit Signed Accumulate Multiply
-    UMAAL,   // 64-bit Unsigned Accumulate Accumulate Multiply
-    SMLALBB, // 64-bit signed accumulate multiply bottom, bottom 16
-    SMLALBT, // 64-bit signed accumulate multiply bottom, top 16
-    SMLALTB, // 64-bit signed accumulate multiply top, bottom 16
-    SMLALTT, // 64-bit signed accumulate multiply top, top 16
-    SMLALD,  // Signed multiply accumulate long dual
-    SMLALDX, // Signed multiply accumulate long dual exchange
-    SMLSLD,  // Signed multiply subtract long dual
-    SMLSLDX, // Signed multiply subtract long dual exchange
-    SMMLAR,  // Signed multiply long, round and add
-    SMMLSR,  // Signed multiply long, subtract and round
-
-    // Single Lane QADD8 and QADD16. Only the bottom lane. That's what the b
-    // stands for.
-    QADD8b,
-    QSUB8b,
-    QADD16b,
-    QSUB16b,
-    UQADD8b,
-    UQSUB8b,
-    UQADD16b,
-    UQSUB16b,
-
-    // Operands of the standard BUILD_VECTOR node are not legalized, which
-    // is fine if BUILD_VECTORs are always lowered to shuffles or other
-    // operations, but for ARM some BUILD_VECTORs are legal as-is and their
-    // operands need to be legalized.  Define an ARM-specific version of
-    // BUILD_VECTOR for this purpose.
-    BUILD_VECTOR,
-
-    // Bit-field insert
-    BFI,
-
-    // Vector OR with immediate
-    VORRIMM,
-    // Vector AND with NOT of immediate
-    VBICIMM,
-
-    // Pseudo vector bitwise select
-    VBSP,
-
-    // Pseudo-instruction representing a memory copy using ldm/stm
-    // instructions.
-    MEMCPY,
-
-    // Pseudo-instruction representing a memory copy using a tail predicated
-    // loop
-    MEMCPYLOOP,
-    // Pseudo-instruction representing a memset using a tail predicated
-    // loop
-    MEMSETLOOP,
-
-    // V8.1MMainline condition select
-    CSINV, // Conditional select invert.
- ...
[truncated]

Comment on lines +29 to +31
MVESEXT, // Legalization aids for extending a vector into two/four vectors.
MVEZEXT, // or truncating two/four vectors into one. Eventually becomes
MVETRUNC, // stack store/load sequence, if not optimized to anything else.
Copy link
Contributor Author

@s-barannikov s-barannikov Nov 15, 2025

Choose a reason for hiding this comment

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

Couldn't add descriptions for these three because they have varying number of operands/results.
It might make sense splitting them into two opcodes, for two/four vectors.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants