Index: llvm/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.cpp +++ llvm/lib/Target/X86/X86ISelLowering.cpp @@ -3330,38 +3330,28 @@ // For info on fast calling convention see Fast Calling Convention (tail call) // implementation LowerX86_32FastCCCallTo. -/// CallIsStructReturn - Determines whether a call uses struct return -/// semantics. -enum StructReturnType { - NotStructReturn, - RegStructReturn, - StackStructReturn -}; -static StructReturnType -callIsStructReturn(ArrayRef Outs, bool IsMCU) { - if (Outs.empty()) - return NotStructReturn; +/// Determines whether Outs contains an [initial] sret pointer +static bool returnHasSRet(ArrayRef Outs, bool IsMCU) { + if (IsMCU || Outs.empty()) + return false; const ISD::ArgFlagsTy &Flags = Outs[0].Flags; - if (!Flags.isSRet()) - return NotStructReturn; - if (Flags.isInReg() || IsMCU) - return RegStructReturn; - return StackStructReturn; + if (Flags.isSRet() && !Flags.isInReg()) + return true; + + return false; } -/// Determines whether a function uses struct return semantics. -static StructReturnType -argsAreStructReturn(ArrayRef Ins, bool IsMCU) { - if (Ins.empty()) - return NotStructReturn; +/// Determines whether Ins contains an [initial] sret pointer. +static bool argsHaveSRet(ArrayRef Ins, bool IsMCU) { + if (IsMCU || Ins.empty()) + return false; const ISD::ArgFlagsTy &Flags = Ins[0].Flags; - if (!Flags.isSRet()) - return NotStructReturn; - if (Flags.isInReg() || IsMCU) - return RegStructReturn; - return StackStructReturn; + if (Flags.isSRet() && !Flags.isInReg()) + return true; + + return false; } /// Make a copy of an aggregate at address specified by "Src" to address @@ -3997,7 +3987,7 @@ // If this is an sret function, the return should pop the hidden pointer. if (!Is64Bit && !canGuaranteeTCO(CallConv) && !Subtarget.getTargetTriple().isOSMSVCRT() && - argsAreStructReturn(Ins, Subtarget.isTargetMCU()) == StackStructReturn) + argsHaveSRet(Ins, Subtarget.isTargetMCU())) FuncInfo->setBytesToPopOnReturn(4); } @@ -4116,7 +4106,7 @@ MachineFunction &MF = DAG.getMachineFunction(); bool Is64Bit = Subtarget.is64Bit(); bool IsWin64 = Subtarget.isCallingConvWin64(CallConv); - StructReturnType SR = callIsStructReturn(Outs, Subtarget.isTargetMCU()); + bool IsSRet = returnHasSRet(Outs, Subtarget.isTargetMCU()); bool IsSibcall = false; bool IsGuaranteeTCO = MF.getTarget().Options.GuaranteedTailCallOpt || CallConv == CallingConv::Tail || CallConv == CallingConv::SwiftTail; @@ -4149,8 +4139,7 @@ if (isTailCall && !IsMustTail) { // Check if it's really possible to do a tail call. isTailCall = IsEligibleForTailCallOptimization( - Callee, CallConv, SR == StackStructReturn, isVarArg, CLI.RetTy, Outs, - OutVals, Ins, DAG); + Callee, CallConv, IsSRet, isVarArg, CLI.RetTy, Outs, OutVals, Ins, DAG); // Sibcalls are automatically detected tailcalls which do not require // ABI changes. @@ -4656,8 +4645,7 @@ DAG.getTarget().Options.GuaranteedTailCallOpt)) NumBytesForCalleeToPop = NumBytes; // Callee pops everything else if (!Is64Bit && !canGuaranteeTCO(CallConv) && - !Subtarget.getTargetTriple().isOSMSVCRT() && - SR == StackStructReturn) + !Subtarget.getTargetTriple().isOSMSVCRT() && IsSRet) // If this is a call to a struct-return function, the callee // pops the hidden struct pointer, so we have to push it back. // This is common for Darwin/X86, Linux & Mingw32 targets.