Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4126,35 +4126,36 @@ assert(EVT.bitsLE(VT) && "Not extending!"); if (EVT == VT) return N1; // Not actually extending - auto SignExtendInReg = [&](APInt Val) { + auto SignExtendInReg = [&](APInt Val, llvm::EVT ScalarVT) { unsigned FromBits = EVT.getScalarSizeInBits(); Val <<= Val.getBitWidth() - FromBits; Val = Val.ashr(Val.getBitWidth() - FromBits); - return getConstant(Val, DL, VT.getScalarType()); + return getConstant(Val, DL, ScalarVT); }; if (N1C) { const APInt &Val = N1C->getAPIntValue(); - return SignExtendInReg(Val); + return SignExtendInReg(Val, VT.getScalarType()); } if (ISD::isBuildVectorOfConstantSDNodes(N1.getNode())) { + // If the scalar type of VT is not legal, keep the original operand type. + llvm::EVT LegalScalarVT = (TLI->isTypeLegal(VT.getScalarType()) ? + VT.getScalarType() : N1.getOperand(0).getValueType().getScalarType()); + SmallVector Ops; for (int i = 0, e = VT.getVectorNumElements(); i != e; ++i) { SDValue Op = N1.getOperand(i); - if (Op.isUndef()) { - Ops.push_back(getUNDEF(VT.getScalarType())); - continue; - } - if (ConstantSDNode *C = dyn_cast(Op)) { + if (Op.isUndef()) + Ops.push_back(getUNDEF(LegalScalarVT)); + else { + ConstantSDNode *C = cast(Op); APInt Val = C->getAPIntValue(); - Val = Val.zextOrTrunc(VT.getScalarSizeInBits()); - Ops.push_back(SignExtendInReg(Val)); + Val = Val.zextOrTrunc(LegalScalarVT.getSizeInBits()); + Ops.push_back(SignExtendInReg(Val, LegalScalarVT)); continue; } - break; } - if (Ops.size() == VT.getVectorNumElements()) - return getBuildVector(VT, DL, Ops); + return getBuildVector(VT, DL, Ops); } break; }