// 256-bit AVX can use the vinsertf128 instruction
// to create 256-bit vectors from two other 128-bit ones.
+// TODO: Detect subvector broadcast here instead of DAG combine?
static SDValue LowerAVXCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
SDLoc dl(Op);
}
}
- // If there are zero or one non-zeros we can handle this very simply.
- if (NumNonZero <= 1) {
- SDValue Vec = NumZero ? getZeroVector(ResVT, Subtarget, DAG, dl)
- : DAG.getUNDEF(ResVT);
- if (!NumNonZero)
- return Vec;
- unsigned Idx = countTrailingZeros(NonZeros);
- SDValue SubVec = Op.getOperand(Idx);
- unsigned SubVecNumElts = SubVec.getSimpleValueType().getVectorNumElements();
- return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec, SubVec,
- DAG.getIntPtrConstant(Idx * SubVecNumElts, dl));
- }
-
- if (NumOperands > 2) {
+ // If we have more than 2 non-zeros, build each half separately.
+ if (NumNonZero > 2) {
MVT HalfVT = MVT::getVectorVT(ResVT.getVectorElementType(),
ResVT.getVectorNumElements()/2);
ArrayRef<SDUse> Ops = Op->ops();
return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
}
- assert(NumNonZero == 2 && "Simple cases not handled?");
+ // Otherwise, build it up through insert_subvectors.
+ SDValue Vec = NumZero ? getZeroVector(ResVT, Subtarget, DAG, dl)
+ : DAG.getUNDEF(ResVT);
- SDValue Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT,
- DAG.getUNDEF(ResVT), Op.getOperand(0),
- DAG.getIntPtrConstant(0, dl));
- unsigned NumElems = ResVT.getVectorNumElements();
- return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec, Op.getOperand(1),
- DAG.getIntPtrConstant(NumElems/2, dl));
+ MVT SubVT = Op.getOperand(0).getSimpleValueType();
+ unsigned NumSubElems = SubVT.getVectorNumElements();
+ for (unsigned i = 0; i != NumOperands; ++i) {
+ if ((NonZeros & (1 << i)) == 0)
+ continue;
+
+ Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec,
+ Op.getOperand(i),
+ DAG.getIntPtrConstant(i * NumSubElems, dl));
+ }
+
+ return Vec;
}
// Return true if all the operands of the given CONCAT_VECTORS node are zeros