From 88f5aedc212a73601678cd8ec0ffde6c53f8ce03 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Fri, 8 Sep 2023 12:32:06 -0700 Subject: [PATCH 1/2] Update coroutine intrinsics documentation and few remaining tests to opaque pointers (#65698) --- llvm/docs/Coroutines.rst | 284 +++++++++--------- .../Transforms/Coroutines/coro-async-remat.ll | 38 +-- .../Coroutines/coro-retcon-opaque-ptr.ll | 16 +- .../Coroutines/coro-retcon-remat.ll | 22 +- .../Coroutines/coro-spill-corobegin.ll | 2 +- .../Coroutines/coro-spill-promise-02.ll | 12 +- 6 files changed, 184 insertions(+), 190 deletions(-) diff --git a/llvm/docs/Coroutines.rst b/llvm/docs/Coroutines.rst index 46dc2dcbee182..7befa8a32a8ee 100644 --- a/llvm/docs/Coroutines.rst +++ b/llvm/docs/Coroutines.rst @@ -29,10 +29,10 @@ then destroy it: define i32 @main() { entry: - %hdl = call i8* @f(i32 4) - call void @llvm.coro.resume(i8* %hdl) - call void @llvm.coro.resume(i8* %hdl) - call void @llvm.coro.destroy(i8* %hdl) + %hdl = call ptr @f(i32 4) + call void @llvm.coro.resume(ptr %hdl) + call void @llvm.coro.resume(ptr %hdl) + call void @llvm.coro.destroy(ptr %hdl) ret i32 0 } @@ -187,7 +187,7 @@ coroutine. Therefore an async coroutine returns `void`. .. code-block:: llvm - define swiftcc void @async_coroutine(i8* %async.ctxt, i8*, i8*) { + define swiftcc void @async_coroutine(ptr %async.ctxt, ptr, ptr) { } Values live across a suspend point need to be stored in the coroutine frame to @@ -217,10 +217,10 @@ a parameter to the `llvm.coro.suspend.async` intrinsic. .. code-block:: llvm - %resume_func_ptr = call i8* @llvm.coro.async.resume() - call {i8*, i8*, i8*} (i8*, i8*, ...) @llvm.coro.suspend.async( - i8* %resume_func_ptr, - i8* %context_projection_function + %resume_func_ptr = call ptr @llvm.coro.async.resume() + call {ptr, ptr, ptr} (ptr, ptr, ...) @llvm.coro.suspend.async( + ptr %resume_func_ptr, + ptr %context_projection_function The frontend should provide a `async function pointer` struct associated with each async coroutine by `llvm.coro.id.async`'s argument. The initial size and @@ -250,11 +250,11 @@ the async coroutine. .. code-block:: llvm - call {i8*, i8*, i8*} (i8*, i8*, ...) @llvm.coro.suspend.async( - i8* %resume_func_ptr, - i8* %context_projection_function, - i8* (bitcast void (i8*, i8*, i8*)* to i8*) %suspend_function, - i8* %arg1, i8* %arg2, i8 %arg3) + call {ptr, ptr, ptr} (ptr, ptr, ...) @llvm.coro.suspend.async( + ptr %resume_func_ptr, + ptr %context_projection_function, + ptr %suspend_function, + ptr %arg1, ptr %arg2, i8 %arg3) Coroutines by Example ===================== @@ -285,12 +285,12 @@ The LLVM IR for this coroutine looks like this: .. code-block:: llvm - define i8* @f(i32 %n) presplitcoroutine { + define ptr @f(i32 %n) presplitcoroutine { entry: - %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) + %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) %size = call i32 @llvm.coro.size.i32() - %alloc = call i8* @malloc(i32 %size) - %hdl = call noalias i8* @llvm.coro.begin(token %id, i8* %alloc) + %alloc = call ptr @malloc(i32 %size) + %hdl = call noalias ptr @llvm.coro.begin(token %id, ptr %alloc) br label %loop loop: %n.val = phi i32 [ %n, %entry ], [ %inc, %loop ] @@ -300,12 +300,12 @@ The LLVM IR for this coroutine looks like this: switch i8 %0, label %suspend [i8 0, label %loop i8 1, label %cleanup] cleanup: - %mem = call i8* @llvm.coro.free(token %id, i8* %hdl) - call void @free(i8* %mem) + %mem = call ptr @llvm.coro.free(token %id, ptr %hdl) + call void @free(ptr %mem) br label %suspend suspend: - %unused = call i1 @llvm.coro.end(i8* %hdl, i1 false) - ret i8* %hdl + %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false) + ret ptr %hdl } The `entry` block establishes the coroutine frame. The `coro.size`_ intrinsic is @@ -352,7 +352,7 @@ example, the coroutine frame will be: .. code-block:: llvm - %f.frame = type { void (%f.frame*)*, void (%f.frame*)*, i32 } + %f.frame = type { ptr, ptr, i32 } After resume and destroy parts are outlined, function `f` will contain only the code responsible for creation and initialization of the coroutine frame and @@ -360,35 +360,34 @@ execution of the coroutine until a suspend point is reached: .. code-block:: llvm - define i8* @f(i32 %n) { + define ptr @f(i32 %n) { entry: - %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) - %alloc = call noalias i8* @malloc(i32 24) - %0 = call noalias i8* @llvm.coro.begin(token %id, i8* %alloc) - %frame = bitcast i8* %0 to %f.frame* - %1 = getelementptr %f.frame, %f.frame* %frame, i32 0, i32 0 - store void (%f.frame*)* @f.resume, void (%f.frame*)** %1 - %2 = getelementptr %f.frame, %f.frame* %frame, i32 0, i32 1 - store void (%f.frame*)* @f.destroy, void (%f.frame*)** %2 + %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) + %alloc = call noalias ptr @malloc(i32 24) + %frame = call noalias ptr @llvm.coro.begin(token %id, ptr %alloc) + %1 = getelementptr %f.frame, ptr %frame, i32 0, i32 0 + store ptr @f.resume, ptr %1 + %2 = getelementptr %f.frame, ptr %frame, i32 0, i32 1 + store ptr @f.destroy, ptr %2 %inc = add nsw i32 %n, 1 - %inc.spill.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32 0, i32 2 - store i32 %inc, i32* %inc.spill.addr + %inc.spill.addr = getelementptr inbounds %f.Frame, ptr %FramePtr, i32 0, i32 2 + store i32 %inc, ptr %inc.spill.addr call void @print(i32 %n) - ret i8* %frame + ret ptr %frame } Outlined resume part of the coroutine will reside in function `f.resume`: .. code-block:: llvm - define internal fastcc void @f.resume(%f.frame* %frame.ptr.resume) { + define internal fastcc void @f.resume(ptr %frame.ptr.resume) { entry: - %inc.spill.addr = getelementptr %f.frame, %f.frame* %frame.ptr.resume, i64 0, i32 2 - %inc.spill = load i32, i32* %inc.spill.addr, align 4 + %inc.spill.addr = getelementptr %f.frame, ptr %frame.ptr.resume, i64 0, i32 2 + %inc.spill = load i32, ptr %inc.spill.addr, align 4 %inc = add i32 %n.val, 1 - store i32 %inc, i32* %inc.spill.addr, align 4 + store i32 %inc, ptr %inc.spill.addr, align 4 tail call void @print(i32 %inc) ret void } @@ -397,10 +396,9 @@ Whereas function `f.destroy` will contain the cleanup code for the coroutine: .. code-block:: llvm - define internal fastcc void @f.destroy(%f.frame* %frame.ptr.destroy) { + define internal fastcc void @f.destroy(ptr %frame.ptr.destroy) { entry: - %0 = bitcast %f.frame* %frame.ptr.destroy to i8* - tail call void @free(i8* %0) + tail call void @free(ptr %frame.ptr.destroy) ret void } @@ -421,16 +419,16 @@ elided. .. code-block:: llvm entry: - %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) + %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id) br i1 %need.dyn.alloc, label %dyn.alloc, label %coro.begin dyn.alloc: %size = call i32 @llvm.coro.size.i32() - %alloc = call i8* @CustomAlloc(i32 %size) + %alloc = call ptr @CustomAlloc(i32 %size) br label %coro.begin coro.begin: - %phi = phi i8* [ null, %entry ], [ %alloc, %dyn.alloc ] - %hdl = call noalias i8* @llvm.coro.begin(token %id, i8* %phi) + %phi = phi ptr [ null, %entry ], [ %alloc, %dyn.alloc ] + %hdl = call noalias ptr @llvm.coro.begin(token %id, ptr %phi) In the cleanup block, we will make freeing the coroutine frame conditional on `coro.free`_ intrinsic. If allocation is elided, `coro.free`_ returns `null` @@ -439,11 +437,11 @@ thus skipping the deallocation code: .. code-block:: llvm cleanup: - %mem = call i8* @llvm.coro.free(token %id, i8* %hdl) - %need.dyn.free = icmp ne i8* %mem, null + %mem = call ptr @llvm.coro.free(token %id, ptr %hdl) + %need.dyn.free = icmp ne ptr %mem, null br i1 %need.dyn.free, label %dyn.free, label %if.end dyn.free: - call void @CustomFree(i8* %mem) + call void @CustomFree(ptr %mem) br label %if.end if.end: ... @@ -503,13 +501,13 @@ as follows: .. code-block:: llvm - define internal fastcc void @f.Resume(%f.Frame* %FramePtr) { + define internal fastcc void @f.Resume(ptr %FramePtr) { entry.Resume: - %index.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i64 0, i32 2 - %index = load i8, i8* %index.addr, align 1 + %index.addr = getelementptr inbounds %f.Frame, ptr %FramePtr, i64 0, i32 2 + %index = load i8, ptr %index.addr, align 1 %switch = icmp eq i8 %index, 0 - %n.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i64 0, i32 3 - %n = load i32, i32* %n.addr, align 4 + %n.addr = getelementptr inbounds %f.Frame, ptr %FramePtr, i64 0, i32 3 + %n = load i32, ptr %n.addr, align 4 br i1 %switch, label %loop.resume, label %loop loop.resume: @@ -518,13 +516,13 @@ as follows: br label %suspend loop: %inc = add nsw i32 %n, 1 - store i32 %inc, i32* %n.addr, align 4 + store i32 %inc, ptr %n.addr, align 4 tail call void @print(i32 %inc) br label %suspend suspend: %storemerge = phi i8 [ 0, %loop ], [ 1, %loop.resume ] - store i8 %storemerge, i8* %index.addr, align 1 + store i8 %storemerge, ptr %index.addr, align 1 ret void } @@ -580,14 +578,14 @@ correct resume point): .. code-block:: llvm if.true: - %save1 = call token @llvm.coro.save(i8* %hdl) - call void @async_op1(i8* %hdl) + %save1 = call token @llvm.coro.save(ptr %hdl) + call void @async_op1(ptr %hdl) %suspend1 = call i1 @llvm.coro.suspend(token %save1, i1 false) switch i8 %suspend1, label %suspend [i8 0, label %resume1 i8 1, label %cleanup] if.false: - %save2 = call token @llvm.coro.save(i8* %hdl) - call void @async_op2(i8* %hdl) + %save2 = call token @llvm.coro.save(ptr %hdl) + call void @async_op2(ptr %hdl) %suspend2 = call i1 @llvm.coro.suspend(token %save2, i1 false) switch i8 %suspend1, label %suspend [i8 0, label %resume2 i8 1, label %cleanup] @@ -607,35 +605,34 @@ store the current value produced by a coroutine. .. code-block:: llvm - define i8* @f(i32 %n) { + define ptr @f(i32 %n) { entry: %promise = alloca i32 - %pv = bitcast i32* %promise to i8* - %id = call token @llvm.coro.id(i32 0, i8* %pv, i8* null, i8* null) + %id = call token @llvm.coro.id(i32 0, ptr %promise, ptr null, ptr null) %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id) br i1 %need.dyn.alloc, label %dyn.alloc, label %coro.begin dyn.alloc: %size = call i32 @llvm.coro.size.i32() - %alloc = call i8* @malloc(i32 %size) + %alloc = call ptr @malloc(i32 %size) br label %coro.begin coro.begin: - %phi = phi i8* [ null, %entry ], [ %alloc, %dyn.alloc ] - %hdl = call noalias i8* @llvm.coro.begin(token %id, i8* %phi) + %phi = phi ptr [ null, %entry ], [ %alloc, %dyn.alloc ] + %hdl = call noalias ptr @llvm.coro.begin(token %id, ptr %phi) br label %loop loop: %n.val = phi i32 [ %n, %coro.begin ], [ %inc, %loop ] %inc = add nsw i32 %n.val, 1 - store i32 %n.val, i32* %promise + store i32 %n.val, ptr %promise %0 = call i8 @llvm.coro.suspend(token none, i1 false) switch i8 %0, label %suspend [i8 0, label %loop i8 1, label %cleanup] cleanup: - %mem = call i8* @llvm.coro.free(token %id, i8* %hdl) - call void @free(i8* %mem) + %mem = call ptr @llvm.coro.free(token %id, ptr %hdl) + call void @free(ptr %mem) br label %suspend suspend: - %unused = call i1 @llvm.coro.end(i8* %hdl, i1 false) - ret i8* %hdl + %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false) + ret ptr %hdl } A coroutine consumer can rely on the `coro.promise`_ intrinsic to access the @@ -645,18 +642,17 @@ coroutine promise. define i32 @main() { entry: - %hdl = call i8* @f(i32 4) - %promise.addr.raw = call i8* @llvm.coro.promise(i8* %hdl, i32 4, i1 false) - %promise.addr = bitcast i8* %promise.addr.raw to i32* - %val0 = load i32, i32* %promise.addr + %hdl = call ptr @f(i32 4) + %promise.addr = call ptr @llvm.coro.promise(ptr %hdl, i32 4, i1 false) + %val0 = load i32, ptr %promise.addr call void @print(i32 %val0) - call void @llvm.coro.resume(i8* %hdl) - %val1 = load i32, i32* %promise.addr + call void @llvm.coro.resume(ptr %hdl) + %val1 = load i32, ptr %promise.addr call void @print(i32 %val1) - call void @llvm.coro.resume(i8* %hdl) - %val2 = load i32, i32* %promise.addr + call void @llvm.coro.resume(ptr %hdl) + %val2 = load i32, ptr %promise.addr call void @print(i32 %val2) - call void @llvm.coro.destroy(i8* %hdl) + call void @llvm.coro.destroy(ptr %hdl) ret i32 0 } @@ -702,14 +698,14 @@ destroyed: define i32 @main() { entry: - %hdl = call i8* @f(i32 4) + %hdl = call ptr @f(i32 4) br label %while while: - call void @llvm.coro.resume(i8* %hdl) - %done = call i1 @llvm.coro.done(i8* %hdl) + call void @llvm.coro.resume(ptr %hdl) + %done = call i1 @llvm.coro.done(ptr %hdl) br i1 %done, label %end, label %while end: - call void @llvm.coro.destroy(i8* %hdl) + call void @llvm.coro.destroy(ptr %hdl) ret i32 0 } @@ -769,7 +765,7 @@ Syntax: :: - declare void @llvm.coro.destroy(i8* ) + declare void @llvm.coro.destroy(ptr ) Overview: """"""""" @@ -797,7 +793,7 @@ frame. Destroying a coroutine that is not suspended leads to undefined behavior. :: - declare void @llvm.coro.resume(i8* ) + declare void @llvm.coro.resume(ptr ) Overview: """"""""" @@ -824,7 +820,7 @@ Resuming a coroutine that is not suspended leads to undefined behavior. :: - declare i1 @llvm.coro.done(i8* ) + declare i1 @llvm.coro.done(ptr ) Overview: """"""""" @@ -850,7 +846,7 @@ or on a coroutine that is not suspended leads to undefined behavior. :: - declare i8* @llvm.coro.promise(i8* , i32 , i1 ) + declare ptr @llvm.coro.promise(ptr , i32 , i1 ) Overview: """"""""" @@ -889,28 +885,26 @@ Example: .. code-block:: llvm - define i8* @f(i32 %n) { + define ptr @f(i32 %n) { entry: %promise = alloca i32 - %pv = bitcast i32* %promise to i8* ; the second argument to coro.id points to the coroutine promise. - %id = call token @llvm.coro.id(i32 0, i8* %pv, i8* null, i8* null) + %id = call token @llvm.coro.id(i32 0, ptr %promise, ptr null, ptr null) ... - %hdl = call noalias i8* @llvm.coro.begin(token %id, i8* %alloc) + %hdl = call noalias ptr @llvm.coro.begin(token %id, ptr %alloc) ... - store i32 42, i32* %promise ; store something into the promise + store i32 42, ptr %promise ; store something into the promise ... - ret i8* %hdl + ret ptr %hdl } define i32 @main() { entry: - %hdl = call i8* @f(i32 4) ; starts the coroutine and returns its handle - %promise.addr.raw = call i8* @llvm.coro.promise(i8* %hdl, i32 4, i1 false) - %promise.addr = bitcast i8* %promise.addr.raw to i32* - %val = load i32, i32* %promise.addr ; load a value from the promise + %hdl = call ptr @f(i32 4) ; starts the coroutine and returns its handle + %promise.addr = call ptr @llvm.coro.promise(ptr %hdl, i32 4, i1 false) + %val = load i32, ptr %promise.addr ; load a value from the promise call void @print(i32 %val) - call void @llvm.coro.destroy(i8* %hdl) + call void @llvm.coro.destroy(ptr %hdl) ret i32 0 } @@ -980,7 +974,7 @@ the coroutine frame. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare i8* @llvm.coro.begin(token , i8* ) + declare ptr @llvm.coro.begin(token , ptr ) Overview: """"""""" @@ -1014,7 +1008,7 @@ A frontend should emit exactly one `coro.begin` intrinsic per coroutine. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare i8* @llvm.coro.free(token %id, i8* ) + declare ptr @llvm.coro.free(token %id, ptr ) Overview: """"""""" @@ -1039,11 +1033,11 @@ Example (custom deallocation function): .. code-block:: llvm cleanup: - %mem = call i8* @llvm.coro.free(token %id, i8* %frame) - %mem_not_null = icmp ne i8* %mem, null + %mem = call ptr @llvm.coro.free(token %id, ptr %frame) + %mem_not_null = icmp ne ptr %mem, null br i1 %mem_not_null, label %if.then, label %if.end if.then: - call void @CustomFree(i8* %mem) + call void @CustomFree(ptr %mem) br label %if.end if.end: ret void @@ -1054,8 +1048,8 @@ Example (standard deallocation functions): .. code-block:: llvm cleanup: - %mem = call i8* @llvm.coro.free(token %id, i8* %frame) - call void @free(i8* %mem) + %mem = call ptr @llvm.coro.free(token %id, ptr %frame) + call void @free(ptr %mem) ret void .. _coro.alloc: @@ -1092,18 +1086,18 @@ Example: .. code-block:: llvm entry: - %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) + %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) %dyn.alloc.required = call i1 @llvm.coro.alloc(token %id) br i1 %dyn.alloc.required, label %coro.alloc, label %coro.begin coro.alloc: %frame.size = call i32 @llvm.coro.size() - %alloc = call i8* @MyAlloc(i32 %frame.size) + %alloc = call ptr @MyAlloc(i32 %frame.size) br label %coro.begin coro.begin: - %phi = phi i8* [ null, %entry ], [ %alloc, %coro.alloc ] - %frame = call i8* @llvm.coro.begin(token %id, i8* %phi) + %phi = phi ptr [ null, %entry ], [ %alloc, %coro.alloc ] + %frame = call ptr @llvm.coro.begin(token %id, ptr %phi) .. _coro.noop: @@ -1111,7 +1105,7 @@ Example: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare i8* @llvm.coro.noop() + declare ptr @llvm.coro.noop() Overview: """"""""" @@ -1137,7 +1131,7 @@ Note that in different translation units llvm.coro.noop may return different poi ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare i8* @llvm.coro.frame() + declare ptr @llvm.coro.frame() Overview: """"""""" @@ -1163,8 +1157,8 @@ coroutine frame. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare token @llvm.coro.id(i32 , i8* , i8* , - i8* ) + declare token @llvm.coro.id(i32 , ptr , ptr , + ptr ) Overview: """"""""" @@ -1177,7 +1171,7 @@ Arguments: The first argument provides information on the alignment of the memory returned by the allocation function and given to `coro.begin` by the first argument. If -this argument is 0, the memory is assumed to be aligned to 2 * sizeof(i8*). +this argument is 0, the memory is assumed to be aligned to 2 * sizeof(ptr). This argument only accepts constants. The second argument, if not `null`, designates a particular alloca instruction @@ -1210,8 +1204,8 @@ A frontend should emit function attribute `presplitcoroutine` for the coroutine. :: declare token @llvm.coro.id.async(i32 , i32 , - i8* , - i8* ) + ptr , + ptr ) Overview: """"""""" @@ -1250,9 +1244,9 @@ A frontend should emit function attribute `presplitcoroutine` for the coroutine. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare token @llvm.coro.id.retcon(i32 , i32 , i8* , - i8* , - i8* , i8* ) + declare token @llvm.coro.id.retcon(i32 , i32 , ptr , + ptr , + ptr , ptr ) Overview: """"""""" @@ -1305,9 +1299,9 @@ A frontend should emit function attribute `presplitcoroutine` for the coroutine. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare token @llvm.coro.id.retcon.once(i32 , i32 , i8* , - i8* , - i8* , i8* ) + declare token @llvm.coro.id.retcon.once(i32 , i32 , ptr , + ptr , + ptr , ptr ) Overview: """"""""" @@ -1333,7 +1327,7 @@ A frontend should emit function attribute `presplitcoroutine` for the coroutine. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare i1 @llvm.coro.end(i8* , i1 ) + declare i1 @llvm.coro.end(ptr , i1 ) Overview: """"""""" @@ -1385,18 +1379,18 @@ For landingpad based exception model, it is expected that frontend uses the .. code-block:: llvm ehcleanup: - %InResumePart = call i1 @llvm.coro.end(i8* null, i1 true) + %InResumePart = call i1 @llvm.coro.end(ptr null, i1 true) br i1 %InResumePart, label %eh.resume, label %cleanup.cont cleanup.cont: ; rest of the cleanup eh.resume: - %exn = load i8*, i8** %exn.slot, align 8 - %sel = load i32, i32* %ehselector.slot, align 4 - %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn, 0 - %lpad.val29 = insertvalue { i8*, i32 } %lpad.val, i32 %sel, 1 - resume { i8*, i32 } %lpad.val29 + %exn = load ptr, ptr %exn.slot, align 8 + %sel = load i32, ptr %ehselector.slot, align 4 + %lpad.val = insertvalue { ptr, i32 } undef, ptr %exn, 0 + %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, thus leading to immediate unwind to the caller, whereas in start function it @@ -1410,7 +1404,7 @@ referring to an enclosing cleanuppad as follows: ehcleanup: %tok = cleanuppad within none [] - %unused = call i1 @llvm.coro.end(i8* null, i1 true) [ "funclet"(token %tok) ] + %unused = call i1 @llvm.coro.end(ptr null, i1 true) [ "funclet"(token %tok) ] cleanupret from %tok unwind label %RestOfTheCleanup The `CoroSplit` pass, if the funclet bundle is present, will insert @@ -1440,7 +1434,7 @@ The following table summarizes the handling of `coro.end`_ intrinsic. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare i1 @llvm.coro.end.async(i8* , i1 , ...) + declare i1 @llvm.coro.end.async(ptr , i1 , ...) Overview: """"""""" @@ -1471,10 +1465,10 @@ the function call. .. code-block:: llvm - call i1 (i8*, i1, ...) @llvm.coro.end.async( - i8* %hdl, i1 0, - void (i8*, %async.task*, %async.actor*)* @must_tail_call_return, - i8* %ctxt, %async.task* %task, %async.actor* %actor) + call i1 (ptr, i1, ...) @llvm.coro.end.async( + ptr %hdl, i1 0, + ptr @must_tail_call_return, + ptr %ctxt, ptr %task, ptr %actor) unreachable .. _coro.suspend: @@ -1548,7 +1542,7 @@ unreachable and can perform optimizations that can take advantage of that fact. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare token @llvm.coro.save(i8* ) + declare token @llvm.coro.save(ptr ) Overview: """"""""" @@ -1585,8 +1579,8 @@ to the coroutine: .. code-block:: llvm - %save1 = call token @llvm.coro.save(i8* %hdl) - call void @async_op1(i8* %hdl) + %save1 = call token @llvm.coro.save(ptr %hdl) + call void @async_op1(ptr %hdl) %suspend1 = call i1 @llvm.coro.suspend(token %save1, i1 false) switch i8 %suspend1, label %suspend [i8 0, label %resume1 i8 1, label %cleanup] @@ -1597,9 +1591,9 @@ to the coroutine: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare {i8*, i8*, i8*} @llvm.coro.suspend.async( - i8* , - i8* , + declare {ptr, ptr, ptr} @llvm.coro.suspend.async( + ptr , + ptr , ... ... ) @@ -1618,7 +1612,7 @@ point. The second argument is the `context projection function`. It should describe how-to restore the `async context` in the continuation function from the first -argument of the continuation function. Its type is `i8* (i8*)`. +argument of the continuation function. Its type is `ptr (ptr)`. The third argument is the function that models transfer to the callee at the suspend point. It should take 3 arguments. Lowering will `musttail` call this @@ -1639,7 +1633,7 @@ called. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare i8* @llvm.coro.prepare.async(i8* ) + declare ptr @llvm.coro.prepare.async(ptr ) Overview: """"""""" @@ -1650,7 +1644,7 @@ async coroutine until after coroutine splitting. Arguments: """""""""" -The first argument should be an async coroutine of type `void (i8*, i8*, i8*)`. +The first argument should be an async coroutine of type `void (ptr, ptr, ptr)`. Lowering will replace this intrinsic with its coroutine function argument. .. _coro.suspend.retcon: diff --git a/llvm/test/Transforms/Coroutines/coro-async-remat.ll b/llvm/test/Transforms/Coroutines/coro-async-remat.ll index 60c045464093a..fd2a35c0c7f88 100644 --- a/llvm/test/Transforms/Coroutines/coro-async-remat.ll +++ b/llvm/test/Transforms/Coroutines/coro-async-remat.ll @@ -2,34 +2,34 @@ %async_func_ptr = type <{ i32, i32 }> %Tsq = type <{}> -%swift.context = type { %swift.context*, void (%swift.context*)*, i64 } +%swift.context = type { ptr, ptr, i64 } %swift.type = type { i64 } %FlatMapSeq = type <{}> %swift.error = type opaque %swift.opaque = type opaque -@repoTU = global %async_func_ptr <{ i32 trunc (i64 sub (i64 ptrtoint (void (%Tsq*, %swift.context*, %swift.type*, %FlatMapSeq*)* @repo to i64), i64 ptrtoint (%async_func_ptr* @repoTU to i64)) to i32), i32 20 }>, section "__TEXT,__const", align 8 +@repoTU = global %async_func_ptr <{ i32 trunc (i64 sub (i64 ptrtoint (ptr @repo to i64), i64 ptrtoint (ptr @repoTU to i64)) to i32), i32 20 }>, section "__TEXT,__const", align 8 ; Function Attrs: nounwind -declare token @llvm.coro.id.async(i32, i32, i32, i8*) #0 +declare token @llvm.coro.id.async(i32, i32, i32, ptr) #0 ; Function Attrs: nounwind -declare i8* @llvm.coro.begin(token, i8* writeonly) #0 +declare ptr @llvm.coro.begin(token, ptr writeonly) #0 ; Function Attrs: nounwind -declare i8* @llvm.coro.async.resume() #0 +declare ptr @llvm.coro.async.resume() #0 -define hidden i8* @__swift_async_resume_project_context(i8* %0) { +define hidden ptr @__swift_async_resume_project_context(ptr %0) { entry: - ret i8* undef + ret ptr undef } -define swifttailcc void @repo(%Tsq* %0, %swift.context* %1, %swift.type* %arg, %FlatMapSeq* %2) #1 { +define swifttailcc void @repo(ptr %0, ptr %1, ptr %arg, ptr %2) #1 { entry: - %swifterror = alloca swifterror %swift.error*, align 8 - %3 = call token @llvm.coro.id.async(i32 20, i32 16, i32 1, i8* bitcast (%async_func_ptr* @repoTU to i8*)) - %4 = call i8* @llvm.coro.begin(token %3, i8* null) - %5 = bitcast i8* undef to %swift.opaque* + %swifterror = alloca swifterror ptr, align 8 + %3 = call token @llvm.coro.id.async(i32 20, i32 16, i32 1, ptr @repoTU) + %4 = call ptr @llvm.coro.begin(token %3, ptr null) + %5 = bitcast ptr undef to ptr br label %6 6: ; preds = %21, %15, %entry @@ -39,11 +39,11 @@ entry: br i1 undef, label %8, label %16 8: ; preds = %7 - %initializeWithTake35 = bitcast i8* undef to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* - %9 = call %swift.opaque* %initializeWithTake35(%swift.opaque* noalias %5, %swift.opaque* noalias undef, %swift.type* undef) #0 - %10 = call i8* @llvm.coro.async.resume() - %11 = bitcast i8* %10 to void (%swift.context*)* - %12 = call { i8*, %swift.error* } (i32, i8*, i8*, ...) @llvm.coro.suspend.async.sl_p0i8p0s_swift.error.4.220.413.429.445.461.672.683ss(i32 256, i8* %10, i8* bitcast (i8* (i8*)* @__swift_async_resume_project_context to i8*), i8* bitcast (void (i8*, %Tsq*, %swift.context*, %swift.opaque*, %swift.type*, i8**)* @__swift_suspend_dispatch_5.23 to i8*), i8* undef, %Tsq* undef, %swift.context* undef, %swift.opaque* %5, %swift.type* undef, i8** undef) + %initializeWithTake35 = bitcast ptr undef to ptr + %9 = call ptr %initializeWithTake35(ptr noalias %5, ptr noalias undef, ptr undef) #0 + %10 = call ptr @llvm.coro.async.resume() + %11 = bitcast ptr %10 to ptr + %12 = call { ptr, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0i8p0s_swift.error.4.220.413.429.445.461.672.683ss(i32 256, ptr %10, ptr @__swift_async_resume_project_context, ptr @__swift_suspend_dispatch_5.23, ptr undef, ptr undef, ptr undef, ptr %5, ptr undef, ptr undef) br i1 undef, label %25, label %13 13: ; preds = %8 @@ -120,13 +120,13 @@ entry: ret void } -define dso_local swifttailcc void @__swift_suspend_dispatch_5.23(i8* %0, %Tsq* %1, %swift.context* %2, %swift.opaque* %3, %swift.type* %4, i8** %5) { +define dso_local swifttailcc void @__swift_suspend_dispatch_5.23(ptr %0, ptr %1, ptr %2, ptr %3, ptr %4, ptr %5) { entry: ret void } ; Function Attrs: nounwind -declare { i8*, %swift.error* } @llvm.coro.suspend.async.sl_p0i8p0s_swift.error.4.220.413.429.445.461.672.683ss(i32, i8*, i8*, ...) #0 +declare { ptr, ptr } @llvm.coro.suspend.async.sl_p0i8p0s_swift.error.4.220.413.429.445.461.672.683ss(i32, ptr, ptr, ...) #0 attributes #0 = { nounwind } attributes #1 = { "tune-cpu"="generic" } diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll b/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll index 868a9c4966756..559d3af024694 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll @@ -74,16 +74,16 @@ cleanup: ; preds = %loop unreachable } -declare token @llvm.coro.id.retcon(i32, i32, i8*, i8*, i8*, i8*) -declare i8* @llvm.coro.begin(token, i8*) +declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(i8*, i1) -declare i8* @llvm.coro.prepare.retcon(i8*) +declare i1 @llvm.coro.end(ptr, i1) +declare ptr @llvm.coro.prepare.retcon(ptr) -declare i8* @prototype(i8*, i1 zeroext) -declare {i8*,i8*} @g_prototype(i8*, i1 zeroext) +declare ptr @prototype(ptr, i1 zeroext) +declare {ptr,ptr} @g_prototype(ptr, i1 zeroext) -declare noalias i8* @allocate(i32 %size) -declare void @deallocate(i8* %ptr) +declare noalias ptr @allocate(i32 %size) +declare void @deallocate(ptr %ptr) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll b/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll index 584c4e0da87b7..70de163caff5d 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll @@ -4,10 +4,10 @@ ; CHECK: %f.Frame = type { i32 } -define { i8*, i32 } @f(i8* %buffer, i32 %n) { +define { ptr, i32 } @f(ptr %buffer, i32 %n) { entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, i8* %buffer, i8* bitcast ({ i8*, i32 } (i8*, i1)* @f_prototype to i8*), i8* bitcast (i8* (i32)* @allocate to i8*), i8* bitcast (void (i8*)* @deallocate to i8*)) - %hdl = call i8* @llvm.coro.begin(token %id, i8* null) + %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @f_prototype, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop loop: @@ -31,19 +31,19 @@ resume1: br label %loop cleanup: - call i1 @llvm.coro.end(i8* %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0) unreachable } -declare token @llvm.coro.id.retcon(i32, i32, i8*, i8*, i8*, i8*) -declare i8* @llvm.coro.begin(token, i8*) +declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(i8*, i1) -declare i8* @llvm.coro.prepare.retcon(i8*) +declare i1 @llvm.coro.end(ptr, i1) +declare ptr @llvm.coro.prepare.retcon(ptr) -declare { i8*, i32 } @f_prototype(i8*, i1 zeroext) +declare { ptr, i32 } @f_prototype(ptr, i1 zeroext) -declare noalias i8* @allocate(i32 %size) -declare void @deallocate(i8* %ptr) +declare noalias ptr @allocate(i32 %size) +declare void @deallocate(ptr %ptr) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll b/llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll index 7e19fd6b76d10..9653bd5b28eea 100644 --- a/llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll +++ b/llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll @@ -37,7 +37,7 @@ suspend: ret ptr %hdl } -; See if the i8* for coro.begin was added to f.Frame +; See if the ptr for coro.begin was added to f.Frame ; CHECK-LABEL: %f.Frame = type { ptr, ptr, ptr, i1 } ; See if the g's coro.begin was spilled into the frame diff --git a/llvm/test/Transforms/Coroutines/coro-spill-promise-02.ll b/llvm/test/Transforms/Coroutines/coro-spill-promise-02.ll index 5ea90d79ebc24..411067362825e 100644 --- a/llvm/test/Transforms/Coroutines/coro-spill-promise-02.ll +++ b/llvm/test/Transforms/Coroutines/coro-spill-promise-02.ll @@ -3,25 +3,25 @@ %"class.task::promise_type" = type { [64 x i8] } -declare void @consume(i32*) -declare void @consume2(%"class.task::promise_type"*) +declare void @consume(ptr) +declare void @consume2(ptr) define ptr @f() presplitcoroutine { entry: %data = alloca i32, align 4 %__promise = alloca %"class.task::promise_type", align 64 %id = call token @llvm.coro.id(i32 0, ptr %__promise, ptr null, ptr null) - call void @consume2(%"class.task::promise_type"* %__promise) + call void @consume2(ptr %__promise) %size = call i32 @llvm.coro.size.i32() %alloc = call ptr @malloc(i32 %size) %hdl = call ptr @llvm.coro.begin(token %id, ptr %alloc) - call void @consume(i32* %data) + call void @consume(ptr %data) %0 = call i8 @llvm.coro.suspend(token none, i1 false) switch i8 %0, label %suspend [i8 0, label %resume i8 1, label %cleanup] resume: - call void @consume(i32* %data) - call void @consume2(%"class.task::promise_type"* %__promise) + call void @consume(ptr %data) + call void @consume2(ptr %__promise) br label %cleanup cleanup: From c332d8590718e66c3750887468c0aadc65eb1dbe Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Thu, 15 Feb 2024 01:41:28 -0800 Subject: [PATCH 2/2] Extend `retcon.once` coroutines lowering to optionally produce a normal result (#66333) One of the main user of these kind of coroutines is swift. There yield-once (`retcon.once`) coroutines are used to temporary "expose" pointers to internal fields of various objects creating borrow scopes. However, in some cases it might be useful also to allow these coroutines to produce a normal result, but there is no convenient way to represent this (as compared to switched-resume kind of coroutines where C++ `co_return` is transformed to a member / callback call on promise object). The extension is simple: we allow continuation function to have a non-void result and accept optional extra arguments via a special `llvm.coro.end.result` intrinsic that would essentially forward them as normal results. --- clang/lib/CodeGen/CGCoroutine.cpp | 17 +- clang/test/CodeGenCoroutines/coro-builtins.c | 2 +- .../CodeGenCoroutines/coro-eh-cleanup.cpp | 4 +- llvm/docs/Coroutines.rst | 71 ++++++- llvm/include/llvm/IR/Intrinsics.td | 3 +- llvm/lib/IR/AutoUpgrade.cpp | 13 ++ llvm/lib/Transforms/Coroutines/CoroInstr.h | 40 +++- llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 37 +++- .../test/Assembler/auto_upgrade_intrinsics.ll | 7 + llvm/test/Transforms/Coroutines/ArgAddr.ll | 4 +- .../Transforms/Coroutines/coro-align16.ll | 4 +- .../Transforms/Coroutines/coro-align32.ll | 4 +- .../Transforms/Coroutines/coro-align64-02.ll | 4 +- .../Transforms/Coroutines/coro-align64.ll | 4 +- .../Transforms/Coroutines/coro-align8-02.ll | 4 +- .../test/Transforms/Coroutines/coro-align8.ll | 4 +- .../Coroutines/coro-alloc-with-param-O0.ll | 4 +- .../Coroutines/coro-alloc-with-param-O2.ll | 4 +- .../Transforms/Coroutines/coro-alloca-01.ll | 4 +- .../Transforms/Coroutines/coro-alloca-02.ll | 4 +- .../Transforms/Coroutines/coro-alloca-03.ll | 4 +- .../Transforms/Coroutines/coro-alloca-04.ll | 4 +- .../Transforms/Coroutines/coro-alloca-05.ll | 4 +- .../Transforms/Coroutines/coro-alloca-06.ll | 4 +- .../Transforms/Coroutines/coro-alloca-07.ll | 4 +- .../Transforms/Coroutines/coro-alloca-08.ll | 6 +- .../Transforms/Coroutines/coro-alloca-09.ll | 4 +- .../coro-alloca-loop-carried-address.ll | 4 +- ...o-async-addr-lifetime-infinite-loop-bug.ll | 2 +- .../coro-async-addr-lifetime-start-bug.ll | 2 +- .../Coroutines/coro-async-dyn-align.ll | 2 +- llvm/test/Transforms/Coroutines/coro-async.ll | 4 +- .../Transforms/Coroutines/coro-byval-param.ll | 4 +- .../Coroutines/coro-catchswitch-cleanuppad.ll | 4 +- .../Transforms/Coroutines/coro-catchswitch.ll | 4 +- .../Transforms/Coroutines/coro-debug-O2.ll | 4 +- .../Coroutines/coro-debug-coro-frame.ll | 6 +- ...coro-debug-dbg.values-not_used_in_frame.ll | 4 +- .../Coroutines/coro-debug-dbg.values.ll | 4 +- .../Coroutines/coro-debug-frame-variable.ll | 4 +- .../coro-debug-spill-dbg.declare.ll | 4 +- llvm/test/Transforms/Coroutines/coro-debug.ll | 4 +- .../Coroutines/coro-eh-aware-edge-split-00.ll | 4 +- .../Coroutines/coro-eh-aware-edge-split-01.ll | 4 +- .../Coroutines/coro-eh-aware-edge-split-02.ll | 4 +- .../Coroutines/coro-frame-arrayalloca.ll | 4 +- .../Coroutines/coro-frame-reuse-alloca-00.ll | 4 +- .../Coroutines/coro-frame-reuse-alloca-01.ll | 4 +- .../Coroutines/coro-frame-reuse-alloca-02.ll | 4 +- .../Coroutines/coro-frame-reuse-alloca-03.ll | 4 +- .../Coroutines/coro-frame-reuse-alloca-04.ll | 4 +- .../Coroutines/coro-frame-reuse-alloca-05.ll | 4 +- .../Coroutines/coro-frame-unreachable.ll | 4 +- llvm/test/Transforms/Coroutines/coro-frame.ll | 4 +- .../Transforms/Coroutines/coro-materialize.ll | 12 +- .../Coroutines/coro-noalias-param.ll | 4 +- .../Transforms/Coroutines/coro-padding.ll | 4 +- .../Transforms/Coroutines/coro-param-copy.ll | 4 +- .../Coroutines/coro-preserve-final.ll | 4 +- .../Transforms/Coroutines/coro-readnone-02.ll | 4 +- .../Transforms/Coroutines/coro-readnone.ll | 4 +- .../coro-retcon-alloca-opaque-ptr.ll | 6 +- .../Coroutines/coro-retcon-alloca.ll | 12 +- .../Coroutines/coro-retcon-frame.ll | 4 +- .../Coroutines/coro-retcon-once-private.ll | 4 +- .../Coroutines/coro-retcon-once-value.ll | 191 +++++++++++++++--- .../Coroutines/coro-retcon-once-value2.ll | 120 ++++++++++- .../Coroutines/coro-retcon-opaque-ptr.ll | 6 +- .../Coroutines/coro-retcon-remat.ll | 4 +- .../Coroutines/coro-retcon-resume-values.ll | 4 +- .../Coroutines/coro-retcon-resume-values2.ll | 4 +- .../Coroutines/coro-retcon-unreachable.ll | 4 +- .../Coroutines/coro-retcon-value.ll | 4 +- .../test/Transforms/Coroutines/coro-retcon.ll | 8 +- .../Coroutines/coro-spill-after-phi.ll | 4 +- .../Coroutines/coro-spill-corobegin.ll | 4 +- .../coro-spill-defs-before-corobegin.ll | 4 +- .../Coroutines/coro-spill-promise-02.ll | 4 +- .../Coroutines/coro-spill-promise.ll | 4 +- .../Transforms/Coroutines/coro-split-00.ll | 4 +- .../Transforms/Coroutines/coro-split-01.ll | 4 +- .../Transforms/Coroutines/coro-split-02.ll | 4 +- .../Transforms/Coroutines/coro-split-alloc.ll | 4 +- .../Transforms/Coroutines/coro-split-dbg.ll | 4 +- .../Transforms/Coroutines/coro-split-eh-00.ll | 6 +- .../Transforms/Coroutines/coro-split-eh-01.ll | 6 +- .../Coroutines/coro-split-final-suspend.ll | 8 +- .../Coroutines/coro-split-hidden.ll | 4 +- .../Coroutines/coro-split-musttail-ppc64le.ll | 4 +- .../Coroutines/coro-split-musttail.ll | 4 +- .../Coroutines/coro-split-musttail1.ll | 4 +- .../Coroutines/coro-split-musttail10.ll | 4 +- .../Coroutines/coro-split-musttail11.ll | 4 +- .../Coroutines/coro-split-musttail12.ll | 4 +- .../Coroutines/coro-split-musttail13.ll | 6 +- .../Coroutines/coro-split-musttail2.ll | 4 +- .../Coroutines/coro-split-musttail3.ll | 4 +- .../Coroutines/coro-split-musttail4.ll | 4 +- .../Coroutines/coro-split-musttail5.ll | 4 +- .../Coroutines/coro-split-musttail6.ll | 6 +- .../Coroutines/coro-split-musttail7.ll | 6 +- .../Coroutines/coro-split-musttail8.ll | 4 +- .../Coroutines/coro-split-musttail9.ll | 4 +- .../Coroutines/coro-split-no-lieftime.ll | 4 +- .../Coroutines/coro-split-sink-lifetime-01.ll | 6 +- .../Coroutines/coro-split-sink-lifetime-02.ll | 4 +- .../Coroutines/coro-split-sink-lifetime-03.ll | 4 +- .../Coroutines/coro-split-sink-lifetime-04.ll | 4 +- .../Transforms/Coroutines/coro-swifterror.ll | 6 +- .../Transforms/Coroutines/coro-zero-alloca.ll | 4 +- llvm/test/Transforms/Coroutines/ex0.ll | 4 +- llvm/test/Transforms/Coroutines/ex1.ll | 4 +- llvm/test/Transforms/Coroutines/ex2.ll | 4 +- llvm/test/Transforms/Coroutines/ex3.ll | 4 +- llvm/test/Transforms/Coroutines/ex4.ll | 4 +- llvm/test/Transforms/Coroutines/ex5.ll | 4 +- llvm/test/Transforms/Coroutines/no-suspend.ll | 18 +- .../Transforms/Coroutines/phi-coro-end.ll | 4 +- llvm/test/Transforms/Coroutines/remarks.ll | 4 +- .../test/Transforms/FunctionAttrs/noreturn.ll | 4 +- .../Transforms/LICM/sink-with-coroutine.ll | 10 +- .../mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td | 5 +- mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 25 +++ .../Conversion/AsyncToLLVM/AsyncToLLVM.cpp | 3 +- mlir/lib/Target/LLVMIR/ModuleImport.cpp | 5 + mlir/test/Target/LLVMIR/Import/intrinsic.ll | 4 +- .../test/Target/LLVMIR/llvmir-intrinsics.mlir | 7 +- 127 files changed, 741 insertions(+), 313 deletions(-) diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp index 8437cda79beb2..1d6058dcde7d2 100644 --- a/clang/lib/CodeGen/CGCoroutine.cpp +++ b/clang/lib/CodeGen/CGCoroutine.cpp @@ -402,8 +402,11 @@ 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()}, Bundles); + auto *CoroEnd = + 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. @@ -754,7 +757,9 @@ void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) { // Emit coro.end before getReturnStmt (and parameter destructors), since // resume and destroy parts of the coroutine should not include them. llvm::Function *CoroEnd = CGM.getIntrinsic(llvm::Intrinsic::coro_end); - Builder.CreateCall(CoroEnd, {NullPtr, Builder.getFalse()}); + Builder.CreateCall(CoroEnd, + {NullPtr, Builder.getFalse(), + llvm::ConstantTokenNone::get(CoroEnd->getContext())}); if (Stmt *Ret = S.getReturnStmt()) { // Since we already emitted the return value above, so we shouldn't @@ -823,7 +828,11 @@ RValue CodeGenFunction::EmitCoroutineIntrinsic(const CallExpr *E, } for (const Expr *Arg : E->arguments()) Args.push_back(EmitScalarExpr(Arg)); - + // @llvm.coro.end takes a token parameter. Add token 'none' as the last + // argument. + if (IID == llvm::Intrinsic::coro_end) + Args.push_back(llvm::ConstantTokenNone::get(getLLVMContext())); + llvm::Function *F = CGM.getIntrinsic(IID); llvm::CallInst *Call = Builder.CreateCall(F, Args); diff --git a/clang/test/CodeGenCoroutines/coro-builtins.c b/clang/test/CodeGenCoroutines/coro-builtins.c index e58820db67839..79f119b2b60ff 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) + // CHECK-NEXT: call i1 @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 c4a6ae96f551e..725cf8faa6b4c 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) [ "funclet"(token %[[CLPAD]]) ] +// CHECK-NEXT: call i1 @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) +// CHECK-LPAD: %[[I1RESUME:.+]] = call i1 @llvm.coro.end(ptr null, i1 true, token none) // 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/llvm/docs/Coroutines.rst b/llvm/docs/Coroutines.rst index 7befa8a32a8ee..ee8cdb15ad508 100644 --- a/llvm/docs/Coroutines.rst +++ b/llvm/docs/Coroutines.rst @@ -152,8 +152,8 @@ lowerings: - In yield-once returned-continuation lowering, the coroutine must suspend itself exactly once (or throw an exception). The ramp function returns a continuation function pointer and yielded - values, but the continuation function simply returns `void` - when the coroutine has run to completion. + values, the continuation function may optionally return ordinary + results when the coroutine has run to completion. The coroutine frame is maintained in a fixed-size buffer that is passed to the `coro.id` intrinsic, which guarantees a certain size @@ -304,7 +304,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) + %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret ptr %hdl } @@ -631,7 +631,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) + %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret ptr %hdl } @@ -1313,8 +1313,8 @@ Arguments: """""""""" As for ``llvm.core.id.retcon``, except that the return type of the -continuation prototype must be `void` instead of matching the -coroutine's return type. +continuation prototype must represent the normal return type of the continuation +(instead of matching the coroutine's return type). Semantics: """""""""" @@ -1327,7 +1327,7 @@ A frontend should emit function attribute `presplitcoroutine` for the coroutine. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - declare i1 @llvm.coro.end(ptr , i1 ) + declare i1 @llvm.coro.end(ptr , i1 , token ) Overview: """"""""" @@ -1348,6 +1348,12 @@ The second argument should be `true` if this coro.end is in the block that is part of the unwind sequence leaving the coroutine body due to an exception and `false` otherwise. +Non-trivial (non-none) token argument can only be specified for unique-suspend +returned-continuation coroutines where it must be a token value produced by +'``llvm.coro.end.results``' intrinsic. + +Only none token is allowed for coro.end calls in unwind sections + Semantics: """""""""" The purpose of this intrinsic is to allow frontends to mark the cleanup and @@ -1379,7 +1385,7 @@ 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) + %InResumePart = call i1 @llvm.coro.end(ptr null, i1 true, token none) br i1 %InResumePart, label %eh.resume, label %cleanup.cont cleanup.cont: @@ -1404,7 +1410,7 @@ referring to an enclosing cleanuppad as follows: ehcleanup: %tok = cleanuppad within none [] - %unused = call i1 @llvm.coro.end(ptr null, i1 true) [ "funclet"(token %tok) ] + %unused = call i1 @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 @@ -1429,6 +1435,53 @@ The following table summarizes the handling of `coro.end`_ intrinsic. | | Landingpad | mark coroutine as done | mark coroutine done | +------------+-------------+------------------------+---------------------------------+ +.. _coro.end.results: + +'llvm.coro.end.results' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + declare token @llvm.coro.end.results(...) + +Overview: +""""""""" + +The '``llvm.coro.end.results``' intrinsic captures values to be returned from +unique-suspend returned-continuation coroutines. + +Arguments: +"""""""""" + +The number of arguments must match the return type of the continuation function: + +- if the return type of the continuation function is ``void`` there must be no + arguments + +- if the return type of the continuation function is a ``struct``, the arguments + will be of element types of that ``struct`` in order; + +- otherwise, it is just the return value of the continuation function. + +.. code-block:: llvm + + define {ptr, ptr} @g(ptr %buffer, ptr %ptr, i8 %val) presplitcoroutine { + entry: + %id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer, + ptr @prototype, + ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) + + ... + + cleanup: + %tok = call token (...) @llvm.coro.end.results(i8 %val) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token %tok) + unreachable + + ... + + declare i8 @prototype(ptr, i1 zeroext) + 'llvm.coro.end.async' Intrinsic ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index e51c04fbad2f4..51d022e931f93 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -1631,7 +1631,8 @@ def int_coro_free : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty], [IntrReadMem, IntrArgMemOnly, ReadOnly>, NoCapture>]>; -def int_coro_end : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_i1_ty], []>; +def int_coro_end : Intrinsic<[llvm_i1_ty], [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], []>; diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index e7de6d1e73ce0..61fb78a99abf1 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -929,6 +929,12 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { F->arg_begin()->getType()); return true; } + if (Name.equals("coro.end") && F->arg_size() == 2) { + rename(F); + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::coro_end); + return true; + } + break; } case 'd': { @@ -4307,6 +4313,13 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { break; } + case Intrinsic::coro_end: { + SmallVector Args(CI->args()); + Args.push_back(ConstantTokenNone::get(CI->getContext())); + NewCall = Builder.CreateCall(NewFn, Args); + break; + } + case Intrinsic::vector_extract: { StringRef Name = F->getName(); Name = Name.substr(5); // Strip llvm diff --git a/llvm/lib/Transforms/Coroutines/CoroInstr.h b/llvm/lib/Transforms/Coroutines/CoroInstr.h index 014938c15a0a3..2e7d9b2ce028a 100644 --- a/llvm/lib/Transforms/Coroutines/CoroInstr.h +++ b/llvm/lib/Transforms/Coroutines/CoroInstr.h @@ -611,8 +611,37 @@ class LLVM_LIBRARY_VISIBILITY CoroAlignInst : public IntrinsicInst { } }; +/// This represents the llvm.end.results instruction. +class LLVM_LIBRARY_VISIBILITY CoroEndResults : public IntrinsicInst { +public: + op_iterator retval_begin() { return arg_begin(); } + const_op_iterator retval_begin() const { return arg_begin(); } + + op_iterator retval_end() { return arg_end(); } + const_op_iterator retval_end() const { return arg_end(); } + + iterator_range return_values() { + return make_range(retval_begin(), retval_end()); + } + iterator_range return_values() const { + return make_range(retval_begin(), retval_end()); + } + + unsigned numReturns() const { + return std::distance(retval_begin(), retval_end()); + } + + // Methods to support type inquiry through isa, cast, and dyn_cast: + static bool classof(const IntrinsicInst *I) { + return I->getIntrinsicID() == Intrinsic::coro_end_results; + } + static bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + class LLVM_LIBRARY_VISIBILITY AnyCoroEndInst : public IntrinsicInst { - enum { FrameArg, UnwindArg }; + enum { FrameArg, UnwindArg, TokenArg }; public: bool isFallthrough() const { return !isUnwind(); } @@ -620,6 +649,15 @@ class LLVM_LIBRARY_VISIBILITY AnyCoroEndInst : public IntrinsicInst { return cast(getArgOperand(UnwindArg))->isOneValue(); } + bool hasResults() const { + return !isa(getArgOperand(TokenArg)); + } + + CoroEndResults *getResults() const { + assert(hasResults()); + return cast(getArgOperand(TokenArg)); + } + // Methods to support type inquiry through isa, cast, and dyn_cast: static bool classof(const IntrinsicInst *I) { auto ID = I->getIntrinsicID(); diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp index f3da3153bc038..546b7807e216b 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -229,6 +229,8 @@ static void replaceFallthroughCoroEnd(AnyCoroEndInst *End, switch (Shape.ABI) { // The cloned functions in switch-lowering always return void. case coro::ABI::Switch: + assert(!cast(End)->hasResults() && + "switch coroutine should not return any values"); // coro.end doesn't immediately end the coroutine in the main function // in this lowering, because we need to deallocate the coroutine. if (!InResume) @@ -246,14 +248,45 @@ static void replaceFallthroughCoroEnd(AnyCoroEndInst *End, // In unique continuation lowering, the continuations always return void. // But we may have implicitly allocated storage. - case coro::ABI::RetconOnce: + case coro::ABI::RetconOnce: { maybeFreeRetconStorage(Builder, Shape, FramePtr, CG); - Builder.CreateRetVoid(); + auto *CoroEnd = cast(End); + auto *RetTy = Shape.getResumeFunctionType()->getReturnType(); + + if (!CoroEnd->hasResults()) { + assert(RetTy->isVoidTy()); + Builder.CreateRetVoid(); + break; + } + + auto *CoroResults = CoroEnd->getResults(); + unsigned NumReturns = CoroResults->numReturns(); + + if (auto *RetStructTy = dyn_cast(RetTy)) { + assert(RetStructTy->getNumElements() == NumReturns && + "numbers of returns should match resume function singature"); + Value *ReturnValue = UndefValue::get(RetStructTy); + unsigned Idx = 0; + for (Value *RetValEl : CoroResults->return_values()) + ReturnValue = Builder.CreateInsertValue(ReturnValue, RetValEl, Idx++); + Builder.CreateRet(ReturnValue); + } else if (NumReturns == 0) { + assert(RetTy->isVoidTy()); + Builder.CreateRetVoid(); + } else { + assert(NumReturns == 1); + Builder.CreateRet(*CoroResults->retval_begin()); + } + CoroResults->replaceAllUsesWith(ConstantTokenNone::get(CoroResults->getContext())); + CoroResults->eraseFromParent(); break; + } // In non-unique continuation lowering, we signal completion by returning // a null continuation. case coro::ABI::Retcon: { + assert(!cast(End)->hasResults() && + "retcon coroutine should not return any values"); maybeFreeRetconStorage(Builder, Shape, FramePtr, CG); auto RetTy = Shape.getResumeFunctionType()->getReturnType(); auto RetStructTy = dyn_cast(RetTy); diff --git a/llvm/test/Assembler/auto_upgrade_intrinsics.ll b/llvm/test/Assembler/auto_upgrade_intrinsics.ll index acca39e314033..e3603846e9e9b 100644 --- a/llvm/test/Assembler/auto_upgrade_intrinsics.ll +++ b/llvm/test/Assembler/auto_upgrade_intrinsics.ll @@ -47,6 +47,13 @@ entry: ret void } +declare i1 @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) + ret void +} @a = private global [60 x i8] zeroinitializer, align 1 diff --git a/llvm/test/Transforms/Coroutines/ArgAddr.ll b/llvm/test/Transforms/Coroutines/ArgAddr.ll index a06dd66da1c58..1fbc8e1d49767 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) + call i1 @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) +declare i1 @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 fdd8af7497680..39902be9149e8 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) + call i1 @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) +declare i1 @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 032fda5f3b2a7..3d910e951259b 100644 --- a/llvm/test/Transforms/Coroutines/coro-align32.ll +++ b/llvm/test/Transforms/Coroutines/coro-align32.ll @@ -28,7 +28,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -48,7 +48,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) +declare i1 @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-align64-02.ll b/llvm/test/Transforms/Coroutines/coro-align64-02.ll index 2eab5c581db31..3e2e33d2da260 100644 --- a/llvm/test/Transforms/Coroutines/coro-align64-02.ll +++ b/llvm/test/Transforms/Coroutines/coro-align64-02.ll @@ -24,7 +24,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @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) +declare i1 @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-align64.ll b/llvm/test/Transforms/Coroutines/coro-align64.ll index aff05b62f1ac9..9623a99a8b27e 100644 --- a/llvm/test/Transforms/Coroutines/coro-align64.ll +++ b/llvm/test/Transforms/Coroutines/coro-align64.ll @@ -24,7 +24,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @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) +declare i1 @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-align8-02.ll b/llvm/test/Transforms/Coroutines/coro-align8-02.ll index 2bbdf0e0164ee..758d4ce3e21b2 100644 --- a/llvm/test/Transforms/Coroutines/coro-align8-02.ll +++ b/llvm/test/Transforms/Coroutines/coro-align8-02.ll @@ -20,7 +20,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -40,7 +40,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @aligned_alloc(i32, i32) declare void @free(ptr) diff --git a/llvm/test/Transforms/Coroutines/coro-align8.ll b/llvm/test/Transforms/Coroutines/coro-align8.ll index a8bdba356b1fb..48a2687cc4799 100644 --- a/llvm/test/Transforms/Coroutines/coro-align8.ll +++ b/llvm/test/Transforms/Coroutines/coro-align8.ll @@ -24,7 +24,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @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) +declare i1 @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-alloc-with-param-O0.ll b/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O0.ll index 31118c4c25770..bdd49413cf15b 100644 --- a/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O0.ll +++ b/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O0.ll @@ -24,7 +24,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -54,7 +54,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @myAlloc(i64, i32) declare double @print(double) diff --git a/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O2.ll b/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O2.ll index 9eae6cc2cfa7e..a0ab5b733fdf0 100644 --- a/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O2.ll +++ b/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O2.ll @@ -21,7 +21,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -49,7 +49,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @myAlloc(i64, i32) declare double @print(double) diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-01.ll b/llvm/test/Transforms/Coroutines/coro-alloca-01.ll index 9ba39491776ea..5208c055c4fdf 100644 --- a/llvm/test/Transforms/Coroutines/coro-alloca-01.ll +++ b/llvm/test/Transforms/Coroutines/coro-alloca-01.ll @@ -33,7 +33,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -55,7 +55,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare void @print(ptr) declare noalias ptr @malloc(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-02.ll b/llvm/test/Transforms/Coroutines/coro-alloca-02.ll index 76d9a0126382e..83f56009f00e3 100644 --- a/llvm/test/Transforms/Coroutines/coro-alloca-02.ll +++ b/llvm/test/Transforms/Coroutines/coro-alloca-02.ll @@ -25,7 +25,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @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) +declare i1 @llvm.coro.end(ptr, i1, token) declare void @print(ptr) declare noalias ptr @malloc(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-03.ll b/llvm/test/Transforms/Coroutines/coro-alloca-03.ll index ec76a8a553654..7740ed440a0d5 100644 --- a/llvm/test/Transforms/Coroutines/coro-alloca-03.ll +++ b/llvm/test/Transforms/Coroutines/coro-alloca-03.ll @@ -23,7 +23,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @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) +declare i1 @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-alloca-04.ll b/llvm/test/Transforms/Coroutines/coro-alloca-04.ll index e528d81986f10..c19cd253a9179 100644 --- a/llvm/test/Transforms/Coroutines/coro-alloca-04.ll +++ b/llvm/test/Transforms/Coroutines/coro-alloca-04.ll @@ -32,7 +32,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -53,7 +53,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare void @print(ptr) declare noalias ptr @malloc(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-05.ll b/llvm/test/Transforms/Coroutines/coro-alloca-05.ll index 6529e8fda1be6..96769e51fb80f 100644 --- a/llvm/test/Transforms/Coroutines/coro-alloca-05.ll +++ b/llvm/test/Transforms/Coroutines/coro-alloca-05.ll @@ -23,7 +23,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @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) +declare i1 @llvm.coro.end(ptr, i1, token) declare void @print(i32) declare noalias ptr @malloc(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-06.ll b/llvm/test/Transforms/Coroutines/coro-alloca-06.ll index a3444c30121ec..89149ceba4c14 100644 --- a/llvm/test/Transforms/Coroutines/coro-alloca-06.ll +++ b/llvm/test/Transforms/Coroutines/coro-alloca-06.ll @@ -37,7 +37,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -63,7 +63,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare void @llvm.lifetime.start.p0(i64, ptr nocapture) declare void @llvm.lifetime.end.p0(i64, ptr nocapture) diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-07.ll b/llvm/test/Transforms/Coroutines/coro-alloca-07.ll index 57dde64be6759..c81bf333f2059 100644 --- a/llvm/test/Transforms/Coroutines/coro-alloca-07.ll +++ b/llvm/test/Transforms/Coroutines/coro-alloca-07.ll @@ -36,7 +36,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -49,7 +49,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare void @llvm.lifetime.start.p0(i64, ptr nocapture) diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-08.ll b/llvm/test/Transforms/Coroutines/coro-alloca-08.ll index b0aeadc81e9ff..5a14a0eb98869 100644 --- a/llvm/test/Transforms/Coroutines/coro-alloca-08.ll +++ b/llvm/test/Transforms/Coroutines/coro-alloca-08.ll @@ -32,7 +32,7 @@ await.ready: %StrayCoroSave = call token @llvm.coro.save(ptr null) br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -59,7 +59,7 @@ await.ready: br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -75,6 +75,6 @@ declare token @llvm.coro.save(ptr) #3 declare ptr @llvm.coro.frame() #5 declare i8 @llvm.coro.suspend(token, i1) #3 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 -declare i1 @llvm.coro.end(ptr, i1) #3 +declare i1 @llvm.coro.end(ptr, i1, token) #3 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4 diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-09.ll b/llvm/test/Transforms/Coroutines/coro-alloca-09.ll index 2e0a8def2d544..5c60c5be46206 100644 --- a/llvm/test/Transforms/Coroutines/coro-alloca-09.ll +++ b/llvm/test/Transforms/Coroutines/coro-alloca-09.ll @@ -37,7 +37,7 @@ await.ready: %StrayCoroSave = call token @llvm.coro.save(ptr null) br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -52,6 +52,6 @@ declare token @llvm.coro.save(ptr) #3 declare ptr @llvm.coro.frame() #5 declare i8 @llvm.coro.suspend(token, i1) #3 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 -declare i1 @llvm.coro.end(ptr, i1) #3 +declare i1 @llvm.coro.end(ptr, i1, token) #3 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4 diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-loop-carried-address.ll b/llvm/test/Transforms/Coroutines/coro-alloca-loop-carried-address.ll index ffdd0ab66359f..412327a49dcf2 100644 --- a/llvm/test/Transforms/Coroutines/coro-alloca-loop-carried-address.ll +++ b/llvm/test/Transforms/Coroutines/coro-alloca-loop-carried-address.ll @@ -68,7 +68,7 @@ loop: ] exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -80,6 +80,6 @@ declare i64 @llvm.coro.size.i64() declare ptr @llvm.coro.begin(token, ptr writeonly) declare token @llvm.coro.save(ptr) declare i8 @llvm.coro.suspend(token, i1) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare void @llvm.lifetime.start(i64, ptr nocapture) declare void @llvm.lifetime.end(i64, ptr nocapture) diff --git a/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-infinite-loop-bug.ll b/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-infinite-loop-bug.ll index 280b94fedd913..9510232d61c43 100644 --- a/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-infinite-loop-bug.ll +++ b/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-infinite-loop-bug.ll @@ -73,7 +73,7 @@ declare ptr @llvm.coro.prepare.async(ptr) declare token @llvm.coro.id.async(i32, i32, i32, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.end.async(ptr, i1, ...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare {ptr, ptr, ptr} @llvm.coro.suspend.async(i32, ptr, ptr, ...) declare ptr @context_alloc() declare void @llvm.coro.async.context.dealloc(ptr) diff --git a/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll b/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll index 964d92b5473cf..c6ec6febabebe 100644 --- a/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll +++ b/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll @@ -97,7 +97,7 @@ declare ptr @llvm.coro.prepare.async(ptr) declare token @llvm.coro.id.async(i32, i32, i32, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.end.async(ptr, i1, ...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare {ptr, ptr, ptr} @llvm.coro.suspend.async(i32, ptr, ptr, ...) declare ptr @context_alloc() declare void @llvm.coro.async.context.dealloc(ptr) diff --git a/llvm/test/Transforms/Coroutines/coro-async-dyn-align.ll b/llvm/test/Transforms/Coroutines/coro-async-dyn-align.ll index 26955521f7ce4..567977ea1476d 100644 --- a/llvm/test/Transforms/Coroutines/coro-async-dyn-align.ll +++ b/llvm/test/Transforms/Coroutines/coro-async-dyn-align.ll @@ -28,7 +28,7 @@ declare ptr @llvm.coro.async.resume() declare token @llvm.coro.id.async(i32, i32, i32, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.end.async(ptr, i1, ...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare swiftcc void @asyncReturn(ptr) declare swiftcc void @asyncSuspend(ptr) declare {ptr} @llvm.coro.suspend.async(i32, ptr, ptr, ...) diff --git a/llvm/test/Transforms/Coroutines/coro-async.ll b/llvm/test/Transforms/Coroutines/coro-async.ll index 7a500809de250..a3abc1c239851 100644 --- a/llvm/test/Transforms/Coroutines/coro-async.ll +++ b/llvm/test/Transforms/Coroutines/coro-async.ll @@ -211,7 +211,7 @@ entry: %continuation_actor_arg = extractvalue {ptr, ptr, ptr} %res.2, 1 tail call swifttailcc void @asyncReturn(ptr %async.ctxt, ptr %continuation_task_arg, ptr %continuation_actor_arg) - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -501,7 +501,7 @@ declare ptr @llvm.coro.prepare.async(ptr) declare token @llvm.coro.id.async(i32, i32, i32, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.end.async(ptr, i1, ...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare {ptr, ptr, ptr} @llvm.coro.suspend.async(i32, ptr, ptr, ...) declare ptr @llvm.coro.async.context.alloc(ptr, ptr) declare void @llvm.coro.async.context.dealloc(ptr) diff --git a/llvm/test/Transforms/Coroutines/coro-byval-param.ll b/llvm/test/Transforms/Coroutines/coro-byval-param.ll index 5f7c1939f9f47..47059182d8ed6 100644 --- a/llvm/test/Transforms/Coroutines/coro-byval-param.ll +++ b/llvm/test/Transforms/Coroutines/coro-byval-param.ll @@ -52,7 +52,7 @@ coro.free: ; preds = %cleanup33 br label %coro.ret coro.ret: ; preds = %coro.free, %cleanup33, %init.ready, %coro.init - %10 = call i1 @llvm.coro.end(ptr null, i1 false) #10 + %10 = call i1 @llvm.coro.end(ptr null, i1 false, token none) #10 ret ptr %call2 } @@ -102,7 +102,7 @@ declare i8 @llvm.coro.suspend(token, i1) #2 declare void @_ZN4task12promise_type13final_suspendEv(ptr nonnull dereferenceable(1)) local_unnamed_addr #7 align 2 ; Function Attrs: nounwind -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 ; Function Attrs: nobuiltin nounwind declare void @_ZdlPv(ptr) local_unnamed_addr #8 diff --git a/llvm/test/Transforms/Coroutines/coro-catchswitch-cleanuppad.ll b/llvm/test/Transforms/Coroutines/coro-catchswitch-cleanuppad.ll index f6f4607b3e810..2f6d23da82692 100644 --- a/llvm/test/Transforms/Coroutines/coro-catchswitch-cleanuppad.ll +++ b/llvm/test/Transforms/Coroutines/coro-catchswitch-cleanuppad.ll @@ -37,7 +37,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl catch.dispatch.1: @@ -106,7 +106,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-catchswitch.ll b/llvm/test/Transforms/Coroutines/coro-catchswitch.ll index dca9a754c9f6c..3cf6dc86f2c6d 100644 --- a/llvm/test/Transforms/Coroutines/coro-catchswitch.ll +++ b/llvm/test/Transforms/Coroutines/coro-catchswitch.ll @@ -54,7 +54,7 @@ resume: ; preds = %await2.suspend br label %coro.ret coro.ret: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret void cleanuppad: @@ -80,7 +80,7 @@ declare void @print(i32) declare noalias ptr @malloc(i32) declare void @free(ptr) -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 ; Function Attrs: nobuiltin nounwind diff --git a/llvm/test/Transforms/Coroutines/coro-debug-O2.ll b/llvm/test/Transforms/Coroutines/coro-debug-O2.ll index f207b7e8030da..ca7a045e46193 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug-O2.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-O2.ll @@ -111,7 +111,7 @@ cleanup.cont: ; preds = %after.coro.free br label %coro.ret coro.ret: ; preds = %cleanup.cont, %after.coro.free, %final.suspend, %await.suspend, %init.suspend - %end = call i1 @llvm.coro.end(ptr null, i1 false) + %end = call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void unreachable: ; preds = %after.coro.free @@ -127,7 +127,7 @@ declare token @llvm.coro.save(ptr) declare ptr @llvm.coro.begin(token, ptr writeonly) declare i8 @llvm.coro.suspend(token, i1) declare ptr @llvm.coro.free(token, ptr nocapture readonly) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @new(i64) declare void @delete(ptr) diff --git a/llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll b/llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll index dada825379137..7f5679e4d522f 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll @@ -205,7 +205,7 @@ cleanup.cont: ; preds = %after.coro.free br label %coro.ret coro.ret: ; preds = %cleanup.cont, %after.coro.free, %final.suspend, %await.suspend, %init.suspend - %end = call i1 @llvm.coro.end(ptr null, i1 false) + %end = call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void unreachable: ; preds = %after.coro.free @@ -334,7 +334,7 @@ cleanup.cont: ; preds = %after.coro.free br label %coro.ret coro.ret: ; preds = %cleanup.cont, %after.coro.free, %final.suspend, %await.suspend, %init.suspend - %end = call i1 @llvm.coro.end(ptr null, i1 false) + %end = call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void unreachable: ; preds = %after.coro.free @@ -350,7 +350,7 @@ declare token @llvm.coro.save(ptr) declare ptr @llvm.coro.begin(token, ptr writeonly) declare i8 @llvm.coro.suspend(token, i1) declare ptr @llvm.coro.free(token, ptr nocapture readonly) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @new(i64) declare void @delete(ptr) diff --git a/llvm/test/Transforms/Coroutines/coro-debug-dbg.values-not_used_in_frame.ll b/llvm/test/Transforms/Coroutines/coro-debug-dbg.values-not_used_in_frame.ll index ed76c67860ee1..1b9a1bd63a2e3 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug-dbg.values-not_used_in_frame.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-dbg.values-not_used_in_frame.ll @@ -123,7 +123,7 @@ cleanup.cont: ; preds = %after.coro.free br label %coro.ret coro.ret: ; preds = %cleanup.cont, %after.coro.free, %final.suspend, %await.suspend, %init.suspend - %end = call i1 @llvm.coro.end(ptr null, i1 false) + %end = call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void unreachable: ; preds = %after.coro.free @@ -155,7 +155,7 @@ declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 ; Function Attrs: nounwind -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @new(i64) diff --git a/llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll b/llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll index fa6c6e9b8d2cf..54cdde8ae4ac0 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll @@ -154,7 +154,7 @@ cleanup.cont: ; preds = %after.coro.free br label %coro.ret coro.ret: ; preds = %cleanup.cont, %after.coro.free, %final.suspend, %await.suspend, %init.suspend - %end = call i1 @llvm.coro.end(ptr null, i1 false) + %end = call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void unreachable: ; preds = %after.coro.free @@ -186,7 +186,7 @@ declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 ; Function Attrs: nounwind -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @new(i64) diff --git a/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll b/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll index 7d9aa879fc5cb..37b4126ce3730 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll @@ -182,7 +182,7 @@ cleanup.cont: ; preds = %after.coro.free br label %coro.ret coro.ret: ; preds = %cleanup.cont, %after.coro.free, %final.suspend, %await.suspend, %init.suspend - %end = call i1 @llvm.coro.end(ptr null, i1 false) + %end = call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void unreachable: ; preds = %after.coro.free @@ -197,7 +197,7 @@ declare token @llvm.coro.save(ptr) declare ptr @llvm.coro.begin(token, ptr writeonly) declare i8 @llvm.coro.suspend(token, i1) declare ptr @llvm.coro.free(token, ptr nocapture readonly) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @new(i64) declare void @delete(ptr) diff --git a/llvm/test/Transforms/Coroutines/coro-debug-spill-dbg.declare.ll b/llvm/test/Transforms/Coroutines/coro-debug-spill-dbg.declare.ll index d6606d7cd6ac5..e7a271a96ead1 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug-spill-dbg.declare.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-spill-dbg.declare.ll @@ -74,7 +74,7 @@ cleanup: ; preds = %resume, %coro.begin br label %suspend suspend: ; preds = %cleanup, %coro.begin - %2 = call i1 @llvm.coro.end(ptr %hdl, i1 false) + %2 = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret ptr %hdl } @@ -104,7 +104,7 @@ declare i1 @llvm.coro.alloc(token) #4 declare ptr @llvm.coro.begin(token, ptr writeonly) #4 ; Function Attrs: nounwind -declare i1 @llvm.coro.end(ptr, i1) #4 +declare i1 @llvm.coro.end(ptr, i1, token) #4 declare noalias ptr @malloc(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-debug.ll b/llvm/test/Transforms/Coroutines/coro-debug.ll index 879c50c9565f0..30715a4dec27d 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug.ll @@ -70,7 +70,7 @@ coro_Cleanup: ; preds = %sw.epilog, %sw.bb1 br label %coro_Suspend, !dbg !24 coro_Suspend: ; preds = %coro_Cleanup, %sw.default - %7 = call i1 @llvm.coro.end(ptr null, i1 false) #7, !dbg !24 + %7 = call i1 @llvm.coro.end(ptr null, i1 false, token none) #7, !dbg !24 %8 = load ptr, ptr %coro_hdl, align 8, !dbg !24 store i32 0, ptr %late_local, !dbg !24 ret ptr %8, !dbg !24 @@ -111,7 +111,7 @@ declare void @free(ptr) #3 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 ; Function Attrs: nounwind -declare i1 @llvm.coro.end(ptr, i1) #5 +declare i1 @llvm.coro.end(ptr, i1, token) #5 ; Function Attrs: alwaysinline define private void @coro.devirt.trigger(ptr) #6 { diff --git a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-00.ll b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-00.ll index e30b3fa55536c..2f5b989a620e0 100644 --- a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-00.ll +++ b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-00.ll @@ -65,7 +65,7 @@ cleanup: ; preds = %invoke.cont15, %if.el br label %coro.ret coro.ret: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void unreach: @@ -92,6 +92,6 @@ declare void @use_val(i32) declare void @__cxa_end_catch() ; Function Attrs: nounwind -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare void @free(ptr) declare ptr @llvm.coro.free(token, ptr nocapture readonly) diff --git a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll index 3959229959f43..d896c6a18b233 100644 --- a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll +++ b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll @@ -59,7 +59,7 @@ cleanup: ; preds = %invoke.cont15, %if.el br label %coro.ret coro.ret: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void unreach: @@ -86,6 +86,6 @@ declare void @use_val(i32) declare void @__cxa_end_catch() ; Function Attrs: nounwind -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare void @free(ptr) declare ptr @llvm.coro.free(token, ptr nocapture readonly) diff --git a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll index 95a73bec09dec..79aa58b85eda8 100644 --- a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll +++ b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll @@ -59,7 +59,7 @@ cleanup: ; preds = %invoke.cont15, %if.el br label %coro.ret coro.ret: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -83,6 +83,6 @@ declare void @use_val(i32) declare void @__cxa_end_catch() ; Function Attrs: nounwind -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare void @free(ptr) declare ptr @llvm.coro.free(token, ptr nocapture readonly) diff --git a/llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll b/llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll index 7d1a3f2e6ef80..7d5ddabf7ea8e 100644 --- a/llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll +++ b/llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll @@ -30,7 +30,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -65,7 +65,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare double @print(double) diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-00.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-00.ll index 0aee256d20e14..c9700c8a09961 100644 --- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-00.ll +++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-00.ll @@ -50,7 +50,7 @@ cleanup: call void @free(ptr %mem) br label %coro.ret coro.ret: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -66,7 +66,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare double @print(double) diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll index a1d1134fab35f..584caa356e9b8 100644 --- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll +++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll @@ -53,7 +53,7 @@ cleanup: call ptr @llvm.coro.free(token %0, ptr %1) br label %coro.ret coro.ret: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -68,6 +68,6 @@ declare token @llvm.coro.save(ptr) #3 declare ptr @llvm.coro.frame() #5 declare i8 @llvm.coro.suspend(token, i1) #3 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 -declare i1 @llvm.coro.end(ptr, i1) #3 +declare i1 @llvm.coro.end(ptr, i1, token) #3 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4 diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll index 923a93ca1694b..f916ebb915982 100644 --- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll +++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll @@ -55,7 +55,7 @@ cleanup: call ptr @llvm.coro.free(token %0, ptr %1) br label %coro.ret coro.ret: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } ; CHECK: %a.Frame = type { ptr, ptr, %"struct.task::promise_type", %struct.big_structure, i1 } @@ -69,6 +69,6 @@ declare token @llvm.coro.save(ptr) #3 declare ptr @llvm.coro.frame() #5 declare i8 @llvm.coro.suspend(token, i1) #3 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 -declare i1 @llvm.coro.end(ptr, i1) #3 +declare i1 @llvm.coro.end(ptr, i1, token) #3 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4 diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-03.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-03.ll index 94032607d98d6..525df873a0f0c 100644 --- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-03.ll +++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-03.ll @@ -50,7 +50,7 @@ cleanup: call void @free(ptr %mem) br label %coro.ret coro.ret: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -66,7 +66,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare double @print(double) diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll index 65a38e6da0a4c..27e0c47cb9042 100644 --- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll +++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll @@ -55,7 +55,7 @@ cleanup: call ptr @llvm.coro.free(token %0, ptr %1) br label %coro.ret coro.ret: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } ; CHECK: %a.Frame = type { ptr, ptr, %"struct.task::promise_type", %struct.big_structure, i1, [26 x i8], %struct.big_structure.2 } @@ -69,6 +69,6 @@ declare token @llvm.coro.save(ptr) #3 declare ptr @llvm.coro.frame() #5 declare i8 @llvm.coro.suspend(token, i1) #3 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 -declare i1 @llvm.coro.end(ptr, i1) #3 +declare i1 @llvm.coro.end(ptr, i1, token) #3 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4 diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll index 2722c9ec45616..6d93eeaa3211e 100644 --- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll +++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll @@ -55,7 +55,7 @@ cleanup: call ptr @llvm.coro.free(token %0, ptr %1) br label %coro.ret coro.ret: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } ; CHECK: %a.Frame = type { ptr, ptr, %"struct.task::promise_type", i1, [14 x i8], %struct.big_structure } @@ -69,6 +69,6 @@ declare token @llvm.coro.save(ptr) #3 declare ptr @llvm.coro.frame() #5 declare i8 @llvm.coro.suspend(token, i1) #3 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 -declare i1 @llvm.coro.end(ptr, i1) #3 +declare i1 @llvm.coro.end(ptr, i1, token) #3 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4 diff --git a/llvm/test/Transforms/Coroutines/coro-frame-unreachable.ll b/llvm/test/Transforms/Coroutines/coro-frame-unreachable.ll index 17d2250611b8e..b81f7d0ed7eac 100644 --- a/llvm/test/Transforms/Coroutines/coro-frame-unreachable.ll +++ b/llvm/test/Transforms/Coroutines/coro-frame-unreachable.ll @@ -24,7 +24,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl no.predecessors: @@ -43,7 +43,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @print(i1) diff --git a/llvm/test/Transforms/Coroutines/coro-frame.ll b/llvm/test/Transforms/Coroutines/coro-frame.ll index e7fa887a05fa2..c20be8ce2ff68 100644 --- a/llvm/test/Transforms/Coroutines/coro-frame.ll +++ b/llvm/test/Transforms/Coroutines/coro-frame.ll @@ -26,7 +26,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl pad: %tok = cleanuppad within none [] @@ -58,7 +58,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare double @print(double) diff --git a/llvm/test/Transforms/Coroutines/coro-materialize.ll b/llvm/test/Transforms/Coroutines/coro-materialize.ll index 7385337ab5750..8de81c3b8cfd3 100644 --- a/llvm/test/Transforms/Coroutines/coro-materialize.ll +++ b/llvm/test/Transforms/Coroutines/coro-materialize.ll @@ -41,7 +41,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -73,7 +73,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -109,7 +109,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -145,7 +145,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -186,7 +186,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -200,7 +200,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-noalias-param.ll b/llvm/test/Transforms/Coroutines/coro-noalias-param.ll index 67e51b1005f80..943d2a67978fa 100644 --- a/llvm/test/Transforms/Coroutines/coro-noalias-param.ll +++ b/llvm/test/Transforms/Coroutines/coro-noalias-param.ll @@ -19,7 +19,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret void } @@ -33,7 +33,7 @@ declare i32 @llvm.coro.size.i32() declare i8 @llvm.coro.suspend(token, i1) declare void @llvm.coro.resume(ptr) declare void @llvm.coro.destroy(ptr) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-padding.ll b/llvm/test/Transforms/Coroutines/coro-padding.ll index faed9b4b3b549..452b83bad388a 100644 --- a/llvm/test/Transforms/Coroutines/coro-padding.ll +++ b/llvm/test/Transforms/Coroutines/coro-padding.ll @@ -26,7 +26,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -54,7 +54,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare double @print(double) diff --git a/llvm/test/Transforms/Coroutines/coro-param-copy.ll b/llvm/test/Transforms/Coroutines/coro-param-copy.ll index 6e80577b56b39..83fa06b1a8cf6 100644 --- a/llvm/test/Transforms/Coroutines/coro-param-copy.ll +++ b/llvm/test/Transforms/Coroutines/coro-param-copy.ll @@ -41,7 +41,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -83,7 +83,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare void @llvm.memset.p0.i32(ptr, i8, i32, i1) diff --git a/llvm/test/Transforms/Coroutines/coro-preserve-final.ll b/llvm/test/Transforms/Coroutines/coro-preserve-final.ll index 730868a9f1ccd..16eeb84e7915a 100644 --- a/llvm/test/Transforms/Coroutines/coro-preserve-final.ll +++ b/llvm/test/Transforms/Coroutines/coro-preserve-final.ll @@ -80,7 +80,7 @@ coro.free: ; preds = %cleanup62 br label %coro.ret coro.ret: ; preds = %coro.free, %cleanup62, %final.suspend, %await2.suspend, %await.suspend, %init.suspend - %20 = call i1 @llvm.coro.end(ptr null, i1 false) #13 + %20 = call i1 @llvm.coro.end(ptr null, i1 false, token none) #13 ret ptr %__promise } @@ -96,7 +96,7 @@ declare i8 @llvm.coro.suspend(token, i1) #3 declare dso_local ptr @_Z5Innerv() local_unnamed_addr #8 declare dso_local void @_ZdlPv(ptr noundef) local_unnamed_addr #9 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 -declare i1 @llvm.coro.end(ptr, i1) #3 +declare i1 @llvm.coro.end(ptr, i1, token) #3 declare dso_local void @_Z5_exiti(i32 noundef) local_unnamed_addr #10 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #11 diff --git a/llvm/test/Transforms/Coroutines/coro-readnone-02.ll b/llvm/test/Transforms/Coroutines/coro-readnone-02.ll index c96377fd1c6d8..4ed962816154b 100644 --- a/llvm/test/Transforms/Coroutines/coro-readnone-02.ll +++ b/llvm/test/Transforms/Coroutines/coro-readnone-02.ll @@ -39,7 +39,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -75,7 +75,7 @@ declare i8 @llvm.coro.suspend(token, i1) 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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @free(ptr) diff --git a/llvm/test/Transforms/Coroutines/coro-readnone.ll b/llvm/test/Transforms/Coroutines/coro-readnone.ll index b7bcff45c4107..1fc91cefaf975 100644 --- a/llvm/test/Transforms/Coroutines/coro-readnone.ll +++ b/llvm/test/Transforms/Coroutines/coro-readnone.ll @@ -33,7 +33,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -83,7 +83,7 @@ declare i8 @llvm.coro.suspend(token, i1) 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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @free(ptr) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-alloca-opaque-ptr.ll b/llvm/test/Transforms/Coroutines/coro-retcon-alloca-opaque-ptr.ll index 879e368489a6a..112ffd215b1be 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-alloca-opaque-ptr.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-alloca-opaque-ptr.ll @@ -34,7 +34,7 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -69,7 +69,7 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -77,7 +77,7 @@ declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) declare void @llvm.coro.suspend.retcon.isVoid(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.prepare.retcon(ptr) declare token @llvm.coro.alloca.alloc.i32(i32, i32) declare ptr @llvm.coro.alloca.get(token) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll b/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll index ab3da8cde729a..fc009520fe4fa 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll @@ -33,7 +33,7 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -69,7 +69,7 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -102,7 +102,7 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -170,7 +170,7 @@ forward: br label %back end: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -217,7 +217,7 @@ non_alloca_block: br label %suspend cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -225,7 +225,7 @@ declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) declare void @llvm.coro.suspend.retcon.isVoid(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.prepare.retcon(ptr) declare token @llvm.coro.alloca.alloc.i32(i32, i32) declare ptr @llvm.coro.alloca.get(token) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-frame.ll b/llvm/test/Transforms/Coroutines/coro-retcon-frame.ll index 3418e07a9b0aa..a81cdf475ae31 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-frame.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-frame.ll @@ -32,7 +32,7 @@ resume: br label %end end: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } ; Make sure we don't lose writes to the frame. @@ -52,5 +52,5 @@ end: declare token @llvm.coro.id.retcon.once(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll b/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll index 3476db91dc85f..e7593cc8c6f81 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll @@ -30,14 +30,14 @@ neg.cont: br label %cleanup cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } declare token @llvm.coro.id.retcon.once(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.prepare.retcon(ptr) declare void @prototype(ptr, i1 zeroext) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll b/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll index c76a76c5fb85a..b67abfb051f35 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll @@ -1,21 +1,10 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs ; RUN: opt < %s -passes='default' -S | FileCheck %s target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.12.0" define {ptr, i32} @f(ptr %buffer, ptr %array) { -; CHECK-LABEL: @f( -; CHECK-NEXT: PostSpill: -; CHECK-NEXT: store ptr [[ARRAY:%.*]], ptr [[BUFFER:%.*]], align 8 -; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[ARRAY]], align 4 -; CHECK-NEXT: [[LOAD_POS:%.*]] = icmp sgt i32 [[LOAD]], 0 -; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[LOAD_POS]], ptr @f.resume.0, ptr @f.resume.1 -; CHECK-NEXT: [[SPEC_SELECT4:%.*]] = tail call i32 @llvm.smax.i32(i32 [[LOAD]], i32 0) -; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { ptr, i32 } poison, ptr [[SPEC_SELECT]], 0 -; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr, i32 } [[TMP0]], i32 [[SPEC_SELECT4]], 1 -; CHECK-NEXT: ret { ptr, i32 } [[TMP1]] -; entry: %id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) @@ -40,23 +29,11 @@ neg.cont: br label %cleanup cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } -define void @test(ptr %array) { -; CHECK-LABEL: @test( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = alloca [8 x i8], align 8 -; CHECK-NEXT: store ptr [[ARRAY:%.*]], ptr [[TMP0]], align 8 -; CHECK-NEXT: [[LOAD_I:%.*]] = load i32, ptr [[ARRAY]], align 4 -; CHECK-NEXT: [[LOAD_POS_I:%.*]] = icmp sgt i32 [[LOAD_I]], 0 -; CHECK-NEXT: [[SPEC_SELECT_I:%.*]] = select i1 [[LOAD_POS_I]], ptr @f.resume.0, ptr @f.resume.1 -; CHECK-NEXT: [[SPEC_SELECT4_I:%.*]] = tail call i32 @llvm.smax.i32(i32 [[LOAD_I]], i32 0) -; CHECK-NEXT: tail call void @print(i32 [[SPEC_SELECT4_I]]) -; CHECK-NEXT: call void [[SPEC_SELECT_I]](ptr nonnull [[TMP0]], i1 zeroext false) -; CHECK-NEXT: ret void -; +define void @test.f(ptr %array) { entry: %0 = alloca [8 x i8], align 8 %prepare = call ptr @llvm.coro.prepare.retcon(ptr @f) @@ -68,19 +45,179 @@ entry: ret void } +define {ptr, i32} @g(ptr %buffer, ptr %array, i32 %val) { +entry: + %id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer, ptr @prototype2, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) + %load = load i32, ptr %array + %load.pos = icmp sgt i32 %load, 0 + br i1 %load.pos, label %pos, label %neg + +pos: + %unwind0 = call i1 (...) @llvm.coro.suspend.retcon.i1(i32 %load) + br i1 %unwind0, label %cleanup, label %pos.cont + +pos.cont: + store i32 0, ptr %array, align 4 + br label %cleanup + +neg: + %unwind1 = call i1 (...) @llvm.coro.suspend.retcon.i1(i32 0) + br i1 %unwind1, label %cleanup, label %neg.cont + +neg.cont: + store i32 10, ptr %array, align 4 + br label %cleanup + +cleanup: + %new.val = add i32 %val, 123 + %tok = call token (...) @llvm.coro.end.results(ptr null, i32 %new.val, ptr @deallocate) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token %tok) + unreachable +} + +define void @test.g(ptr %array) { +entry: + %0 = alloca [8 x i8], align 8 + %prepare = call ptr @llvm.coro.prepare.retcon(ptr @f) + %yield.result = call {ptr, i32} %prepare(ptr %0, ptr %array) + %value = extractvalue {ptr, i32} %yield.result, 1 + call void @print(i32 %value) + %cont = extractvalue {ptr, i32} %yield.result, 0 + %normal.result = call {ptr, i32, ptr} %cont(ptr %0, i1 zeroext 0) + %value2 = extractvalue {ptr, i32, ptr} %normal.result, 1 + call void @print(i32 %value2) + ret void +} + ; Unfortunately, we don't seem to fully optimize this right now due ; to some sort of phase-ordering thing. declare token @llvm.coro.id.retcon.once(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) +declare token @llvm.coro.end.results(...) declare ptr @llvm.coro.prepare.retcon(ptr) declare void @prototype(ptr, i1 zeroext) +declare {ptr, i32, ptr} @prototype2(ptr, i1 zeroext) declare noalias ptr @allocate(i32 %size) declare void @deallocate(ptr %ptr) declare void @print(i32) +; CHECK-LABEL: @f( +; CHECK-NEXT: PostSpill: +; CHECK-NEXT: store ptr [[ARRAY:%.*]], ptr [[BUFFER:%.*]], align 8 +; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[ARRAY]], align 4 +; CHECK-NEXT: [[LOAD_POS:%.*]] = icmp sgt i32 [[LOAD]], 0 +; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[LOAD_POS]], ptr @f.resume.0, ptr @f.resume.1 +; CHECK-NEXT: [[SPEC_SELECT4:%.*]] = tail call i32 @llvm.smax.i32(i32 [[LOAD]], i32 0) +; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { ptr, i32 } poison, ptr [[SPEC_SELECT]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr, i32 } [[TMP0]], i32 [[SPEC_SELECT4]], 1 +; CHECK-NEXT: ret { ptr, i32 } [[TMP1]] +; +; +; CHECK-LABEL: @f.resume.0( +; CHECK-NEXT: entryresume.0: +; CHECK-NEXT: br i1 [[TMP1:%.*]], label [[COROEND:%.*]], label [[CLEANUP_SINK_SPLIT:%.*]] +; CHECK: cleanup.sink.split: +; CHECK-NEXT: [[ARRAY_RELOAD:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 +; CHECK-NEXT: store i32 0, ptr [[ARRAY_RELOAD]], align 4 +; CHECK-NEXT: br label [[COROEND]] +; CHECK: CoroEnd: +; CHECK-NEXT: ret void +; +; +; CHECK-LABEL: @f.resume.1( +; CHECK-NEXT: entryresume.1: +; CHECK-NEXT: br i1 [[TMP1:%.*]], label [[COROEND:%.*]], label [[CLEANUP_SINK_SPLIT:%.*]] +; CHECK: cleanup.sink.split: +; CHECK-NEXT: [[ARRAY_RELOAD:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 +; CHECK-NEXT: store i32 10, ptr [[ARRAY_RELOAD]], align 4 +; CHECK-NEXT: br label [[COROEND]] +; CHECK: CoroEnd: +; CHECK-NEXT: ret void +; +; +; CHECK-LABEL: @test.f( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = alloca [8 x i8], align 8 +; CHECK-NEXT: store ptr [[ARRAY:%.*]], ptr [[TMP0]], align 8 +; CHECK-NEXT: [[LOAD_I:%.*]] = load i32, ptr [[ARRAY]], align 4 +; CHECK-NEXT: [[LOAD_POS_I:%.*]] = icmp sgt i32 [[LOAD_I]], 0 +; CHECK-NEXT: [[SPEC_SELECT_I:%.*]] = select i1 [[LOAD_POS_I]], ptr @f.resume.0, ptr @f.resume.1 +; CHECK-NEXT: [[SPEC_SELECT4_I:%.*]] = tail call i32 @llvm.smax.i32(i32 [[LOAD_I]], i32 0) +; CHECK-NEXT: tail call void @print(i32 [[SPEC_SELECT4_I]]) +; CHECK-NEXT: call void [[SPEC_SELECT_I]](ptr nonnull [[TMP0]], i1 zeroext false) +; CHECK-NEXT: ret void +; +; +; CHECK-LABEL: @g( +; CHECK-NEXT: PostSpill: +; CHECK-NEXT: [[TMP0:%.*]] = tail call ptr @allocate(i32 16) +; CHECK-NEXT: store ptr [[TMP0]], ptr [[BUFFER:%.*]], align 8 +; CHECK-NEXT: [[VAL_SPILL_ADDR:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], ptr [[TMP0]], i64 0, i32 1 +; CHECK-NEXT: store i32 [[VAL:%.*]], ptr [[VAL_SPILL_ADDR]], align 4 +; CHECK-NEXT: store ptr [[ARRAY:%.*]], ptr [[TMP0]], align 8 +; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[ARRAY]], align 4 +; CHECK-NEXT: [[LOAD_POS:%.*]] = icmp sgt i32 [[LOAD]], 0 +; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[LOAD_POS]], ptr @g.resume.0, ptr @g.resume.1 +; CHECK-NEXT: [[SPEC_SELECT4:%.*]] = tail call i32 @llvm.smax.i32(i32 [[LOAD]], i32 0) +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr, i32 } poison, ptr [[SPEC_SELECT]], 0 +; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr, i32 } [[TMP1]], i32 [[SPEC_SELECT4]], 1 +; CHECK-NEXT: ret { ptr, i32 } [[TMP2]] +; +; +; CHECK-LABEL: @g.resume.0( +; CHECK-NEXT: entryresume.0: +; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 +; CHECK-NEXT: br i1 [[TMP1:%.*]], label [[COROEND:%.*]], label [[CLEANUP_SINK_SPLIT:%.*]] +; CHECK: cleanup.sink.split: +; CHECK-NEXT: [[ARRAY_RELOAD:%.*]] = load ptr, ptr [[TMP2]], align 8 +; CHECK-NEXT: store i32 0, ptr [[ARRAY_RELOAD]], align 4 +; CHECK-NEXT: br label [[COROEND]] +; CHECK: CoroEnd: +; CHECK-NEXT: [[VAL_RELOAD_ADDR:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], ptr [[TMP2]], i64 0, i32 1 +; CHECK-NEXT: [[VAL_RELOAD:%.*]] = load i32, ptr [[VAL_RELOAD_ADDR]], align 4 +; CHECK-NEXT: [[NEW_VAL:%.*]] = add i32 [[VAL_RELOAD]], 123 +; CHECK-NEXT: tail call void @deallocate(ptr [[TMP2]]) +; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { ptr, i32, ptr } { ptr null, i32 undef, ptr undef }, i32 [[NEW_VAL]], 1 +; CHECK-NEXT: [[TMP4:%.*]] = insertvalue { ptr, i32, ptr } [[TMP3]], ptr @deallocate, 2 +; CHECK-NEXT: ret { ptr, i32, ptr } [[TMP4]] +; +; +; CHECK-LABEL: @g.resume.1( +; CHECK-NEXT: entryresume.1: +; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 +; CHECK-NEXT: br i1 [[TMP1:%.*]], label [[COROEND:%.*]], label [[CLEANUP_SINK_SPLIT:%.*]] +; CHECK: cleanup.sink.split: +; CHECK-NEXT: [[ARRAY_RELOAD:%.*]] = load ptr, ptr [[TMP2]], align 8 +; CHECK-NEXT: store i32 10, ptr [[ARRAY_RELOAD]], align 4 +; CHECK-NEXT: br label [[COROEND]] +; CHECK: CoroEnd: +; CHECK-NEXT: [[VAL_RELOAD_ADDR:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], ptr [[TMP2]], i64 0, i32 1 +; CHECK-NEXT: [[VAL_RELOAD:%.*]] = load i32, ptr [[VAL_RELOAD_ADDR]], align 4 +; CHECK-NEXT: [[NEW_VAL:%.*]] = add i32 [[VAL_RELOAD]], 123 +; CHECK-NEXT: tail call void @deallocate(ptr [[TMP2]]) +; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { ptr, i32, ptr } { ptr null, i32 undef, ptr undef }, i32 [[NEW_VAL]], 1 +; CHECK-NEXT: [[TMP4:%.*]] = insertvalue { ptr, i32, ptr } [[TMP3]], ptr @deallocate, 2 +; CHECK-NEXT: ret { ptr, i32, ptr } [[TMP4]] +; +; +; CHECK-LABEL: @test.g( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = alloca [8 x i8], align 8 +; CHECK-NEXT: store ptr [[ARRAY:%.*]], ptr [[TMP0]], align 8 +; CHECK-NEXT: [[LOAD_I:%.*]] = load i32, ptr [[ARRAY]], align 4 +; CHECK-NEXT: [[LOAD_POS_I:%.*]] = icmp sgt i32 [[LOAD_I]], 0 +; CHECK-NEXT: [[SPEC_SELECT_I:%.*]] = select i1 [[LOAD_POS_I]], ptr @f.resume.0, ptr @f.resume.1 +; CHECK-NEXT: [[SPEC_SELECT4_I:%.*]] = tail call i32 @llvm.smax.i32(i32 [[LOAD_I]], i32 0) +; CHECK-NEXT: tail call void @print(i32 [[SPEC_SELECT4_I]]) +; CHECK-NEXT: [[NORMAL_RESULT:%.*]] = call { ptr, i32, ptr } [[SPEC_SELECT_I]](ptr nonnull [[TMP0]], i1 zeroext false) +; CHECK-NEXT: [[VALUE2:%.*]] = extractvalue { ptr, i32, ptr } [[NORMAL_RESULT]], 1 +; CHECK-NEXT: call void @print(i32 [[VALUE2]]) +; CHECK-NEXT: ret void +; diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll b/llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll index 17a0a1d0e6b9e..c33e60e98cd8b 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll @@ -19,18 +19,64 @@ cont: br label %cleanup cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } +define {ptr, ptr} @g(ptr %buffer, ptr %ptr, i8 %val) presplitcoroutine { +entry: + %temp = alloca i32, align 4 + %id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer, ptr @prototype2, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) + %oldvalue = load i32, ptr %ptr + store i32 %oldvalue, ptr %temp + %unwind = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr %temp) + br i1 %unwind, label %cleanup, label %cont + +cont: + %newvalue = load i32, ptr %temp + store i32 %newvalue, ptr %ptr + br label %cleanup + +cleanup: + %tok = call token (...) @llvm.coro.end.results(i8 %val) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token %tok) + unreachable +} + + +define {ptr, ptr} @h(ptr %buffer, ptr %ptr) presplitcoroutine { +entry: + %temp = alloca i32, align 4 + %id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer, ptr @prototype3, ptr @allocate, ptr @deallocate) + %hdl = call ptr @llvm.coro.begin(token %id, ptr null) + %oldvalue = load i32, ptr %ptr + store i32 %oldvalue, ptr %temp + %unwind = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr %temp) + br i1 %unwind, label %cleanup, label %cont + +cont: + %newvalue = load i32, ptr %temp + store i32 %newvalue, ptr %ptr + br label %cleanup + +cleanup: + %tok = call token (...) @llvm.coro.end.results(ptr null, i32 123, ptr @deallocate) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token %tok) + unreachable +} + declare token @llvm.coro.id.retcon.once(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) +declare token @llvm.coro.end.results(...) declare void @prototype(ptr, i1 zeroext) +declare i8 @prototype2(ptr, i1 zeroext) +declare {ptr, i32, ptr} @prototype3(ptr, i1 zeroext) declare noalias ptr @allocate(i32 %size) declare fastcc void @deallocate(ptr %ptr) @@ -44,21 +90,79 @@ declare void @print(i32) ; CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[TMP0]], align 8 ; CHECK-NEXT: [[OLDVALUE:%.*]] = load i32, ptr [[PTR]], align 4 ; CHECK-NEXT: store i32 [[OLDVALUE]], ptr [[TEMP]], align 4 -; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr, ptr } { ptr @f.resume.0, ptr poison }, ptr [[TEMP]], 1 -; CHECK-NEXT: ret { ptr, ptr } [[TMP2]] +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr, ptr } { ptr @f.resume.0, ptr poison }, ptr [[TEMP]], 1 +; CHECK-NEXT: ret { ptr, ptr } [[TMP1]] ; ; ; CHECK-LABEL: @f.resume.0( ; CHECK-NEXT: entryresume.0: -; CHECK-NEXT: [[FRAMEPTR:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 -; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[FRAMEPTR]], i32 0, i32 1 +; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 +; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[TMP2]], i32 0, i32 1 ; CHECK-NEXT: br i1 [[TMP1:%.*]], label [[COROEND:%.*]], label [[CONT:%.*]] ; CHECK: cont: -; CHECK-NEXT: [[PTR_RELOAD:%.*]] = load ptr, ptr [[FRAMEPTR]], align 8 +; CHECK-NEXT: [[PTR_RELOAD:%.*]] = load ptr, ptr [[TMP2]], align 8 ; CHECK-NEXT: [[NEWVALUE:%.*]] = load i32, ptr [[TEMP]], align 4 ; CHECK-NEXT: store i32 [[NEWVALUE]], ptr [[PTR_RELOAD]], align 4 ; CHECK-NEXT: br label [[COROEND]] ; CHECK: CoroEnd: -; CHECK-NEXT: call fastcc void @deallocate(ptr [[FRAMEPTR]]) +; CHECK-NEXT: call fastcc void @deallocate(ptr [[TMP2]]) ; CHECK-NEXT: ret void ; +; +; CHECK-LABEL: @g( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = call ptr @allocate(i32 16) +; CHECK-NEXT: store ptr [[TMP0]], ptr [[BUFFER:%.*]], align 8 +; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], ptr [[TMP0]], i32 0, i32 1 +; CHECK-NEXT: [[VAL_SPILL_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], ptr [[TMP0]], i32 0, i32 2 +; CHECK-NEXT: store i8 [[VAL:%.*]], ptr [[VAL_SPILL_ADDR]], align 1 +; CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[TMP0]], align 8 +; CHECK-NEXT: [[OLDVALUE:%.*]] = load i32, ptr [[PTR]], align 4 +; CHECK-NEXT: store i32 [[OLDVALUE]], ptr [[TEMP]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr, ptr } { ptr @g.resume.0, ptr poison }, ptr [[TEMP]], 1 +; CHECK-NEXT: ret { ptr, ptr } [[TMP1]] +; +; +; CHECK-LABEL: @g.resume.0( +; CHECK-NEXT: entryresume.0: +; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 +; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], ptr [[TMP2]], i32 0, i32 1 +; CHECK-NEXT: br i1 [[TMP1:%.*]], label [[CLEANUP:%.*]], label [[CONT:%.*]] +; CHECK: cont: +; CHECK-NEXT: [[PTR_RELOAD:%.*]] = load ptr, ptr [[TMP2]], align 8 +; CHECK-NEXT: [[NEWVALUE:%.*]] = load i32, ptr [[TEMP]], align 4 +; CHECK-NEXT: store i32 [[NEWVALUE]], ptr [[PTR_RELOAD]], align 4 +; CHECK-NEXT: br label [[CLEANUP]] +; CHECK: cleanup: +; CHECK-NEXT: [[VAL_RELOAD_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], ptr [[TMP2]], i32 0, i32 2 +; CHECK-NEXT: [[VAL_RELOAD:%.*]] = load i8, ptr [[VAL_RELOAD_ADDR]], align 1 +; CHECK-NEXT: call fastcc void @deallocate(ptr [[TMP2]]) +; CHECK-NEXT: ret i8 [[VAL_RELOAD]] +; +; +; CHECK-LABEL: @h( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = call ptr @allocate(i32 16) +; CHECK-NEXT: store ptr [[TMP0]], ptr [[BUFFER:%.*]], align 8 +; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds [[H_FRAME:%.*]], ptr [[TMP0]], i32 0, i32 1 +; CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[TMP0]], align 8 +; CHECK-NEXT: [[OLDVALUE:%.*]] = load i32, ptr [[PTR]], align 4 +; CHECK-NEXT: store i32 [[OLDVALUE]], ptr [[TEMP]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr, ptr } { ptr @h.resume.0, ptr poison }, ptr [[TEMP]], 1 +; CHECK-NEXT: ret { ptr, ptr } [[TMP1]] +; +; +; CHECK-LABEL: @h.resume.0( +; CHECK-NEXT: entryresume.0: +; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 +; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds [[H_FRAME:%.*]], ptr [[TMP2]], i32 0, i32 1 +; CHECK-NEXT: br i1 [[TMP1:%.*]], label [[COROEND:%.*]], label [[CONT:%.*]] +; CHECK: cont: +; CHECK-NEXT: [[PTR_RELOAD:%.*]] = load ptr, ptr [[TMP2]], align 8 +; CHECK-NEXT: [[NEWVALUE:%.*]] = load i32, ptr [[TEMP]], align 4 +; CHECK-NEXT: store i32 [[NEWVALUE]], ptr [[PTR_RELOAD]], align 4 +; CHECK-NEXT: br label [[COROEND]] +; CHECK: CoroEnd: +; CHECK-NEXT: call fastcc void @deallocate(ptr [[TMP2]]) +; CHECK-NEXT: ret { ptr, i32, ptr } { ptr null, i32 123, ptr @deallocate } +; diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll b/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll index 559d3af024694..f456b6e7bc858 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll @@ -26,7 +26,7 @@ resume: ; preds = %loop br label %loop cleanup: ; preds = %loop - %0 = call i1 @llvm.coro.end(ptr %hdl, i1 false) + %0 = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) unreachable } @@ -70,14 +70,14 @@ resume: ; preds = %loop br label %loop cleanup: ; preds = %loop - %0 = call i1 @llvm.coro.end(ptr %hdl, i1 false) + %0 = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) unreachable } declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.prepare.retcon(ptr) declare ptr @prototype(ptr, i1 zeroext) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll b/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll index 70de163caff5d..fd16ba96181b9 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll @@ -31,14 +31,14 @@ resume1: br label %loop cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.prepare.retcon(ptr) declare { ptr, i32 } @f_prototype(ptr, i1 zeroext) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll index 09a17f8ab3b38..f4333a12bb34a 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll @@ -27,7 +27,7 @@ resume: cleanup: call void @print(i32 %n.val) - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -66,7 +66,7 @@ entry: declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare { i32, i1 } @llvm.coro.suspend.retcon.sl_i32i1s(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.prepare.retcon(ptr) declare ptr @prototype(ptr, i32, i1 zeroext) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll index 7c00464211034..2caa6430ca012 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll @@ -15,14 +15,14 @@ entry: %sum4 = call i32 @add(i32 %sum3, i32 %value1) %sum5 = call i32 @add(i32 %sum4, i32 %value2) call void @print(i32 %sum5) - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i32 @llvm.coro.suspend.retcon.i32(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.prepare.retcon(ptr) declare ptr @prototype(ptr, i32) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-unreachable.ll b/llvm/test/Transforms/Coroutines/coro-retcon-unreachable.ll index f598e0a3e0d7c..8ed03849fb63b 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-unreachable.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-unreachable.ll @@ -23,7 +23,7 @@ define hidden swiftcc { ptr, ptr } @no_suspends(ptr %buffer, i64 %arg) #1 { bb1: call void @print(i64 %arg) - call i1 @llvm.coro.end(ptr %begin, i1 false) + call i1 @llvm.coro.end(ptr %begin, i1 false, token none) unreachable } @@ -41,7 +41,7 @@ declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #6 declare i1 @llvm.coro.suspend.retcon.i1(...) #5 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #6 declare void @llvm.coro.alloca.free(token) #5 -declare i1 @llvm.coro.end(ptr, i1) #5 +declare i1 @llvm.coro.end(ptr, i1, token) #5 declare void @llvm.trap() diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-value.ll b/llvm/test/Transforms/Coroutines/coro-retcon-value.ll index 0b0f5dfd56c95..6a150c6a79807 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-value.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-value.ll @@ -25,7 +25,7 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -64,7 +64,7 @@ entry: declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i8 @llvm.coro.suspend.retcon.i8(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.prepare.retcon(ptr) declare {ptr, i32} @prototype(ptr, i8 zeroext) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon.ll b/llvm/test/Transforms/Coroutines/coro-retcon.ll index 774c609ed6c44..b12a646ef53f9 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon.ll @@ -33,7 +33,7 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -103,7 +103,7 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -137,14 +137,14 @@ cleanup: call void @use_var_ptr(ptr %a) %al = load i32, ptr %a call void @use_var(i32 %al) - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.prepare.retcon(ptr) declare void @use_var(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll b/llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll index a464c8ac2e221..cbe57a8d61132 100644 --- a/llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll +++ b/llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll @@ -50,7 +50,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -63,7 +63,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare i32 @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll b/llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll index 9653bd5b28eea..f238955d1c3e9 100644 --- a/llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll +++ b/llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll @@ -33,7 +33,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -62,7 +62,7 @@ declare i8 @llvm.coro.suspend(token, i1) 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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @print.i32(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll b/llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll index 12b24df00c1de..801c4a1776135 100644 --- a/llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll +++ b/llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll @@ -36,7 +36,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl lpad: @@ -70,7 +70,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare i32 @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-spill-promise-02.ll b/llvm/test/Transforms/Coroutines/coro-spill-promise-02.ll index 411067362825e..3293e5c84b987 100644 --- a/llvm/test/Transforms/Coroutines/coro-spill-promise-02.ll +++ b/llvm/test/Transforms/Coroutines/coro-spill-promise-02.ll @@ -29,7 +29,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -57,7 +57,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare double @print(double) diff --git a/llvm/test/Transforms/Coroutines/coro-spill-promise.ll b/llvm/test/Transforms/Coroutines/coro-spill-promise.ll index 8e15d41a1c35b..47e891a57d222 100644 --- a/llvm/test/Transforms/Coroutines/coro-spill-promise.ll +++ b/llvm/test/Transforms/Coroutines/coro-spill-promise.ll @@ -28,7 +28,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -48,7 +48,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare double @print(double) diff --git a/llvm/test/Transforms/Coroutines/coro-split-00.ll b/llvm/test/Transforms/Coroutines/coro-split-00.ll index c75aff50dab6c..b35bd720b86f9 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-00.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-00.ll @@ -28,7 +28,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -72,7 +72,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) allockind("alloc,uninitialized") "alloc-family"="malloc" declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-split-01.ll b/llvm/test/Transforms/Coroutines/coro-split-01.ll index 039f80db57acf..7a03495e75d8d 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-01.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-01.ll @@ -26,7 +26,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } define i32 @main() { @@ -49,7 +49,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-split-02.ll b/llvm/test/Transforms/Coroutines/coro-split-02.ll index ed09f009f9b83..31e8e8155035c 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-02.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-02.ll @@ -34,7 +34,7 @@ await.ready: call void @print(i32 %val) br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -60,6 +60,6 @@ declare ptr @llvm.coro.frame() #5 declare i8 @llvm.coro.suspend(token, i1) #3 declare void @"\01??3@YAXPEAX@Z"(ptr) local_unnamed_addr #10 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 -declare i1 @llvm.coro.end(ptr, i1) #3 +declare i1 @llvm.coro.end(ptr, i1, token) #3 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4 diff --git a/llvm/test/Transforms/Coroutines/coro-split-alloc.ll b/llvm/test/Transforms/Coroutines/coro-split-alloc.ll index 8759c525b65ab..f6f50e2f3c76c 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-alloc.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-alloc.ll @@ -33,7 +33,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -57,7 +57,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @custom_alloctor(i32, i32) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-split-dbg.ll b/llvm/test/Transforms/Coroutines/coro-split-dbg.ll index 781571d4a2ce4..184d4a564ab72 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-dbg.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-dbg.ll @@ -38,7 +38,7 @@ coro_Cleanup: ; preds = %for.cond br label %coro_Suspend, !dbg !36 coro_Suspend: ; preds = %for.cond, %if.then, %coro_Cleanup - tail call i1 @llvm.coro.end(ptr null, i1 false) #9, !dbg !38 + tail call i1 @llvm.coro.end(ptr null, i1 false, token none) #9, !dbg !38 ret ptr %2, !dbg !39 } @@ -57,7 +57,7 @@ declare i8 @llvm.coro.suspend(token, i1) #7 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #5 declare void @free(ptr nocapture) local_unnamed_addr #6 -declare i1 @llvm.coro.end(ptr, i1) #7 +declare i1 @llvm.coro.end(ptr, i1, token) #7 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #5 declare void @llvm.dbg.value(metadata, metadata, metadata) #1 diff --git a/llvm/test/Transforms/Coroutines/coro-split-eh-00.ll b/llvm/test/Transforms/Coroutines/coro-split-eh-00.ll index d2bb1bbb98891..d7d60bb2bfa22 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-eh-00.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-eh-00.ll @@ -17,7 +17,7 @@ resume: invoke void @print(i32 1) to label %suspend unwind label %lpad suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) call void @print(i32 0) ; should not be present in f.resume ret ptr %hdl @@ -26,7 +26,7 @@ lpad: cleanup call void @print(i32 2) - %need.resume = call i1 @llvm.coro.end(ptr null, i1 true) + %need.resume = call i1 @llvm.coro.end(ptr null, i1 true, token none) br i1 %need.resume, label %eh.resume, label %cleanup.cont cleanup.cont: @@ -80,7 +80,7 @@ declare void @llvm.coro.destroy(ptr) declare token @llvm.coro.id(i32, ptr, ptr, ptr) declare ptr @llvm.coro.alloc(token) declare ptr @llvm.coro.begin(token, ptr) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-split-eh-01.ll b/llvm/test/Transforms/Coroutines/coro-split-eh-01.ll index 835d399d55b54..b25c4b9f5a700 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-eh-01.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-eh-01.ll @@ -17,14 +17,14 @@ resume: invoke void @print(i32 1) to label %suspend unwind label %lpad suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) call void @print(i32 0) ; should not be present in f.resume ret ptr %hdl lpad: %tok = cleanuppad within none [] call void @print(i32 2) - %unused = call i1 @llvm.coro.end(ptr null, i1 true) [ "funclet"(token %tok) ] + %unused = call i1 @llvm.coro.end(ptr null, i1 true, token none) [ "funclet"(token %tok) ] cleanupret from %tok unwind label %cleanup.cont cleanup.cont: @@ -74,7 +74,7 @@ declare void @llvm.coro.destroy(ptr) declare token @llvm.coro.id(i32, ptr, ptr, ptr) declare ptr @llvm.coro.alloc(token) declare ptr @llvm.coro.begin(token, ptr) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-split-final-suspend.ll b/llvm/test/Transforms/Coroutines/coro-split-final-suspend.ll index df99e8905b7b9..fbefd43f73c36 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-final-suspend.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-final-suspend.ll @@ -28,7 +28,7 @@ resume: invoke void @print(i32 1) to label %suspend unwind label %lpad suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) call void @print(i32 0) ret ptr %hdl @@ -37,7 +37,7 @@ lpad: cleanup call void @print(i32 2) - %need.resume = call i1 @llvm.coro.end(ptr null, i1 true) + %need.resume = call i1 @llvm.coro.end(ptr null, i1 true, token none) br i1 %need.resume, label %eh.resume, label %cleanup.cont cleanup.cont: @@ -97,7 +97,7 @@ resume: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) call void @print(i32 0) ret ptr %hdl } @@ -122,7 +122,7 @@ declare void @llvm.coro.destroy(ptr) declare token @llvm.coro.id(i32, ptr, ptr, ptr) declare ptr @llvm.coro.alloc(token) declare ptr @llvm.coro.begin(token, ptr) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-split-hidden.ll b/llvm/test/Transforms/Coroutines/coro-split-hidden.ll index aebc0bb8d93ba..fa4f0ab13bebc 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-hidden.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-hidden.ll @@ -30,7 +30,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -74,7 +74,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) allockind("alloc,uninitialized") declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail-ppc64le.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail-ppc64le.ll index 41787c4a31ea9..e8596b78460a5 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail-ppc64le.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail-ppc64le.ll @@ -36,7 +36,7 @@ await.ready: i8 1, label %exit ] exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -58,7 +58,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail.ll index 718e272c1d46f..0406135687904 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail.ll @@ -28,7 +28,7 @@ await.ready: i8 1, label %exit ] exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -51,7 +51,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail1.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail1.ll index 3a1e8694b2773..cd1635b93d2cc 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail1.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail1.ll @@ -48,7 +48,7 @@ final.suspend: pre.exit: br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void unreach: unreachable @@ -83,7 +83,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) declare i8 @switch_result() diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail10.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail10.ll index c8f681cbcf6cd..9d73c8bbc57b8 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail10.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail10.ll @@ -30,7 +30,7 @@ await.ready: i8 1, label %exit ] exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -44,7 +44,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail11.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail11.ll index e892fa9fc21cc..9bc5b4f0c65d9 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail11.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail11.ll @@ -30,7 +30,7 @@ await.ready: i8 1, label %exit ] exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -44,7 +44,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail12.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail12.ll index 66f640c34f774..e7f4bcb9b0ff2 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail12.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail12.ll @@ -55,7 +55,7 @@ coro.free: br label %coro.end coro.end: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -72,7 +72,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) declare void @delete(ptr nonnull) #2 diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail13.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail13.ll index 29823cee57a08..2384f9382685b 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail13.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail13.ll @@ -38,7 +38,7 @@ lpad: %lpval = landingpad { ptr, i32 } cleanup - %need.resume = call i1 @llvm.coro.end(ptr null, i1 true) + %need.resume = call i1 @llvm.coro.end(ptr null, i1 true, token none) resume { ptr, i32 } %lpval coro.free: @@ -46,7 +46,7 @@ coro.free: br label %coro.end coro.end: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -63,7 +63,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) declare void @delete(ptr nonnull) #2 diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail2.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail2.ll index 8dc347b7c4ae9..38fc12815c033 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail2.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail2.ll @@ -36,7 +36,7 @@ await.ready: i8 1, label %exit ] exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -57,7 +57,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail3.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail3.ll index 30ab7a2e861ac..b777f000e33a6 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail3.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail3.ll @@ -44,7 +44,7 @@ final.suspend: pre.exit: br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void unreach: unreachable @@ -79,7 +79,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) declare i8 @switch_result() diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail4.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail4.ll index 93bb7ef49f290..1e0fcdb87a72d 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail4.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail4.ll @@ -38,7 +38,7 @@ coro.free: br label %coro.end coro.end: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -54,7 +54,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) declare void @delete(ptr nonnull) #2 diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail5.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail5.ll index b892b6b304099..d19606491335e 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail5.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail5.ll @@ -32,7 +32,7 @@ await.ready: call void @llvm.lifetime.end.p0(i64 1, ptr %alloc.var) br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -49,7 +49,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) declare void @consume(ptr) diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail6.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail6.ll index 846d2b5ab6b2a..eea711861c488 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail6.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail6.ll @@ -35,7 +35,7 @@ await.ready: call void @llvm.lifetime.end.p0(i64 1, ptr %alloc.var) br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -83,7 +83,7 @@ coro.free: br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -101,7 +101,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) declare void @delete(ptr nonnull) #2 diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll index 3280bfd603279..c32fe9b0ee304 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll @@ -35,7 +35,7 @@ await.ready: call void @llvm.lifetime.end.p0(i64 1, ptr %alloc.var) br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -83,7 +83,7 @@ coro.free: br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -101,7 +101,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) declare void @delete(ptr nonnull) #2 diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail8.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail8.ll index 25da65e2c4400..31b18d746be5f 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail8.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail8.ll @@ -32,7 +32,7 @@ await.ready: i8 1, label %exit ] exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -46,7 +46,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) declare void @print() diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail9.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail9.ll index 6b41cad6be35c..76376dbbbe3d8 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail9.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail9.ll @@ -32,7 +32,7 @@ await.ready: i8 1, label %exit ] exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -46,7 +46,7 @@ declare token @llvm.coro.save(ptr) #2 declare ptr @llvm.coro.frame() #3 declare i8 @llvm.coro.suspend(token, i1) #2 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1) #2 +declare i1 @llvm.coro.end(ptr, i1, token) #2 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 declare ptr @malloc(i64) declare void @print() diff --git a/llvm/test/Transforms/Coroutines/coro-split-no-lieftime.ll b/llvm/test/Transforms/Coroutines/coro-split-no-lieftime.ll index bdd3747ecad67..157807dc05363 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-no-lieftime.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-no-lieftime.ll @@ -37,7 +37,7 @@ cleanup: br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -52,7 +52,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare void @llvm.lifetime.start.p0(i64, ptr nocapture) declare void @llvm.lifetime.end.p0(i64, ptr nocapture) diff --git a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll index 442e1d24e85de..1d0cf94c1a979 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll @@ -37,7 +37,7 @@ await.ready: call void @print(i32 %val) br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -76,7 +76,7 @@ await.ready: call void @print(i32 %val) br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -91,6 +91,6 @@ declare ptr @llvm.coro.frame() #5 declare i8 @llvm.coro.suspend(token, i1) #3 declare void @"\01??3@YAXPEAX@Z"(ptr) local_unnamed_addr #10 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 -declare i1 @llvm.coro.end(ptr, i1) #3 +declare i1 @llvm.coro.end(ptr, i1, token) #3 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4 diff --git a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll index 771468cd4ac02..38a2a33efe051 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll @@ -48,7 +48,7 @@ after.await: br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -68,6 +68,6 @@ declare ptr @llvm.coro.frame() #5 declare i8 @llvm.coro.suspend(token, i1) #3 declare void @"\01??3@YAXPEAX@Z"(ptr) local_unnamed_addr #10 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 -declare i1 @llvm.coro.end(ptr, i1) #3 +declare i1 @llvm.coro.end(ptr, i1, token) #3 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4 diff --git a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-03.ll b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-03.ll index 6b845f97368eb..de377a6a38b94 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-03.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-03.ll @@ -36,7 +36,7 @@ await.ready: call void @print(i32 %val) br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } ; CHECK-LABEL: @a.gep.resume( @@ -59,6 +59,6 @@ declare ptr @llvm.coro.frame() #5 declare i8 @llvm.coro.suspend(token, i1) #3 declare void @"\01??3@YAXPEAX@Z"(ptr) local_unnamed_addr #10 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 -declare i1 @llvm.coro.end(ptr, i1) #3 +declare i1 @llvm.coro.end(ptr, i1, token) #3 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4 diff --git a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-04.ll b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-04.ll index ddb45108d6786..821045583092d 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-04.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-04.ll @@ -35,7 +35,7 @@ await.ready: call void @print(i32 %val) br label %exit exit: - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 @llvm.coro.end(ptr null, i1 false, token none) ret void } @@ -61,6 +61,6 @@ declare ptr @llvm.coro.frame() #5 declare i8 @llvm.coro.suspend(token, i1) #3 declare void @"\01??3@YAXPEAX@Z"(ptr) local_unnamed_addr #10 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2 -declare i1 @llvm.coro.end(ptr, i1) #3 +declare i1 @llvm.coro.end(ptr, i1, token) #3 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4 diff --git a/llvm/test/Transforms/Coroutines/coro-swifterror.ll b/llvm/test/Transforms/Coroutines/coro-swifterror.ll index 1fba4e4163102..f192dbac3197e 100644 --- a/llvm/test/Transforms/Coroutines/coro-swifterror.ll +++ b/llvm/test/Transforms/Coroutines/coro-swifterror.ll @@ -34,7 +34,7 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -76,7 +76,7 @@ resume: br label %loop cleanup: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) unreachable } @@ -86,7 +86,7 @@ declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) declare { i1, ptr } @llvm.coro.suspend.retcon.i1p0p0i8(...) declare i1 @llvm.coro.suspend.retcon.i1(...) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.prepare.retcon(ptr) declare ptr @f_prototype(ptr, i1 zeroext, ptr swifterror) diff --git a/llvm/test/Transforms/Coroutines/coro-zero-alloca.ll b/llvm/test/Transforms/Coroutines/coro-zero-alloca.ll index 14a5be073211c..e3f09ba29cbf7 100644 --- a/llvm/test/Transforms/Coroutines/coro-zero-alloca.ll +++ b/llvm/test/Transforms/Coroutines/coro-zero-alloca.ll @@ -9,7 +9,7 @@ declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) declare i64 @llvm.coro.size.i64() declare ptr @llvm.coro.begin(token, ptr writeonly) declare i8 @llvm.coro.suspend(token, i1) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.free(token, ptr nocapture readonly) declare token @llvm.coro.save(ptr) @@ -42,7 +42,7 @@ wakeup: ; preds = %entry br label %cleanup suspend: ; preds = %cleanup, %entry - %unused = call i1 @llvm.coro.end(ptr %coro.state, i1 false) + %unused = call i1 @llvm.coro.end(ptr %coro.state, i1 false, token none) ret void cleanup: ; preds = %wakeup, %entry diff --git a/llvm/test/Transforms/Coroutines/ex0.ll b/llvm/test/Transforms/Coroutines/ex0.ll index 4ef0910e5e72d..9809488c85b37 100644 --- a/llvm/test/Transforms/Coroutines/ex0.ll +++ b/llvm/test/Transforms/Coroutines/ex0.ll @@ -24,7 +24,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -52,7 +52,7 @@ declare void @llvm.coro.resume(ptr) declare void @llvm.coro.destroy(ptr) declare ptr @llvm.coro.begin(token, ptr) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/ex1.ll b/llvm/test/Transforms/Coroutines/ex1.ll index fd969c2c1f6a8..2db5ef6067cad 100644 --- a/llvm/test/Transforms/Coroutines/ex1.ll +++ b/llvm/test/Transforms/Coroutines/ex1.ll @@ -20,7 +20,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret ptr %hdl } @@ -48,7 +48,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) +declare i1 @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/ex2.ll b/llvm/test/Transforms/Coroutines/ex2.ll index ade3bc7b98852..d9999d46b38cf 100644 --- a/llvm/test/Transforms/Coroutines/ex2.ll +++ b/llvm/test/Transforms/Coroutines/ex2.ll @@ -29,7 +29,7 @@ dyn.free: call void @CustomFree(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret ptr %hdl } @@ -63,7 +63,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) +declare i1 @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/ex3.ll b/llvm/test/Transforms/Coroutines/ex3.ll index 60dfc33bf1359..e7fbc97d8f14f 100644 --- a/llvm/test/Transforms/Coroutines/ex3.ll +++ b/llvm/test/Transforms/Coroutines/ex3.ll @@ -32,7 +32,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret ptr %hdl } @@ -67,7 +67,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) +declare i1 @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/ex4.ll b/llvm/test/Transforms/Coroutines/ex4.ll index d4dba1cf818dd..7c7a869e4a500 100644 --- a/llvm/test/Transforms/Coroutines/ex4.ll +++ b/llvm/test/Transforms/Coroutines/ex4.ll @@ -27,7 +27,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret ptr %hdl } @@ -63,7 +63,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) +declare i1 @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/ex5.ll b/llvm/test/Transforms/Coroutines/ex5.ll index e6daec528ce40..bf5cbec266c91 100644 --- a/llvm/test/Transforms/Coroutines/ex5.ll +++ b/llvm/test/Transforms/Coroutines/ex5.ll @@ -31,7 +31,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret ptr %hdl } @@ -46,7 +46,7 @@ declare ptr @llvm.coro.begin(token, ptr) declare token @llvm.coro.save(ptr) declare i8 @llvm.coro.suspend(token, i1) declare ptr @llvm.coro.free(token, ptr) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) ; CHECK-LABEL: @main define i32 @main() { diff --git a/llvm/test/Transforms/Coroutines/no-suspend.ll b/llvm/test/Transforms/Coroutines/no-suspend.ll index dbbdd7feda187..53eb98f1273a9 100644 --- a/llvm/test/Transforms/Coroutines/no-suspend.ll +++ b/llvm/test/Transforms/Coroutines/no-suspend.ll @@ -32,7 +32,7 @@ dyn.free: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret void } @@ -81,7 +81,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret void } @@ -129,7 +129,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret void lpad: %lpval = landingpad { ptr, i32 } @@ -190,7 +190,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret void } @@ -244,7 +244,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret void } @@ -291,7 +291,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret void lpad: %lpval = landingpad { ptr, i32 } @@ -343,7 +343,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret void } @@ -388,7 +388,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) ret void lpad: %lpval = landingpad { ptr, i32 } @@ -410,7 +410,7 @@ declare ptr @llvm.coro.begin(token, ptr) declare token @llvm.coro.save(ptr %hdl) declare i8 @llvm.coro.suspend(token, i1) declare ptr @llvm.coro.free(token, ptr) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.subfn.addr(ptr, i8) diff --git a/llvm/test/Transforms/Coroutines/phi-coro-end.ll b/llvm/test/Transforms/Coroutines/phi-coro-end.ll index 52cecce869e4d..aab76faed3f1a 100644 --- a/llvm/test/Transforms/Coroutines/phi-coro-end.ll +++ b/llvm/test/Transforms/Coroutines/phi-coro-end.ll @@ -17,7 +17,7 @@ cleanup: suspend: %r = phi i32 [%n, %entry], [1, %cleanup] - call i1 @llvm.coro.end(ptr %hdl, i1 false) + call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) call void @print(i32 %r) ret ptr %hdl } @@ -41,7 +41,7 @@ declare void @llvm.coro.destroy(ptr) declare token @llvm.coro.id(i32, ptr, ptr, ptr) declare ptr @llvm.coro.begin(token, ptr) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @print(i32) diff --git a/llvm/test/Transforms/Coroutines/remarks.ll b/llvm/test/Transforms/Coroutines/remarks.ll index be1a213f67a92..5eaddbfc3d107 100644 --- a/llvm/test/Transforms/Coroutines/remarks.ll +++ b/llvm/test/Transforms/Coroutines/remarks.ll @@ -33,7 +33,7 @@ cleanup: call void @free(ptr %mem) br label %suspend suspend: - call i1 @llvm.coro.end(ptr %hdl, i1 0) + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) ret ptr %hdl } @@ -60,7 +60,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) +declare i1 @llvm.coro.end(ptr, i1, token) declare noalias ptr @malloc(i32) declare void @print(i32) diff --git a/llvm/test/Transforms/FunctionAttrs/noreturn.ll b/llvm/test/Transforms/FunctionAttrs/noreturn.ll index ae26eba6fc40e..fa80f6c2eced4 100644 --- a/llvm/test/Transforms/FunctionAttrs/noreturn.ll +++ b/llvm/test/Transforms/FunctionAttrs/noreturn.ll @@ -81,9 +81,9 @@ define void @unreachable() { ; CHECK: @coro define void @coro() presplitcoroutine { call token @llvm.coro.id.retcon.once(i32 0, i32 0, ptr null, ptr @coro, ptr null, ptr null) - call i1 @llvm.coro.end(ptr null, i1 false) + call i1 (ptr, i1, ...) @llvm.coro.end(ptr null, i1 false) unreachable } declare token @llvm.coro.id.retcon.once(i32 %size, i32 %align, ptr %buffer, ptr %prototype, ptr %alloc, ptr %free) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, ...) diff --git a/llvm/test/Transforms/LICM/sink-with-coroutine.ll b/llvm/test/Transforms/LICM/sink-with-coroutine.ll index 0b3f2e1c630a1..2013df11d9c44 100644 --- a/llvm/test/Transforms/LICM/sink-with-coroutine.ll +++ b/llvm/test/Transforms/LICM/sink-with-coroutine.ll @@ -22,7 +22,7 @@ define i64 @licm(i64 %n) #0 { ; CHECK-NEXT: [[T6:%.*]] = icmp ult i64 [[T5]], [[N]] ; CHECK-NEXT: br i1 [[T6]], label [[LOOP]], label [[BB2]] ; CHECK: bb2: -; CHECK-NEXT: [[RES:%.*]] = call i1 @llvm.coro.end(ptr null, i1 false) +; CHECK-NEXT: [[RES:%.*]] = call i1 @llvm.coro.end(ptr null, i1 false, token none) ; CHECK-NEXT: ret i64 0 ; entry: @@ -46,7 +46,7 @@ await.ready: br i1 %t6, label %loop, label %bb2 bb2: - %res = call i1 @llvm.coro.end(ptr null, i1 false) + %res = call i1 @llvm.coro.end(ptr null, i1 false, token none) ret i64 0 } @@ -82,7 +82,7 @@ define i64 @hoist_threadlocal() presplitcoroutine { ; CHECK: loop.end: ; CHECK-NEXT: br i1 [[CMP]], label [[EXIT]], label [[FOR_BODY]] ; CHECK: exit: -; CHECK-NEXT: [[RES:%.*]] = call i1 @llvm.coro.end(ptr null, i1 false) +; CHECK-NEXT: [[RES:%.*]] = call i1 @llvm.coro.end(ptr null, i1 false, token none) ; CHECK-NEXT: ret i64 0 ; entry: @@ -119,12 +119,12 @@ loop.end: br i1 %cmp, label %exit, label %for.body exit: - %res = call i1 @llvm.coro.end(ptr null, i1 false) + %res = call i1 @llvm.coro.end(ptr null, i1 false, token none) ret i64 0 } declare i8 @llvm.coro.suspend(token, i1) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare nonnull ptr @readonly_funcs() readonly declare nonnull ptr @llvm.threadlocal.address(ptr nonnull) nounwind readnone willreturn declare void @not.reachable() diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td index c144afbd5de69..5d0c2cb558b02 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td @@ -503,8 +503,9 @@ def LLVM_CoroSuspendOp : LLVM_IntrOp<"coro.suspend", [], [], [], 1> { def LLVM_CoroEndOp : LLVM_IntrOp<"coro.end", [], [], [], 1> { let arguments = (ins LLVM_i8Ptr:$handle, - I1:$unwind); - let assemblyFormat = "$handle `,` $unwind attr-dict `:` functional-type(operands, results)"; + I1:$unwind, + LLVM_TokenType:$retvals); + let assemblyFormat = "$handle `,` $unwind `,` $retvals attr-dict `:` functional-type(operands, results)"; } def LLVM_CoroFreeOp : LLVM_IntrOp<"coro.free", [], [], [], 1> { diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td index 2d0ca913e8137..39d1cf23c8712 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -1515,6 +1515,31 @@ def LLVM_NullOp let assemblyFormat = "attr-dict `:` qualified(type($res))"; } +def LLVM_NoneTokenOp + : LLVM_Op<"mlir.none", [Pure]> { + let summary = "Defines a value containing an empty token to LLVM type."; + let description = [{ + Unlike LLVM IR, MLIR does not have first-class token values. They must be + explicitly created as SSA values using `llvm.mlir.none`. This operation has + no operands or attributes, and returns a none token value of a wrapped LLVM IR + pointer type. + + Examples: + + ```mlir + %0 = llvm.mlir.none : !llvm.token + ``` + }]; + + string llvmBuilder = [{ + $res = llvm::ConstantTokenNone::get(builder.getContext()); + }]; + + let results = (outs LLVM_TokenType:$res); + let builders = [LLVM_OneResultOpBuilder]; + let assemblyFormat = "attr-dict `:` type($res)"; +} + def LLVM_UndefOp : LLVM_Op<"mlir.undef", [Pure]>, LLVM_Builder<"$res = llvm::UndefValue::get($_resultType);"> { let summary = "Creates an undefined value of LLVM dialect type."; diff --git a/mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp b/mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp index d1998cfb4b642..28d04f476c0ff 100644 --- a/mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp +++ b/mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp @@ -532,11 +532,12 @@ class CoroEndOpConversion : public OpConversionPattern { // We are not in the block that is part of the unwind sequence. auto constFalse = rewriter.create( op->getLoc(), rewriter.getI1Type(), rewriter.getBoolAttr(false)); + auto noneToken = rewriter.create(op->getLoc()); // Mark the end of a coroutine: @llvm.coro.end. auto coroHdl = adaptor.getHandle(); rewriter.create(op->getLoc(), rewriter.getI1Type(), - ValueRange({coroHdl, constFalse})); + ValueRange({coroHdl, constFalse, noneToken})); rewriter.eraseOp(op); return success(); diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index 9f7ac54b8bcce..3a6544439729e 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -985,6 +985,11 @@ FailureOr ModuleImport::convertConstant(llvm::Constant *constant) { return builder.create(loc, type).getResult(); } + // Convert none token constants. + if (auto *noneToken = dyn_cast(constant)) { + return builder.create(loc).getResult(); + } + // Convert poison. if (auto *poisonVal = dyn_cast(constant)) { Type type = convertType(poisonVal->getType()); diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic.ll b/mlir/test/Target/LLVMIR/Import/intrinsic.ll index 543de93f2f44c..3bb4044e3ca03 100644 --- a/mlir/test/Target/LLVMIR/Import/intrinsic.ll +++ b/mlir/test/Target/LLVMIR/Import/intrinsic.ll @@ -701,7 +701,7 @@ define void @coro_suspend(i32 %0, i1 %1, ptr %2) { ; CHECK-LABEL: llvm.func @coro_end define void @coro_end(ptr %0, i1 %1) { ; CHECK: llvm.intr.coro.end - call i1 @llvm.coro.end(ptr %0, i1 %1) + call i1 @llvm.coro.end(ptr %0, i1 %1, token none) ret void } @@ -1017,7 +1017,7 @@ declare i64 @llvm.coro.align.i64() declare i32 @llvm.coro.align.i32() declare token @llvm.coro.save(ptr) declare i8 @llvm.coro.suspend(token, i1) -declare i1 @llvm.coro.end(ptr, i1) +declare i1 @llvm.coro.end(ptr, i1, token) declare ptr @llvm.coro.free(token, ptr nocapture readonly) declare void @llvm.coro.resume(ptr) declare i32 @llvm.eh.typeid.for(ptr) diff --git a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir index d666017f6aa24..f73e11003b944 100644 --- a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir @@ -689,9 +689,10 @@ llvm.func @coro_suspend(%arg0: i32, %arg1 : i1, %arg2 : !llvm.ptr) { } // CHECK-LABEL: @coro_end -llvm.func @coro_end(%arg0: !llvm.ptr, %arg1 : i1) { +llvm.func @coro_end(%arg0: !llvm.ptr, %arg1 : i1) { + %none = llvm.mlir.none : !llvm.token // CHECK: call i1 @llvm.coro.end - %0 = llvm.intr.coro.end %arg0, %arg1 : (!llvm.ptr, i1) -> i1 + %0 = llvm.intr.coro.end %arg0, %arg1, %none : (!llvm.ptr, i1, !llvm.token) -> i1 llvm.return } @@ -1039,7 +1040,7 @@ llvm.func @ssa_copy(%arg: f32) -> f32 { // CHECK-DAG: declare i32 @llvm.coro.size.i32() // CHECK-DAG: declare token @llvm.coro.save(ptr) // CHECK-DAG: declare i8 @llvm.coro.suspend(token, i1) -// CHECK-DAG: declare i1 @llvm.coro.end(ptr, i1) +// CHECK-DAG: declare i1 @llvm.coro.end(ptr, i1, token) // CHECK-DAG: declare ptr @llvm.coro.free(token, ptr nocapture readonly) // CHECK-DAG: declare void @llvm.coro.resume(ptr) // CHECK-DAG: declare <8 x i32> @llvm.vp.add.v8i32(<8 x i32>, <8 x i32>, <8 x i1>, i32)