[ARM] Split 128-bit vectors in BUILD_VECTOR lowering
Given that INSERT_VECTOR_ELT operates on D registers anyway, combining
64-bit vectors into a 128-bit vector is basically free. Therefore, try
to split BUILD_VECTOR nodes before giving up and lowering them to a series
of INSERT_VECTOR_ELT instructions. Sometimes this allows dramatically
better lowerings; see testcases for examples. Inspired by similar code
in the x86 backend for AVX.
Differential Revision: https://reviews.llvm.org/D27624
llvm-svn: 289706
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 57beb422..3ddb66e 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -6053,6 +6053,9 @@
unsigned SplatBitSize;
bool HasAnyUndefs;
if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
+ if (SplatUndef.isAllOnesValue())
+ return DAG.getUNDEF(VT);
+
if (SplatBitSize <= 64) {
// Check if an immediate VMOV works.
EVT VmovVT;
@@ -6214,6 +6217,24 @@
return shuffle;
}
+ if (VT.is128BitVector() && VT != MVT::v2f64 && VT != MVT::v4f32) {
+ // If we haven't found an efficient lowering, try splitting a 128-bit vector
+ // into two 64-bit vectors; we might discover a better way to lower it.
+ SmallVector<SDValue, 64> Ops(Op->op_begin(), Op->op_begin() + NumElts);
+ EVT ExtVT = VT.getVectorElementType();
+ EVT HVT = EVT::getVectorVT(*DAG.getContext(), ExtVT, NumElts / 2);
+ SDValue Lower =
+ DAG.getBuildVector(HVT, dl, makeArrayRef(&Ops[0], NumElts / 2));
+ if (Lower.getOpcode() == ISD::BUILD_VECTOR)
+ Lower = LowerBUILD_VECTOR(Lower, DAG, ST);
+ SDValue Upper = DAG.getBuildVector(
+ HVT, dl, makeArrayRef(&Ops[NumElts / 2], NumElts / 2));
+ if (Upper.getOpcode() == ISD::BUILD_VECTOR)
+ Upper = LowerBUILD_VECTOR(Upper, DAG, ST);
+ if (Lower && Upper)
+ return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lower, Upper);
+ }
+
// Vectors with 32- or 64-bit elements can be built by directly assigning
// the subregisters. Lower it to an ARMISD::BUILD_VECTOR so the operands
// will be legalized.