-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[Coroutines] Add llvm.coro.is_in_ramp and drop return value of llvm.coro.end #153404
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
✅ With the latest revision this PR passed the C/C++ code formatter. |
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-clang-codegen Author: Weibo He (NewSigma) ChangesAs mentioned in #151067, current design of Patch is 149.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/153404.diff 147 Files Affected:
diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp
index 827385f9c1a1f..cbc38516a0815 100644
--- a/clang/lib/CodeGen/CGCoroutine.cpp
+++ b/clang/lib/CodeGen/CGCoroutine.cpp
@@ -575,17 +575,19 @@ struct CallCoroEnd final : public EHScopeStack::Cleanup {
llvm::Function *CoroEndFn = CGM.getIntrinsic(llvm::Intrinsic::coro_end);
// See if we have a funclet bundle to associate coro.end with. (WinEH)
auto Bundles = getBundlesForCoroEnd(CGF);
- auto *CoroEnd =
- CGF.Builder.CreateCall(CoroEndFn,
- {NullPtr, CGF.Builder.getTrue(),
- llvm::ConstantTokenNone::get(CoroEndFn->getContext())},
- Bundles);
+ CGF.Builder.CreateCall(
+ CoroEndFn,
+ {NullPtr, CGF.Builder.getTrue(),
+ llvm::ConstantTokenNone::get(CoroEndFn->getContext())},
+ Bundles);
if (Bundles.empty()) {
// Otherwise, (landingpad model), create a conditional branch that leads
// either to a cleanup block or a block with EH resume instruction.
auto *ResumeBB = CGF.getEHResumeBlock(/*isCleanup=*/true);
auto *CleanupContBB = CGF.createBasicBlock("cleanup.cont");
- CGF.Builder.CreateCondBr(CoroEnd, ResumeBB, CleanupContBB);
+ auto *CoroWhereFn = CGM.getIntrinsic(llvm::Intrinsic::coro_where);
+ auto *CoroWhere = CGF.Builder.CreateCall(CoroWhereFn);
+ CGF.Builder.CreateCondBr(CoroWhere, ResumeBB, CleanupContBB);
CGF.EmitBlock(CleanupContBB);
}
}
diff --git a/clang/test/CodeGenCoroutines/coro-builtins.c b/clang/test/CodeGenCoroutines/coro-builtins.c
index 79f119b2b60ff..0c2553274f09f 100644
--- a/clang/test/CodeGenCoroutines/coro-builtins.c
+++ b/clang/test/CodeGenCoroutines/coro-builtins.c
@@ -37,7 +37,7 @@ void f(int n) {
// CHECK-NEXT: call ptr @llvm.coro.free(token %[[COROID]], ptr %[[FRAME]])
__builtin_coro_free(__builtin_coro_frame());
- // CHECK-NEXT: call i1 @llvm.coro.end(ptr %[[FRAME]], i1 false, token none)
+ // CHECK-NEXT: call void @llvm.coro.end(ptr %[[FRAME]], i1 false, token none)
__builtin_coro_end(__builtin_coro_frame(), 0);
// CHECK-NEXT: call i8 @llvm.coro.suspend(token none, i1 true)
diff --git a/clang/test/CodeGenCoroutines/coro-eh-cleanup.cpp b/clang/test/CodeGenCoroutines/coro-eh-cleanup.cpp
index 725cf8faa6b4c..d849ccef17681 100644
--- a/clang/test/CodeGenCoroutines/coro-eh-cleanup.cpp
+++ b/clang/test/CodeGenCoroutines/coro-eh-cleanup.cpp
@@ -60,7 +60,7 @@ coro_t f() {
// CHECK: [[COROENDBB]]:
// CHECK-NEXT: %[[CLPAD:.+]] = cleanuppad within none
-// CHECK-NEXT: call i1 @llvm.coro.end(ptr null, i1 true, token none) [ "funclet"(token %[[CLPAD]]) ]
+// CHECK-NEXT: call void @llvm.coro.end(ptr null, i1 true, token none) [ "funclet"(token %[[CLPAD]]) ]
// CHECK-NEXT: cleanupret from %[[CLPAD]] unwind label
// CHECK-LPAD: @_Z1fv(
@@ -76,7 +76,7 @@ coro_t f() {
// CHECK-LPAD: to label %{{.+}} unwind label %[[UNWINDBB:.+]]
// CHECK-LPAD: [[UNWINDBB]]:
-// CHECK-LPAD: %[[I1RESUME:.+]] = call i1 @llvm.coro.end(ptr null, i1 true, token none)
+// CHECK-LPAD: %[[I1RESUME:.+]] = call i1 @llvm.coro.where()
// CHECK-LPAD: br i1 %[[I1RESUME]], label %[[EHRESUME:.+]], label
// CHECK-LPAD: [[EHRESUME]]:
// CHECK-LPAD-NEXT: %[[exn:.+]] = load ptr, ptr %exn.slot, align 8
diff --git a/clang/test/CodeGenCoroutines/coro-lambda.cpp b/clang/test/CodeGenCoroutines/coro-lambda.cpp
index 26c51070f9e2d..b24a190ab41fb 100644
--- a/clang/test/CodeGenCoroutines/coro-lambda.cpp
+++ b/clang/test/CodeGenCoroutines/coro-lambda.cpp
@@ -55,4 +55,4 @@ void f() {
// CHECK: alloca %"struct.Task::promise_type"
// CHECK: call token @llvm.coro.id(
// CHECK: call i8 @llvm.coro.suspend(
-// CHECK: call i1 @llvm.coro.end(
+// CHECK: call void @llvm.coro.end(
diff --git a/clang/test/CodeGenCoroutines/coro-params.cpp b/clang/test/CodeGenCoroutines/coro-params.cpp
index 719726cca29c5..79e77a21017fa 100644
--- a/clang/test/CodeGenCoroutines/coro-params.cpp
+++ b/clang/test/CodeGenCoroutines/coro-params.cpp
@@ -117,7 +117,7 @@ void f(int val, MoveOnly moParam, MoveAndCopy mcParam, TrivialABI trivialParam)
// CHECK-NEXT: call ptr @llvm.coro.free(
// The original trivial_abi parameter is destroyed when returning from the ramp.
- // CHECK: call i1 @llvm.coro.end
+ // CHECK: call void @llvm.coro.end
// CHECK: call void @_ZN10TrivialABID1Ev(ptr {{[^,]*}} %[[TrivialAlloca]])
}
@@ -242,6 +242,6 @@ void msabi(MSParm p) {
co_return;
// The local alloca is used for the destructor call at the end of the ramp.
- // MSABI: call i1 @llvm.coro.end
+ // MSABI: call void @llvm.coro.end
// MSABI: call void @"??1MSParm@@QEAA@XZ"(ptr{{.*}} %[[ParamAlloca]])
}
diff --git a/llvm/docs/Coroutines.rst b/llvm/docs/Coroutines.rst
index dde73c9c3cc23..d9114eb1d1aa6 100644
--- a/llvm/docs/Coroutines.rst
+++ b/llvm/docs/Coroutines.rst
@@ -303,7 +303,7 @@ The LLVM IR for this coroutine looks like this:
call void @free(ptr %mem)
br label %suspend
suspend:
- %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none)
+ call void @llvm.coro.end(ptr %hdl, i1 false, token none)
ret ptr %hdl
}
@@ -637,7 +637,7 @@ store the current value produced by a coroutine.
call void @free(ptr %mem)
br label %suspend
suspend:
- %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none)
+ call void @llvm.coro.end(ptr %hdl, i1 false, token none)
ret ptr %hdl
}
@@ -806,7 +806,7 @@ The LLVM IR for a coroutine using a Coroutine with a custom ABI looks like:
call void @free(ptr %mem)
br label %suspend
suspend:
- %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none)
+ call void @llvm.coro.end(ptr %hdl, i1 false, token none)
ret ptr %hdl
}
@@ -1444,7 +1444,7 @@ A frontend should emit function attribute `presplitcoroutine` for the coroutine.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- declare i1 @llvm.coro.end(ptr <handle>, i1 <unwind>, token <result.token>)
+ declare void @llvm.coro.end(ptr <handle>, i1 <unwind>, token <result.token>)
Overview:
"""""""""
@@ -1502,7 +1502,8 @@ For landingpad based exception model, it is expected that frontend uses the
.. code-block:: llvm
ehcleanup:
- %InResumePart = call i1 @llvm.coro.end(ptr null, i1 true, token none)
+ call void @llvm.coro.end(ptr null, i1 true, token none)
+ %InResumePart = call i1 @llvm.coro.where()
br i1 %InResumePart, label %eh.resume, label %cleanup.cont
cleanup.cont:
@@ -1515,7 +1516,7 @@ For landingpad based exception model, it is expected that frontend uses the
%lpad.val29 = insertvalue { ptr, i32 } %lpad.val, i32 %sel, 1
resume { ptr, i32 } %lpad.val29
-The `CoroSpit` pass replaces `coro.end` with ``True`` in the resume functions,
+The `CoroSpit` pass replaces `coro.where` with ``True`` in the resume functions,
thus leading to immediate unwind to the caller, whereas in start function it
is replaced with ``False``, thus allowing to proceed to the rest of the cleanup
code that is only needed during initial invocation of the coroutine.
@@ -1527,7 +1528,7 @@ referring to an enclosing cleanuppad as follows:
ehcleanup:
%tok = cleanuppad within none []
- %unused = call i1 @llvm.coro.end(ptr null, i1 true, token none) [ "funclet"(token %tok) ]
+ call void @llvm.coro.end(ptr null, i1 true, token none) [ "funclet"(token %tok) ]
cleanupret from %tok unwind label %RestOfTheCleanup
The `CoroSplit` pass, if the funclet bundle is present, will insert
@@ -1592,7 +1593,7 @@ The number of arguments must match the return type of the continuation function:
cleanup:
%tok = call token (...) @llvm.coro.end.results(i8 %val)
- call i1 @llvm.coro.end(ptr %hdl, i1 0, token %tok)
+ call void @llvm.coro.end(ptr %hdl, i1 0, token %tok)
unreachable
...
@@ -1604,7 +1605,7 @@ The number of arguments must match the return type of the continuation function:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- declare i1 @llvm.coro.end.async(ptr <handle>, i1 <unwind>, ...)
+ declare void @llvm.coro.end.async(ptr <handle>, i1 <unwind>, ...)
Overview:
"""""""""
@@ -1635,10 +1636,10 @@ the function call.
.. code-block:: llvm
- call i1 (ptr, i1, ...) @llvm.coro.end.async(
- ptr %hdl, i1 0,
- ptr @must_tail_call_return,
- ptr %ctxt, ptr %task, ptr %actor)
+ call void (ptr, i1, ...) @llvm.coro.end.async(
+ ptr %hdl, i1 0,
+ ptr @must_tail_call_return,
+ ptr %ctxt, ptr %task, ptr %actor)
unreachable
.. _coro.suspend:
@@ -2117,6 +2118,30 @@ Example:
%hdl.result = ... ; get address of returned coroutine handle
ret ptr %hdl.result
+'llvm.coro.where' Intrinsic
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+::
+
+ declare i1 @llvm.coro.where()
+
+Overview:
+"""""""""
+
+The '``llvm.coro.where``' intrinsic returns a bool value that marks coroutine resume
+part and start part.
+
+Arguments:
+""""""""""
+
+None
+
+Semantics:
+""""""""""
+
+The `CoroSpit` pass replaces `coro.where` with ``True`` in the resume functions,
+whereas in start function it is replaced with ``False``, thus allowing the frontend
+separate resume part and start part.
+
Coroutine Transformation Passes
===============================
CoroEarly
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index e0ee12391b31d..0d113e0ccb854 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -1775,12 +1775,13 @@ def int_coro_free : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty],
[IntrReadMem, IntrArgMemOnly,
ReadOnly<ArgIndex<1>>,
NoCapture<ArgIndex<1>>]>;
-def int_coro_end : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_i1_ty, llvm_token_ty], []>;
+def int_coro_end : Intrinsic<[], [llvm_ptr_ty, llvm_i1_ty, llvm_token_ty], []>;
def int_coro_end_results : Intrinsic<[llvm_token_ty], [llvm_vararg_ty]>;
def int_coro_end_async
- : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_i1_ty, llvm_vararg_ty], []>;
+ : Intrinsic<[], [llvm_ptr_ty, llvm_i1_ty, llvm_vararg_ty], []>;
def int_coro_frame : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
+def int_coro_where : Intrinsic<[llvm_i1_ty], [], [IntrNoMem]>;
def int_coro_noop : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
def int_coro_size : Intrinsic<[llvm_anyint_ty], [], [IntrNoMem]>;
def int_coro_align : Intrinsic<[llvm_anyint_ty], [], [IntrNoMem]>;
diff --git a/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h b/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h
index 0688068167ae6..36ec76c554d50 100644
--- a/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h
+++ b/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h
@@ -428,6 +428,18 @@ class CoroFrameInst : public IntrinsicInst {
}
};
+/// This represents the llvm.coro.where instruction.
+class CoroWhereInst : public IntrinsicInst {
+public:
+ // Methods to support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::coro_where;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
/// This represents the llvm.coro.free instruction.
class CoroFreeInst : public IntrinsicInst {
enum { IdArg, FrameArg };
diff --git a/llvm/include/llvm/Transforms/Coroutines/CoroShape.h b/llvm/include/llvm/Transforms/Coroutines/CoroShape.h
index c54081de2d9da..83697200e061d 100644
--- a/llvm/include/llvm/Transforms/Coroutines/CoroShape.h
+++ b/llvm/include/llvm/Transforms/Coroutines/CoroShape.h
@@ -53,6 +53,7 @@ enum class ABI {
struct Shape {
CoroBeginInst *CoroBegin = nullptr;
SmallVector<AnyCoroEndInst *, 4> CoroEnds;
+ SmallVector<CoroWhereInst *, 2> CoroWheres;
SmallVector<CoroSizeInst *, 2> CoroSizes;
SmallVector<CoroAlignInst *, 2> CoroAligns;
SmallVector<AnyCoroSuspendInst *, 4> CoroSuspends;
@@ -65,6 +66,7 @@ struct Shape {
void clear() {
CoroBegin = nullptr;
CoroEnds.clear();
+ CoroWheres.clear();
CoroSizes.clear();
CoroAligns.clear();
CoroSuspends.clear();
diff --git a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
index c00e9c7bbee06..65b5a6fc18c0f 100644
--- a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
@@ -75,8 +75,8 @@ bool Lowerer::lower(Function &F) {
case Intrinsic::coro_subfn_addr:
lowerSubFn(Builder, cast<CoroSubFnInst>(II));
break;
- case Intrinsic::coro_end:
case Intrinsic::coro_suspend_retcon:
+ case Intrinsic::coro_where:
if (IsPrivateAndUnprocessed) {
II->replaceAllUsesWith(PoisonValue::get(II->getType()));
} else
diff --git a/llvm/lib/Transforms/Coroutines/CoroCloner.h b/llvm/lib/Transforms/Coroutines/CoroCloner.h
index d1887980fb3bc..78de08879c99e 100644
--- a/llvm/lib/Transforms/Coroutines/CoroCloner.h
+++ b/llvm/lib/Transforms/Coroutines/CoroCloner.h
@@ -120,6 +120,7 @@ class BaseCloner {
void replaceRetconOrAsyncSuspendUses();
void replaceCoroSuspends();
void replaceCoroEnds();
+ void replaceCoroWhere();
void replaceSwiftErrorOps();
void salvageDebugInfo();
void handleFinalSuspend();
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 180ac9c61e7df..5961cbf726f1a 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -388,10 +388,6 @@ static void replaceCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape,
replaceUnwindCoroEnd(End, Shape, FramePtr, InResume, CG);
else
replaceFallthroughCoroEnd(End, Shape, FramePtr, InResume, CG);
-
- auto &Context = End->getContext();
- End->replaceAllUsesWith(InResume ? ConstantInt::getTrue(Context)
- : ConstantInt::getFalse(Context));
End->eraseFromParent();
}
@@ -562,6 +558,15 @@ void coro::BaseCloner::replaceCoroEnds() {
}
}
+void coro::BaseCloner::replaceCoroWhere() {
+ auto &Ctx = OrigF.getContext();
+ for (auto *CW : Shape.CoroWheres) {
+ auto *NewCW = cast<CoroWhereInst>(VMap[CW]);
+ NewCW->replaceAllUsesWith(ConstantInt::getTrue(Ctx));
+ NewCW->eraseFromParent();
+ }
+}
+
static void replaceSwiftErrorOps(Function &F, coro::Shape &Shape,
ValueToValueMapTy *VMap) {
if (Shape.ABI == coro::ABI::Async && Shape.CoroSuspends.empty())
@@ -1077,6 +1082,8 @@ void coro::BaseCloner::create() {
// Remove coro.end intrinsics.
replaceCoroEnds();
+ replaceCoroWhere();
+
// Salvage debug info that points into the coroutine frame.
salvageDebugInfo();
}
@@ -1951,11 +1958,16 @@ static void removeCoroEndsFromRampFunction(const coro::Shape &Shape) {
replaceCoroEnd(End, Shape, Shape.FramePtr, /*in resume*/ false, nullptr);
}
} else {
- for (llvm::AnyCoroEndInst *End : Shape.CoroEnds) {
- auto &Context = End->getContext();
- End->replaceAllUsesWith(ConstantInt::getFalse(Context));
+ for (llvm::AnyCoroEndInst *End : Shape.CoroEnds)
End->eraseFromParent();
- }
+ }
+}
+
+static void removeCoroWhereFromRampFunction(const coro::Shape &Shape) {
+ for (auto *CW : Shape.CoroWheres) {
+ auto &Ctx = CW->getContext();
+ CW->replaceAllUsesWith(ConstantInt::getFalse(Ctx));
+ CW->eraseFromParent();
}
}
@@ -2020,6 +2032,7 @@ static void doSplitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones,
coro::salvageDebugInfo(ArgToAllocaMap, *DVR, false /*UseEntryValue*/);
removeCoroEndsFromRampFunction(Shape);
+ removeCoroWhereFromRampFunction(Shape);
if (shouldCreateNoAllocVariant)
SwitchCoroutineSplitter::createNoAllocVariant(F, Shape, Clones);
diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
index ac93f748ce65c..7c3cbe62ab7b1 100644
--- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp
+++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
@@ -93,6 +93,7 @@ static Intrinsic::ID NonOverloadedCoroIntrinsics[] = {
Intrinsic::coro_save,
Intrinsic::coro_subfn_addr,
Intrinsic::coro_suspend,
+ Intrinsic::coro_where,
};
bool coro::isSuspendBlock(BasicBlock *BB) {
@@ -275,6 +276,9 @@ void coro::Shape::analyze(Function &F,
}
}
break;
+ case Intrinsic::coro_where:
+ CoroWheres.push_back(cast<CoroWhereInst>(II));
+ break;
case Intrinsic::coro_promise:
assert(CoroPromise == nullptr &&
"CoroEarly must ensure coro.promise unique");
diff --git a/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll b/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll
index eed93cf0df8ef..e2eb4f6e7b9e9 100644
--- a/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll
+++ b/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll
@@ -62,7 +62,7 @@ define ptr @test1_tls_noopt(ptr %coro, ptr %param) presplitcoroutine {
; CHECK-NEXT: store i32 [[V]], ptr [[PARAM]], align 4
; CHECK-NEXT: ret ptr [[CORO]]
; CHECK: suspend:
-; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.coro.end(ptr [[CORO]], i1 false, token none)
+; CHECK-NEXT: call void @llvm.coro.end(ptr [[CORO]], i1 false, token none)
; CHECK-NEXT: ret ptr [[CORO]]
;
entry:
@@ -79,7 +79,7 @@ resume:
ret ptr %coro
suspend:
- call i1 @llvm.coro.end(ptr %coro, i1 0, token none)
+ call void @llvm.coro.end(ptr %coro, i1 0, token none)
ret ptr %coro
}
diff --git a/llvm/test/Assembler/auto_upgrade_intrinsics.ll b/llvm/test/Assembler/auto_upgrade_intrinsics.ll
index 37cb49650f6bd..64d4a3ba7c802 100644
--- a/llvm/test/Assembler/auto_upgrade_intrinsics.ll
+++ b/llvm/test/Assembler/auto_upgrade_intrinsics.ll
@@ -47,11 +47,11 @@ entry:
ret void
}
-declare i1 @llvm.coro.end(ptr, i1)
+declare void @llvm.coro.end(ptr, i1)
define void @test.coro.end(ptr %ptr) {
; CHECK-LABEL: @test.coro.end(
-; CHECK: call i1 @llvm.coro.end(ptr %ptr, i1 false, token none)
- call i1 @llvm.coro.end(ptr %ptr, i1 false)
+; CHECK: call void @llvm.coro.end(ptr %ptr, i1 false, token none)
+ call void @llvm.coro.end(ptr %ptr, i1 false)
ret void
}
diff --git a/llvm/test/Transforms/Coroutines/ArgAddr.ll b/llvm/test/Transforms/Coroutines/ArgAddr.ll
index ab70836508101..9328c67459077 100644
--- a/llvm/test/Transforms/Coroutines/ArgAddr.ll
+++ b/llvm/test/Transforms/Coroutines/ArgAddr.ll
@@ -45,7 +45,7 @@ coro_Cleanup:
br label %coro_Suspend
coro_Suspend:
- call i1 @llvm.coro.end(ptr null, i1 false, token none)
+ call void @llvm.coro.end(ptr null, i1 false, token none)
ret ptr %1
}
@@ -69,7 +69,7 @@ declare i32 @llvm.coro.size.i32()
declare ptr @llvm.coro.begin(token, ptr)
declare i8 @llvm.coro.suspend(token, i1)
declare ptr @llvm.coro.free(token, ptr)
-declare i1 @llvm.coro.end(ptr, i1, token)
+declare void @llvm.coro.end(ptr, i1, token)
declare void @llvm.coro.resume(ptr)
declare void @llvm.coro.destroy(ptr)
diff --git a/llvm/test/Transforms/Coroutines/coro-align16.ll b/llvm/test/Transforms/Coroutines/coro-align16.ll
index 39902be9149e8..afdca77e8af3e 100644
--- a/llvm/test/Transforms/Coroutines/coro-align16.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align16.ll
@@ -24,7 +24,7 @@ cleanup:
br label %suspend
suspend:
- call i1 @llvm.coro.end(ptr %hdl, i1 0, token none)
+ call void @llvm.coro.end(ptr %hdl, i1 0, token none)
ret ptr %hdl
}
@@ -44,7 +44,7 @@ declare void @llvm.coro.destroy(ptr)
declare token @llvm.coro.id(i32, ptr, ptr, ptr)
declare i1 @llvm.coro.alloc(token)
declare ptr @llvm.coro.begin(token, ptr)
-declare i1 @llvm.coro.end(ptr, i1, token)
+declare void @llvm.coro.end(ptr, i1, token)
declare void @capture_call(ptr)
declare void @nocapture_call(ptr nocapture)
diff --git a/llvm/test/Transforms/Coroutines/coro-align32.ll b/llvm/test/Transforms/Coroutines/coro-align32.ll
index 3d910e951259b..9e82ec83011f5 100644
--- a/llvm/test/Transforms/Coroutines/coro-align32.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align32.ll
@@ -28,7 +28,7 @@ cleanup...
[truncated]
|
@llvm/pr-subscribers-clang Author: Weibo He (NewSigma) ChangesAs mentioned in #151067, current design of Patch is 149.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/153404.diff 147 Files Affected:
diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp
index 827385f9c1a1f..cbc38516a0815 100644
--- a/clang/lib/CodeGen/CGCoroutine.cpp
+++ b/clang/lib/CodeGen/CGCoroutine.cpp
@@ -575,17 +575,19 @@ struct CallCoroEnd final : public EHScopeStack::Cleanup {
llvm::Function *CoroEndFn = CGM.getIntrinsic(llvm::Intrinsic::coro_end);
// See if we have a funclet bundle to associate coro.end with. (WinEH)
auto Bundles = getBundlesForCoroEnd(CGF);
- auto *CoroEnd =
- CGF.Builder.CreateCall(CoroEndFn,
- {NullPtr, CGF.Builder.getTrue(),
- llvm::ConstantTokenNone::get(CoroEndFn->getContext())},
- Bundles);
+ CGF.Builder.CreateCall(
+ CoroEndFn,
+ {NullPtr, CGF.Builder.getTrue(),
+ llvm::ConstantTokenNone::get(CoroEndFn->getContext())},
+ Bundles);
if (Bundles.empty()) {
// Otherwise, (landingpad model), create a conditional branch that leads
// either to a cleanup block or a block with EH resume instruction.
auto *ResumeBB = CGF.getEHResumeBlock(/*isCleanup=*/true);
auto *CleanupContBB = CGF.createBasicBlock("cleanup.cont");
- CGF.Builder.CreateCondBr(CoroEnd, ResumeBB, CleanupContBB);
+ auto *CoroWhereFn = CGM.getIntrinsic(llvm::Intrinsic::coro_where);
+ auto *CoroWhere = CGF.Builder.CreateCall(CoroWhereFn);
+ CGF.Builder.CreateCondBr(CoroWhere, ResumeBB, CleanupContBB);
CGF.EmitBlock(CleanupContBB);
}
}
diff --git a/clang/test/CodeGenCoroutines/coro-builtins.c b/clang/test/CodeGenCoroutines/coro-builtins.c
index 79f119b2b60ff..0c2553274f09f 100644
--- a/clang/test/CodeGenCoroutines/coro-builtins.c
+++ b/clang/test/CodeGenCoroutines/coro-builtins.c
@@ -37,7 +37,7 @@ void f(int n) {
// CHECK-NEXT: call ptr @llvm.coro.free(token %[[COROID]], ptr %[[FRAME]])
__builtin_coro_free(__builtin_coro_frame());
- // CHECK-NEXT: call i1 @llvm.coro.end(ptr %[[FRAME]], i1 false, token none)
+ // CHECK-NEXT: call void @llvm.coro.end(ptr %[[FRAME]], i1 false, token none)
__builtin_coro_end(__builtin_coro_frame(), 0);
// CHECK-NEXT: call i8 @llvm.coro.suspend(token none, i1 true)
diff --git a/clang/test/CodeGenCoroutines/coro-eh-cleanup.cpp b/clang/test/CodeGenCoroutines/coro-eh-cleanup.cpp
index 725cf8faa6b4c..d849ccef17681 100644
--- a/clang/test/CodeGenCoroutines/coro-eh-cleanup.cpp
+++ b/clang/test/CodeGenCoroutines/coro-eh-cleanup.cpp
@@ -60,7 +60,7 @@ coro_t f() {
// CHECK: [[COROENDBB]]:
// CHECK-NEXT: %[[CLPAD:.+]] = cleanuppad within none
-// CHECK-NEXT: call i1 @llvm.coro.end(ptr null, i1 true, token none) [ "funclet"(token %[[CLPAD]]) ]
+// CHECK-NEXT: call void @llvm.coro.end(ptr null, i1 true, token none) [ "funclet"(token %[[CLPAD]]) ]
// CHECK-NEXT: cleanupret from %[[CLPAD]] unwind label
// CHECK-LPAD: @_Z1fv(
@@ -76,7 +76,7 @@ coro_t f() {
// CHECK-LPAD: to label %{{.+}} unwind label %[[UNWINDBB:.+]]
// CHECK-LPAD: [[UNWINDBB]]:
-// CHECK-LPAD: %[[I1RESUME:.+]] = call i1 @llvm.coro.end(ptr null, i1 true, token none)
+// CHECK-LPAD: %[[I1RESUME:.+]] = call i1 @llvm.coro.where()
// CHECK-LPAD: br i1 %[[I1RESUME]], label %[[EHRESUME:.+]], label
// CHECK-LPAD: [[EHRESUME]]:
// CHECK-LPAD-NEXT: %[[exn:.+]] = load ptr, ptr %exn.slot, align 8
diff --git a/clang/test/CodeGenCoroutines/coro-lambda.cpp b/clang/test/CodeGenCoroutines/coro-lambda.cpp
index 26c51070f9e2d..b24a190ab41fb 100644
--- a/clang/test/CodeGenCoroutines/coro-lambda.cpp
+++ b/clang/test/CodeGenCoroutines/coro-lambda.cpp
@@ -55,4 +55,4 @@ void f() {
// CHECK: alloca %"struct.Task::promise_type"
// CHECK: call token @llvm.coro.id(
// CHECK: call i8 @llvm.coro.suspend(
-// CHECK: call i1 @llvm.coro.end(
+// CHECK: call void @llvm.coro.end(
diff --git a/clang/test/CodeGenCoroutines/coro-params.cpp b/clang/test/CodeGenCoroutines/coro-params.cpp
index 719726cca29c5..79e77a21017fa 100644
--- a/clang/test/CodeGenCoroutines/coro-params.cpp
+++ b/clang/test/CodeGenCoroutines/coro-params.cpp
@@ -117,7 +117,7 @@ void f(int val, MoveOnly moParam, MoveAndCopy mcParam, TrivialABI trivialParam)
// CHECK-NEXT: call ptr @llvm.coro.free(
// The original trivial_abi parameter is destroyed when returning from the ramp.
- // CHECK: call i1 @llvm.coro.end
+ // CHECK: call void @llvm.coro.end
// CHECK: call void @_ZN10TrivialABID1Ev(ptr {{[^,]*}} %[[TrivialAlloca]])
}
@@ -242,6 +242,6 @@ void msabi(MSParm p) {
co_return;
// The local alloca is used for the destructor call at the end of the ramp.
- // MSABI: call i1 @llvm.coro.end
+ // MSABI: call void @llvm.coro.end
// MSABI: call void @"??1MSParm@@QEAA@XZ"(ptr{{.*}} %[[ParamAlloca]])
}
diff --git a/llvm/docs/Coroutines.rst b/llvm/docs/Coroutines.rst
index dde73c9c3cc23..d9114eb1d1aa6 100644
--- a/llvm/docs/Coroutines.rst
+++ b/llvm/docs/Coroutines.rst
@@ -303,7 +303,7 @@ The LLVM IR for this coroutine looks like this:
call void @free(ptr %mem)
br label %suspend
suspend:
- %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none)
+ call void @llvm.coro.end(ptr %hdl, i1 false, token none)
ret ptr %hdl
}
@@ -637,7 +637,7 @@ store the current value produced by a coroutine.
call void @free(ptr %mem)
br label %suspend
suspend:
- %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none)
+ call void @llvm.coro.end(ptr %hdl, i1 false, token none)
ret ptr %hdl
}
@@ -806,7 +806,7 @@ The LLVM IR for a coroutine using a Coroutine with a custom ABI looks like:
call void @free(ptr %mem)
br label %suspend
suspend:
- %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none)
+ call void @llvm.coro.end(ptr %hdl, i1 false, token none)
ret ptr %hdl
}
@@ -1444,7 +1444,7 @@ A frontend should emit function attribute `presplitcoroutine` for the coroutine.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- declare i1 @llvm.coro.end(ptr <handle>, i1 <unwind>, token <result.token>)
+ declare void @llvm.coro.end(ptr <handle>, i1 <unwind>, token <result.token>)
Overview:
"""""""""
@@ -1502,7 +1502,8 @@ For landingpad based exception model, it is expected that frontend uses the
.. code-block:: llvm
ehcleanup:
- %InResumePart = call i1 @llvm.coro.end(ptr null, i1 true, token none)
+ call void @llvm.coro.end(ptr null, i1 true, token none)
+ %InResumePart = call i1 @llvm.coro.where()
br i1 %InResumePart, label %eh.resume, label %cleanup.cont
cleanup.cont:
@@ -1515,7 +1516,7 @@ For landingpad based exception model, it is expected that frontend uses the
%lpad.val29 = insertvalue { ptr, i32 } %lpad.val, i32 %sel, 1
resume { ptr, i32 } %lpad.val29
-The `CoroSpit` pass replaces `coro.end` with ``True`` in the resume functions,
+The `CoroSpit` pass replaces `coro.where` with ``True`` in the resume functions,
thus leading to immediate unwind to the caller, whereas in start function it
is replaced with ``False``, thus allowing to proceed to the rest of the cleanup
code that is only needed during initial invocation of the coroutine.
@@ -1527,7 +1528,7 @@ referring to an enclosing cleanuppad as follows:
ehcleanup:
%tok = cleanuppad within none []
- %unused = call i1 @llvm.coro.end(ptr null, i1 true, token none) [ "funclet"(token %tok) ]
+ call void @llvm.coro.end(ptr null, i1 true, token none) [ "funclet"(token %tok) ]
cleanupret from %tok unwind label %RestOfTheCleanup
The `CoroSplit` pass, if the funclet bundle is present, will insert
@@ -1592,7 +1593,7 @@ The number of arguments must match the return type of the continuation function:
cleanup:
%tok = call token (...) @llvm.coro.end.results(i8 %val)
- call i1 @llvm.coro.end(ptr %hdl, i1 0, token %tok)
+ call void @llvm.coro.end(ptr %hdl, i1 0, token %tok)
unreachable
...
@@ -1604,7 +1605,7 @@ The number of arguments must match the return type of the continuation function:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- declare i1 @llvm.coro.end.async(ptr <handle>, i1 <unwind>, ...)
+ declare void @llvm.coro.end.async(ptr <handle>, i1 <unwind>, ...)
Overview:
"""""""""
@@ -1635,10 +1636,10 @@ the function call.
.. code-block:: llvm
- call i1 (ptr, i1, ...) @llvm.coro.end.async(
- ptr %hdl, i1 0,
- ptr @must_tail_call_return,
- ptr %ctxt, ptr %task, ptr %actor)
+ call void (ptr, i1, ...) @llvm.coro.end.async(
+ ptr %hdl, i1 0,
+ ptr @must_tail_call_return,
+ ptr %ctxt, ptr %task, ptr %actor)
unreachable
.. _coro.suspend:
@@ -2117,6 +2118,30 @@ Example:
%hdl.result = ... ; get address of returned coroutine handle
ret ptr %hdl.result
+'llvm.coro.where' Intrinsic
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+::
+
+ declare i1 @llvm.coro.where()
+
+Overview:
+"""""""""
+
+The '``llvm.coro.where``' intrinsic returns a bool value that marks coroutine resume
+part and start part.
+
+Arguments:
+""""""""""
+
+None
+
+Semantics:
+""""""""""
+
+The `CoroSpit` pass replaces `coro.where` with ``True`` in the resume functions,
+whereas in start function it is replaced with ``False``, thus allowing the frontend
+separate resume part and start part.
+
Coroutine Transformation Passes
===============================
CoroEarly
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index e0ee12391b31d..0d113e0ccb854 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -1775,12 +1775,13 @@ def int_coro_free : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty],
[IntrReadMem, IntrArgMemOnly,
ReadOnly<ArgIndex<1>>,
NoCapture<ArgIndex<1>>]>;
-def int_coro_end : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_i1_ty, llvm_token_ty], []>;
+def int_coro_end : Intrinsic<[], [llvm_ptr_ty, llvm_i1_ty, llvm_token_ty], []>;
def int_coro_end_results : Intrinsic<[llvm_token_ty], [llvm_vararg_ty]>;
def int_coro_end_async
- : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_i1_ty, llvm_vararg_ty], []>;
+ : Intrinsic<[], [llvm_ptr_ty, llvm_i1_ty, llvm_vararg_ty], []>;
def int_coro_frame : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
+def int_coro_where : Intrinsic<[llvm_i1_ty], [], [IntrNoMem]>;
def int_coro_noop : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
def int_coro_size : Intrinsic<[llvm_anyint_ty], [], [IntrNoMem]>;
def int_coro_align : Intrinsic<[llvm_anyint_ty], [], [IntrNoMem]>;
diff --git a/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h b/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h
index 0688068167ae6..36ec76c554d50 100644
--- a/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h
+++ b/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h
@@ -428,6 +428,18 @@ class CoroFrameInst : public IntrinsicInst {
}
};
+/// This represents the llvm.coro.where instruction.
+class CoroWhereInst : public IntrinsicInst {
+public:
+ // Methods to support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::coro_where;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
/// This represents the llvm.coro.free instruction.
class CoroFreeInst : public IntrinsicInst {
enum { IdArg, FrameArg };
diff --git a/llvm/include/llvm/Transforms/Coroutines/CoroShape.h b/llvm/include/llvm/Transforms/Coroutines/CoroShape.h
index c54081de2d9da..83697200e061d 100644
--- a/llvm/include/llvm/Transforms/Coroutines/CoroShape.h
+++ b/llvm/include/llvm/Transforms/Coroutines/CoroShape.h
@@ -53,6 +53,7 @@ enum class ABI {
struct Shape {
CoroBeginInst *CoroBegin = nullptr;
SmallVector<AnyCoroEndInst *, 4> CoroEnds;
+ SmallVector<CoroWhereInst *, 2> CoroWheres;
SmallVector<CoroSizeInst *, 2> CoroSizes;
SmallVector<CoroAlignInst *, 2> CoroAligns;
SmallVector<AnyCoroSuspendInst *, 4> CoroSuspends;
@@ -65,6 +66,7 @@ struct Shape {
void clear() {
CoroBegin = nullptr;
CoroEnds.clear();
+ CoroWheres.clear();
CoroSizes.clear();
CoroAligns.clear();
CoroSuspends.clear();
diff --git a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
index c00e9c7bbee06..65b5a6fc18c0f 100644
--- a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
@@ -75,8 +75,8 @@ bool Lowerer::lower(Function &F) {
case Intrinsic::coro_subfn_addr:
lowerSubFn(Builder, cast<CoroSubFnInst>(II));
break;
- case Intrinsic::coro_end:
case Intrinsic::coro_suspend_retcon:
+ case Intrinsic::coro_where:
if (IsPrivateAndUnprocessed) {
II->replaceAllUsesWith(PoisonValue::get(II->getType()));
} else
diff --git a/llvm/lib/Transforms/Coroutines/CoroCloner.h b/llvm/lib/Transforms/Coroutines/CoroCloner.h
index d1887980fb3bc..78de08879c99e 100644
--- a/llvm/lib/Transforms/Coroutines/CoroCloner.h
+++ b/llvm/lib/Transforms/Coroutines/CoroCloner.h
@@ -120,6 +120,7 @@ class BaseCloner {
void replaceRetconOrAsyncSuspendUses();
void replaceCoroSuspends();
void replaceCoroEnds();
+ void replaceCoroWhere();
void replaceSwiftErrorOps();
void salvageDebugInfo();
void handleFinalSuspend();
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 180ac9c61e7df..5961cbf726f1a 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -388,10 +388,6 @@ static void replaceCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape,
replaceUnwindCoroEnd(End, Shape, FramePtr, InResume, CG);
else
replaceFallthroughCoroEnd(End, Shape, FramePtr, InResume, CG);
-
- auto &Context = End->getContext();
- End->replaceAllUsesWith(InResume ? ConstantInt::getTrue(Context)
- : ConstantInt::getFalse(Context));
End->eraseFromParent();
}
@@ -562,6 +558,15 @@ void coro::BaseCloner::replaceCoroEnds() {
}
}
+void coro::BaseCloner::replaceCoroWhere() {
+ auto &Ctx = OrigF.getContext();
+ for (auto *CW : Shape.CoroWheres) {
+ auto *NewCW = cast<CoroWhereInst>(VMap[CW]);
+ NewCW->replaceAllUsesWith(ConstantInt::getTrue(Ctx));
+ NewCW->eraseFromParent();
+ }
+}
+
static void replaceSwiftErrorOps(Function &F, coro::Shape &Shape,
ValueToValueMapTy *VMap) {
if (Shape.ABI == coro::ABI::Async && Shape.CoroSuspends.empty())
@@ -1077,6 +1082,8 @@ void coro::BaseCloner::create() {
// Remove coro.end intrinsics.
replaceCoroEnds();
+ replaceCoroWhere();
+
// Salvage debug info that points into the coroutine frame.
salvageDebugInfo();
}
@@ -1951,11 +1958,16 @@ static void removeCoroEndsFromRampFunction(const coro::Shape &Shape) {
replaceCoroEnd(End, Shape, Shape.FramePtr, /*in resume*/ false, nullptr);
}
} else {
- for (llvm::AnyCoroEndInst *End : Shape.CoroEnds) {
- auto &Context = End->getContext();
- End->replaceAllUsesWith(ConstantInt::getFalse(Context));
+ for (llvm::AnyCoroEndInst *End : Shape.CoroEnds)
End->eraseFromParent();
- }
+ }
+}
+
+static void removeCoroWhereFromRampFunction(const coro::Shape &Shape) {
+ for (auto *CW : Shape.CoroWheres) {
+ auto &Ctx = CW->getContext();
+ CW->replaceAllUsesWith(ConstantInt::getFalse(Ctx));
+ CW->eraseFromParent();
}
}
@@ -2020,6 +2032,7 @@ static void doSplitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones,
coro::salvageDebugInfo(ArgToAllocaMap, *DVR, false /*UseEntryValue*/);
removeCoroEndsFromRampFunction(Shape);
+ removeCoroWhereFromRampFunction(Shape);
if (shouldCreateNoAllocVariant)
SwitchCoroutineSplitter::createNoAllocVariant(F, Shape, Clones);
diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
index ac93f748ce65c..7c3cbe62ab7b1 100644
--- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp
+++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
@@ -93,6 +93,7 @@ static Intrinsic::ID NonOverloadedCoroIntrinsics[] = {
Intrinsic::coro_save,
Intrinsic::coro_subfn_addr,
Intrinsic::coro_suspend,
+ Intrinsic::coro_where,
};
bool coro::isSuspendBlock(BasicBlock *BB) {
@@ -275,6 +276,9 @@ void coro::Shape::analyze(Function &F,
}
}
break;
+ case Intrinsic::coro_where:
+ CoroWheres.push_back(cast<CoroWhereInst>(II));
+ break;
case Intrinsic::coro_promise:
assert(CoroPromise == nullptr &&
"CoroEarly must ensure coro.promise unique");
diff --git a/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll b/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll
index eed93cf0df8ef..e2eb4f6e7b9e9 100644
--- a/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll
+++ b/llvm/test/Analysis/GlobalsModRef/nonescaping-noalias.ll
@@ -62,7 +62,7 @@ define ptr @test1_tls_noopt(ptr %coro, ptr %param) presplitcoroutine {
; CHECK-NEXT: store i32 [[V]], ptr [[PARAM]], align 4
; CHECK-NEXT: ret ptr [[CORO]]
; CHECK: suspend:
-; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.coro.end(ptr [[CORO]], i1 false, token none)
+; CHECK-NEXT: call void @llvm.coro.end(ptr [[CORO]], i1 false, token none)
; CHECK-NEXT: ret ptr [[CORO]]
;
entry:
@@ -79,7 +79,7 @@ resume:
ret ptr %coro
suspend:
- call i1 @llvm.coro.end(ptr %coro, i1 0, token none)
+ call void @llvm.coro.end(ptr %coro, i1 0, token none)
ret ptr %coro
}
diff --git a/llvm/test/Assembler/auto_upgrade_intrinsics.ll b/llvm/test/Assembler/auto_upgrade_intrinsics.ll
index 37cb49650f6bd..64d4a3ba7c802 100644
--- a/llvm/test/Assembler/auto_upgrade_intrinsics.ll
+++ b/llvm/test/Assembler/auto_upgrade_intrinsics.ll
@@ -47,11 +47,11 @@ entry:
ret void
}
-declare i1 @llvm.coro.end(ptr, i1)
+declare void @llvm.coro.end(ptr, i1)
define void @test.coro.end(ptr %ptr) {
; CHECK-LABEL: @test.coro.end(
-; CHECK: call i1 @llvm.coro.end(ptr %ptr, i1 false, token none)
- call i1 @llvm.coro.end(ptr %ptr, i1 false)
+; CHECK: call void @llvm.coro.end(ptr %ptr, i1 false, token none)
+ call void @llvm.coro.end(ptr %ptr, i1 false)
ret void
}
diff --git a/llvm/test/Transforms/Coroutines/ArgAddr.ll b/llvm/test/Transforms/Coroutines/ArgAddr.ll
index ab70836508101..9328c67459077 100644
--- a/llvm/test/Transforms/Coroutines/ArgAddr.ll
+++ b/llvm/test/Transforms/Coroutines/ArgAddr.ll
@@ -45,7 +45,7 @@ coro_Cleanup:
br label %coro_Suspend
coro_Suspend:
- call i1 @llvm.coro.end(ptr null, i1 false, token none)
+ call void @llvm.coro.end(ptr null, i1 false, token none)
ret ptr %1
}
@@ -69,7 +69,7 @@ declare i32 @llvm.coro.size.i32()
declare ptr @llvm.coro.begin(token, ptr)
declare i8 @llvm.coro.suspend(token, i1)
declare ptr @llvm.coro.free(token, ptr)
-declare i1 @llvm.coro.end(ptr, i1, token)
+declare void @llvm.coro.end(ptr, i1, token)
declare void @llvm.coro.resume(ptr)
declare void @llvm.coro.destroy(ptr)
diff --git a/llvm/test/Transforms/Coroutines/coro-align16.ll b/llvm/test/Transforms/Coroutines/coro-align16.ll
index 39902be9149e8..afdca77e8af3e 100644
--- a/llvm/test/Transforms/Coroutines/coro-align16.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align16.ll
@@ -24,7 +24,7 @@ cleanup:
br label %suspend
suspend:
- call i1 @llvm.coro.end(ptr %hdl, i1 0, token none)
+ call void @llvm.coro.end(ptr %hdl, i1 0, token none)
ret ptr %hdl
}
@@ -44,7 +44,7 @@ declare void @llvm.coro.destroy(ptr)
declare token @llvm.coro.id(i32, ptr, ptr, ptr)
declare i1 @llvm.coro.alloc(token)
declare ptr @llvm.coro.begin(token, ptr)
-declare i1 @llvm.coro.end(ptr, i1, token)
+declare void @llvm.coro.end(ptr, i1, token)
declare void @capture_call(ptr)
declare void @nocapture_call(ptr nocapture)
diff --git a/llvm/test/Transforms/Coroutines/coro-align32.ll b/llvm/test/Transforms/Coroutines/coro-align32.ll
index 3d910e951259b..9e82ec83011f5 100644
--- a/llvm/test/Transforms/Coroutines/coro-align32.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align32.ll
@@ -28,7 +28,7 @@ cleanup...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did a quick scanning. It looks good generally.
As mentioned in #151067, current design of
llvm.coro.end
mixes two functionalities: querying where we are and lowering to some code. This patch separate these functionalities into independent intrinsics by introducing a new intrinsicllvm.coro.is_in_ramp
.