@@ -7974,12 +7974,19 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
79747974 }
79757975 case Intrinsic::amdgcn_call_whole_wave: {
79767976 TargetLowering::ArgListTy Args;
7977+ bool isTailCall = I.isTailCall();
79777978
79787979 // The first argument is the callee. Skip it when assembling the call args.
79797980 for (unsigned Idx = 1; Idx < I.arg_size(); ++Idx) {
79807981 TargetLowering::ArgListEntry Arg(getValue(I.getArgOperand(Idx)),
79817982 I.getArgOperand(Idx)->getType());
79827983 Arg.setAttributes(&I, Idx);
7984+
7985+ // If we have an explicit sret argument that is an Instruction, (i.e., it
7986+ // might point to function-local memory), we can't meaningfully tail-call.
7987+ if (Arg.IsSRet && isa<Instruction>(I.getArgOperand(Idx)))
7988+ isTailCall = false;
7989+
79837990 Args.push_back(Arg);
79847991 }
79857992
@@ -7994,7 +8001,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
79948001 .setChain(getRoot())
79958002 .setCallee(CallingConv::AMDGPU_Gfx_WholeWave, I.getType(),
79968003 getValue(I.getArgOperand(0)), std::move(Args))
7997- .setTailCall(false )
8004+ .setTailCall(isTailCall && canTailCall(I) )
79988005 .setIsPreallocated(
79998006 I.countOperandBundlesOfType(LLVMContext::OB_preallocated) != 0)
80008007 .setConvergent(I.isConvergent())
@@ -8929,6 +8936,29 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
89298936 return Result;
89308937}
89318938
8939+ bool SelectionDAGBuilder::canTailCall(const CallBase &CB) const {
8940+ bool isMustTailCall = CB.isMustTailCall();
8941+
8942+ // Avoid emitting tail calls in functions with the disable-tail-calls
8943+ // attribute.
8944+ const Function *Caller = CB.getParent()->getParent();
8945+ if (Caller->getFnAttribute("disable-tail-calls").getValueAsString() ==
8946+ "true" &&
8947+ !isMustTailCall)
8948+ return false;
8949+
8950+ // We can't tail call inside a function with a swifterror argument. Lowering
8951+ // does not support this yet. It would have to move into the swifterror
8952+ // register before the call.
8953+ if (DAG.getTargetLoweringInfo().supportSwiftError() &&
8954+ Caller->getAttributes().hasAttrSomewhere(Attribute::SwiftError))
8955+ return false;
8956+
8957+ // Check if target-independent constraints permit a tail call here.
8958+ // Target-dependent constraints are checked within TLI->LowerCallTo.
8959+ return isInTailCallPosition(CB, DAG.getTarget());
8960+ }
8961+
89328962void SelectionDAGBuilder::LowerCallTo(const CallBase &CB, SDValue Callee,
89338963 bool isTailCall, bool isMustTailCall,
89348964 const BasicBlock *EHPadBB,
@@ -8943,21 +8973,8 @@ void SelectionDAGBuilder::LowerCallTo(const CallBase &CB, SDValue Callee,
89438973 const Value *SwiftErrorVal = nullptr;
89448974 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
89458975
8946- if (isTailCall) {
8947- // Avoid emitting tail calls in functions with the disable-tail-calls
8948- // attribute.
8949- auto *Caller = CB.getParent()->getParent();
8950- if (Caller->getFnAttribute("disable-tail-calls").getValueAsString() ==
8951- "true" && !isMustTailCall)
8952- isTailCall = false;
8953-
8954- // We can't tail call inside a function with a swifterror argument. Lowering
8955- // does not support this yet. It would have to move into the swifterror
8956- // register before the call.
8957- if (TLI.supportSwiftError() &&
8958- Caller->getAttributes().hasAttrSomewhere(Attribute::SwiftError))
8959- isTailCall = false;
8960- }
8976+ if (isTailCall)
8977+ isTailCall = canTailCall(CB);
89618978
89628979 for (auto I = CB.arg_begin(), E = CB.arg_end(); I != E; ++I) {
89638980 const Value *V = *I;
@@ -8997,11 +9014,6 @@ void SelectionDAGBuilder::LowerCallTo(const CallBase &CB, SDValue Callee,
89979014 Args.push_back(Entry);
89989015 }
89999016
9000- // Check if target-independent constraints permit a tail call here.
9001- // Target-dependent constraints are checked within TLI->LowerCallTo.
9002- if (isTailCall && !isInTailCallPosition(CB, DAG.getTarget()))
9003- isTailCall = false;
9004-
90059017 // Disable tail calls if there is an swifterror argument. Targets have not
90069018 // been updated to support tail calls.
90079019 if (TLI.supportSwiftError() && SwiftErrorVal)
0 commit comments