Index: lib/Target/X86/X86ISelLowering.h =================================================================== --- lib/Target/X86/X86ISelLowering.h +++ lib/Target/X86/X86ISelLowering.h @@ -981,6 +981,10 @@ const SmallVectorImpl &OutVals, SDLoc dl, SelectionDAG &DAG) const override; + SDValue LowerReturnWithRegisters(SDValue chain, + const SmallVectorImpl &, + SDLoc, SelectionDAG &) const override; + bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override; bool mayBeEmittedAsTailCall(CallInst *CI) const override; Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -2012,6 +2012,42 @@ return DAG.getNode(X86ISD::RET_FLAG, dl, MVT::Other, RetOps); } +SDValue X86TargetLowering::LowerReturnWithRegisters( + SDValue chain, + const SmallVectorImpl &values, + SDLoc dl, SelectionDAG &DAG) const { + MachineFunction &MF = DAG.getMachineFunction(); + X86MachineFunctionInfo *FuncInfo = MF.getInfo(); + SmallVector ops; + SDValue flag, r; + + ops.push_back(chain); + ops.push_back(DAG.getTargetConstant(FuncInfo->getBytesToPopOnReturn(), + MVT::i16)); + + if (chain->getNumValues() > 1) + flag = chain.getValue(1); + + for (auto i = values.begin(), e = values.end(); i != e; ++i) { + ops.push_back(*i); + } + + // Add the flag if we have it. + if (flag.getNode()) + ops.push_back(flag); + + r = DAG.getNode(X86ISD::RET_FLAG, dl, MVT::Other, ops); + assert((!flag.getNode() + || r->getOperand(r->getNumOperands()-1).getValueType() == MVT::Glue) + && "Failed to create glue operand"); + assert(r->getOperand(0).getValueType() == MVT::Other + && "Failed to create chain operand"); + assert(r->getOperand(1).getValueType() == MVT::i16 + && "Failed to create stack fixup operand"); + return r; +} + + bool X86TargetLowering::isUsedByReturnOnly(SDNode *N, SDValue &Chain) const { if (N->getNumValues() != 1) return false;