[llvm] [CGP] Consider arguments and ret values in `dupRetToEnableTailCallOpts` (PR #76613)

Antonio Frighetto via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 16 05:55:14 PST 2024


================
@@ -2621,8 +2622,36 @@ 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(),
+        /// whose return value may have been optimized out.
+        /// @code
+        /// bb0:
+        ///   tail call void @llvm.memset.p0.i64()
+        ///   br label %return
+        /// @endcode
+        if (PredBB && PredBB->getSingleSuccessor() == BB)
+          CI = dyn_cast_or_null<CallInst>(
+              PredBB->getTerminator()->getPrevNonDebugInstruction(true));
+
+        // If we return void from the call site, it must be an intrinsic.
+        if (CI && CI->getType()->isVoidTy() && !isa<IntrinsicInst>(CI))
----------------
antoniofrighetto wrote:

It helps preventing cases in which `FoldReturnIntoUncondBranch` would otherwise be called uselessly later (causing, among other things, compile-time regressions, as above). We are handling cases in which the return value propagated via the phi is, in principle, _not_ the return value of the call site. I can't think of a valid scenario in which we could be tail calling in those cases, unless handling a `llvm.memset` / `llvm.memcpy` / `llvm.memmove` (similarly for the `strcpy` case later: https://godbolt.org/z/ao5WKW74W).

https://github.com/llvm/llvm-project/pull/76613


More information about the llvm-commits mailing list