[clang] [llvm] [coro] Lower `llvm.coro.await.suspend.handle` to resume with tail call (PR #89751)

Chuanqi Xu via llvm-commits llvm-commits at lists.llvm.org
Thu May 23 02:27:35 PDT 2024


ChuanqiXu9 wrote:

It is pretty interesting that I can pass the test by:

```
$git diff -U10
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 450ea8234371..003bfbf7138a 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -220,20 +220,21 @@ static void lowerAwaitSuspend(IRBuilder<> &Builder, CoroAwaitSuspendInst *CB,
     }

     coro::LowererBase LB(*Wrapper->getParent());
     auto *ResumeAddr = LB.makeSubFnCall(NewCall, CoroSubFnInst::ResumeIndex,
                                         &*Builder.GetInsertPoint());

     LLVMContext &Ctx = Builder.getContext();
     FunctionType *ResumeTy = FunctionType::get(
         Type::getVoidTy(Ctx), PointerType::getUnqual(Ctx), false);
     auto *ResumeCall = Builder.CreateCall(ResumeTy, ResumeAddr, {NewCall});
+    ResumeCall->setCallingConv(CallingConv::Fast);

     // We can't insert the 'ret' instruction and adjust the cc until the
     // function has been split, so remember this for later.
     Shape.SymmetricTransfers.push_back(ResumeCall);

     NewCall = ResumeCall;
   }

   CB->replaceAllUsesWith(NewCall);
   CB->eraseFromParent();
```

The breaking only happens with optimizations in a workload.

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


More information about the llvm-commits mailing list