[llvm] [ARM] Add combine for vector_deinterleave load (PR #225747)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 2 06:26:35 PDT 2026
================
@@ -15446,6 +15446,169 @@ static SDValue PerformBUILD_VECTORCombine(SDNode *N,
return DAG.getNode(ISD::BITCAST, dl, VT, BV);
}
+static SDValue performLegalizedVECTOR_DEINTERLEAVECombine(
+ SDNode *N, TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG,
+ const ARMSubtarget *Subtarget) {
+ // Type legalization splits a wide load into consecutive legal loads. Combine
+ // each group used by a legal VECTOR_DEINTERLEAVE into a structured load.
+ if (DCI.getDAGCombineLevel() < AfterLegalizeTypes)
+ return SDValue();
+
+ unsigned NumParts = N->getNumOperands();
+ if (NumParts < 2 || NumParts > 4)
+ return SDValue();
+
+ if (NumParts == 3 && !Subtarget->hasNEON())
+ return SDValue();
+
+ EVT SubVecTy = N->getValueType(0);
+ if (!SubVecTy.is64BitVector() && !SubVecTy.is128BitVector())
+ return SDValue();
+ unsigned EltBits = SubVecTy.getScalarSizeInBits();
+ if (EltBits != 8 && EltBits != 16 && EltBits != 32)
+ return SDValue();
+
+ SmallVector<LoadSDNode *, 4> Loads;
+ for (const SDValue &Operand : N->op_values()) {
+ auto *Load = dyn_cast<LoadSDNode>(Operand);
+ if (!Load || !Operand.hasOneUse())
+ return SDValue();
+ Loads.push_back(Load);
+ }
+
+ LoadSDNode *BaseLoad = Loads[0];
+ unsigned Bytes = SubVecTy.getStoreSize().getFixedValue();
+ for (auto [Idx, Load] : enumerate(Loads)) {
+ if (!DAG.areNonVolatileConsecutiveLoads(Load, BaseLoad, Bytes, Idx))
+ return SDValue();
+ }
+
+ static constexpr Intrinsic::ID NEONLoads[] = {Intrinsic::arm_neon_vld2,
----------------
davemgreen wrote:
Move these next to where they are used?
https://github.com/llvm/llvm-project/pull/225747
More information about the llvm-commits
mailing list