-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[CoroEarly] Infer presplitcoroutine attribute for Switch-Resumed ABI #169866
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-coroutines Author: Weibo He (NewSigma) ChangesThis patch proposes adding Close #156652 Full diff: https://github.com/llvm/llvm-project/pull/169866.diff 1 Files Affected:
diff --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
index cdb58523d1e0e..a84fdad071303 100644
--- a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
@@ -204,64 +204,66 @@ void Lowerer::lowerEarlyIntrinsics(Function &F) {
continue;
switch (CB->getIntrinsicID()) {
- default:
- continue;
- case Intrinsic::coro_begin:
- case Intrinsic::coro_begin_custom_abi:
- if (CoroBegin)
- report_fatal_error(
- "coroutine should have exactly one defining @llvm.coro.begin");
- CoroBegin = cast<CoroBeginInst>(&I);
- break;
- case Intrinsic::coro_free:
- CoroFrees.push_back(cast<CoroFreeInst>(&I));
- break;
- case Intrinsic::coro_suspend:
- // Make sure that final suspend point is not duplicated as CoroSplit
- // pass expects that there is at most one final suspend point.
- if (cast<CoroSuspendInst>(&I)->isFinal())
- CB->setCannotDuplicate();
- HasCoroSuspend = true;
- break;
- case Intrinsic::coro_end_async:
- case Intrinsic::coro_end:
- // Make sure that fallthrough coro.end is not duplicated as CoroSplit
- // pass expects that there is at most one fallthrough coro.end.
- if (cast<AnyCoroEndInst>(&I)->isFallthrough())
- CB->setCannotDuplicate();
- break;
- case Intrinsic::coro_noop:
- lowerCoroNoop(cast<IntrinsicInst>(&I));
- break;
- case Intrinsic::coro_id:
- if (auto *CII = cast<CoroIdInst>(&I)) {
- if (CII->getInfo().isPreSplit()) {
- assert(F.isPresplitCoroutine() &&
- "The frontend uses Switch-Resumed ABI should emit "
- "\"presplitcoroutine\" attribute for the coroutine.");
- setCannotDuplicate(CII);
- CII->setCoroutineSelf();
- CoroId = cast<CoroIdInst>(&I);
- }
+ default:
+ continue;
+ case Intrinsic::coro_begin:
+ case Intrinsic::coro_begin_custom_abi:
+ if (CoroBegin)
+ report_fatal_error(
+ "coroutine should have exactly one defining @llvm.coro.begin");
+ CoroBegin = cast<CoroBeginInst>(&I);
+ break;
+ case Intrinsic::coro_free:
+ CoroFrees.push_back(cast<CoroFreeInst>(&I));
+ break;
+ case Intrinsic::coro_suspend:
+ // Make sure that final suspend point is not duplicated as CoroSplit
+ // pass expects that there is at most one final suspend point.
+ if (cast<CoroSuspendInst>(&I)->isFinal())
+ CB->setCannotDuplicate();
+ HasCoroSuspend = true;
+ break;
+ case Intrinsic::coro_end_async:
+ case Intrinsic::coro_end:
+ // Make sure that fallthrough coro.end is not duplicated as CoroSplit
+ // pass expects that there is at most one fallthrough coro.end.
+ if (cast<AnyCoroEndInst>(&I)->isFallthrough())
+ CB->setCannotDuplicate();
+ break;
+ case Intrinsic::coro_noop:
+ lowerCoroNoop(cast<IntrinsicInst>(&I));
+ break;
+ case Intrinsic::coro_id:
+ if (auto *CII = cast<CoroIdInst>(&I)) {
+ if (CII->getInfo().isPreSplit()) {
+ // The frontend uses Switch-Resumed ABI should emit
+ // `presplitcoroutine` attribute for the coroutine.
+ if (!F.isPresplitCoroutine())
+ F.setPresplitCoroutine();
+
+ setCannotDuplicate(CII);
+ CII->setCoroutineSelf();
+ CoroId = cast<CoroIdInst>(&I);
}
- break;
- case Intrinsic::coro_id_retcon:
- case Intrinsic::coro_id_retcon_once:
- case Intrinsic::coro_id_async:
- F.setPresplitCoroutine();
- break;
- case Intrinsic::coro_resume:
- lowerResumeOrDestroy(*CB, CoroSubFnInst::ResumeIndex);
- break;
- case Intrinsic::coro_destroy:
- lowerResumeOrDestroy(*CB, CoroSubFnInst::DestroyIndex);
- break;
- case Intrinsic::coro_promise:
- lowerCoroPromise(cast<CoroPromiseInst>(&I));
- break;
- case Intrinsic::coro_done:
- lowerCoroDone(cast<IntrinsicInst>(&I));
- break;
+ }
+ break;
+ case Intrinsic::coro_id_retcon:
+ case Intrinsic::coro_id_retcon_once:
+ case Intrinsic::coro_id_async:
+ F.setPresplitCoroutine();
+ break;
+ case Intrinsic::coro_resume:
+ lowerResumeOrDestroy(*CB, CoroSubFnInst::ResumeIndex);
+ break;
+ case Intrinsic::coro_destroy:
+ lowerResumeOrDestroy(*CB, CoroSubFnInst::DestroyIndex);
+ break;
+ case Intrinsic::coro_promise:
+ lowerCoroPromise(cast<CoroPromiseInst>(&I));
+ break;
+ case Intrinsic::coro_done:
+ lowerCoroDone(cast<IntrinsicInst>(&I));
+ break;
}
}
|
|
Please add tests. |
|
Done. Thanks for the reminder. |
🐧 Linux x64 Test Results
Failed Tests(click on a test name to see its output) ClangClang.CodeGenCoroutines/coro-always-inline.cppClang.CodeGenCoroutines/coro-attributes.cppIf these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the |
|
If you just want to fix the crash, you can add a verifier check. (The IR will still fail to parse, but it won't present as a crash.) That said, if it's not useful to have the frontend add the marking, we can just drop the requirement. |
This patch proposes adding
presplitcoroutineattribute instead of asserting it. It doesn't seem good to suppress the requirement in release mode.Close #156652