- // The low part is sign extension of the input (which degenerates to a copy).
- Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0));
-
- // The high part is obtained by SRA'ing all but one of the bits of low part.
- unsigned LoSize = MVT::getSizeInBits(NVT);
- Hi = DAG.getNode(ISD::SRA, NVT, Lo,
- DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
+ SDOperand Op = N->getOperand(0);
+ if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) {
+ // The low part is sign extension of the input (which degenerates to a copy).
+ Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0));
+ // The high part is obtained by SRA'ing all but one of the bits of low part.
+ unsigned LoSize = MVT::getSizeInBits(NVT);
+ Hi = DAG.getNode(ISD::SRA, NVT, Lo,
+ DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
+ } else {
+ // For example, extension of an i48 to an i64. The operand type necessarily
+ // promotes to the result type, so will end up being expanded too.
+ assert(getTypeAction(Op.getValueType()) == Promote &&
+ "Don't know how to expand this result!");
+ SDOperand Res = GetPromotedOp(Op);
+ assert(Res.getValueType() == N->getValueType(0) &&
+ "Operand over promoted?");
+ // Split the promoted operand. This will simplify when it is expanded.
+ SplitOp(Res, Lo, Hi);
+ unsigned ExcessBits =
+ MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT);
+ Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi,
+ DAG.getValueType(MVT::getIntegerType(ExcessBits)));
+ }