- SDValue Tmp1;
-
- // The incoming vector might already be the proper type
- if (Node->getOperand(0).getValueType() != WidenVT)
- Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT);
- else
- Tmp1 = Node->getOperand(0);
- assert(Tmp1.getValueType() == WidenVT);
- Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, Node->getOperand(1));
+ SDValue Tmp1 = Node->getOperand(0);
+ SDValue Idx = Node->getOperand(1);
+ ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx);
+ if (CIdx && CIdx->getZExtValue() == 0) {
+ // Since we are access the start of the vector, the incoming
+ // vector type might be the proper.
+ MVT Tmp1VT = Tmp1.getValueType();
+ if (Tmp1VT == WidenVT)
+ return Tmp1;
+ else {
+ unsigned Tmp1VTNumElts = Tmp1VT.getVectorNumElements();
+ if (Tmp1VTNumElts < NewNumElts)
+ Result = WidenVectorOp(Tmp1, WidenVT);
+ else
+ Result = DAG.getNode(ISD::EXTRACT_SUBVECTOR, WidenVT, Tmp1, Idx);
+ }
+ } else if (NewNumElts % NumElts == 0) {
+ // Widen the extracted subvector.
+ unsigned NumConcat = NewNumElts / NumElts;
+ SDValue UndefVal = DAG.getNode(ISD::UNDEF, VT);
+ SmallVector<SDValue, 8> MOps;
+ MOps.push_back(Op);
+ for (unsigned i = 1; i != NumConcat; ++i) {
+ MOps.push_back(UndefVal);
+ }
+ Result = LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, WidenVT,
+ &MOps[0], MOps.size()));
+ } else {
+ assert(0 && "can not widen extract subvector");
+ // This could be implemented using insert and build vector but I would
+ // like to see when this happens.
+ }