[llvm] [CGP] Consider arguments and ret values in `dupRetToEnableTailCallOpts` (PR #76613)
Antonio Frighetto via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 7 08:57:50 PST 2024
================
@@ -2620,8 +2621,58 @@ bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
// Make sure the phi value is indeed produced by the tail call.
if (CI && CI->hasOneUse() && CI->getParent() == PredBB &&
TLI->mayBeEmittedAsTailCall(CI) &&
- attributesPermitTailCall(F, CI, RetI, *TLI))
+ attributesPermitTailCall(F, CI, RetI, *TLI)) {
TailCallBBs.push_back(PredBB);
+ } else {
+ /// Consider the cases in which the phi value is indirectly produced by
+ /// the tail call, for example when encountering memset(), memmove(),
+ /// strcpy(), whose return value may have been optimized out. In such
+ /// cases, the value needs to be the first function argument.
+ /// @code
+ /// bb0:
+ /// tail call void @llvm.memset.p0.i64(ptr %0, i8 0, i64 %1)
+ /// br label %return
+ /// return:
+ /// %phi = phi ptr [ %0, %bb0 ], [ %2, %entry ]
+ /// @endcode
+ if (PredBB && PredBB->getSingleSuccessor() == BB)
+ CI = dyn_cast_or_null<CallInst>(
+ PredBB->getTerminator()->getPrevNonDebugInstruction(true));
+
+ auto IsIntrinsicOrLibFuncToBeTailCalled = [&](const auto *CI) {
+ if (CI && CI->use_empty() && CI->hasArgument(IncomingVal) &&
+ IncomingVal == CI->getArgOperand(0)) {
+ if (const auto *II = dyn_cast<IntrinsicInst>(CI))
+ switch (II->getIntrinsicID()) {
+ case Intrinsic::memset:
+ case Intrinsic::memcpy:
+ case Intrinsic::memmove:
+ return true;
+ default:
+ return false;
+ }
+
+ LibFunc LF;
+ Function *Callee = CI->getCalledFunction();
+ if (Callee && TLInfo && TLInfo->getLibFunc(*Callee, LF))
+ switch (LF) {
+ case LibFunc_strcpy:
+ case LibFunc_strncpy:
+ case LibFunc_strcat:
+ case LibFunc_strncat:
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+ };
+
+ if (IsIntrinsicOrLibFuncToBeTailCalled(CI) &&
+ TLI->mayBeEmittedAsTailCall(CI) &&
+ attributesPermitTailCall(F, CI, RetI, *TLI))
+ TailCallBBs.push_back(PredBB);
+ }
----------------
antoniofrighetto wrote:
It turns out we need them in the !PN branch too when handling a Arg or CallInst, added more test coverage, thanks for taking a look.
https://github.com/llvm/llvm-project/pull/76613
More information about the llvm-commits
mailing list