diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index b4e758136b39f..a41015821d22a 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -1674,11 +1674,11 @@ def int_coro_id : DefaultAttrsIntrinsic<[llvm_token_ty], NoCapture>]>; def int_coro_id_retcon : Intrinsic<[llvm_token_ty], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty, - llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty], + llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty, llvm_vararg_ty], []>; def int_coro_id_retcon_once : Intrinsic<[llvm_token_ty], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty, - llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty], + llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty, llvm_vararg_ty], []>; def int_coro_alloc : Intrinsic<[llvm_i1_ty], [llvm_token_ty], []>; def int_coro_id_async : Intrinsic<[llvm_token_ty], diff --git a/llvm/lib/Transforms/Coroutines/CoroInstr.h b/llvm/lib/Transforms/Coroutines/CoroInstr.h index a31703fe01304..413c233b9b4b9 100644 --- a/llvm/lib/Transforms/Coroutines/CoroInstr.h +++ b/llvm/lib/Transforms/Coroutines/CoroInstr.h @@ -233,7 +233,7 @@ class LLVM_LIBRARY_VISIBILITY CoroIdInst : public AnyCoroIdInst { /// This represents either the llvm.coro.id.retcon or /// llvm.coro.id.retcon.once instruction. class LLVM_LIBRARY_VISIBILITY AnyCoroIdRetconInst : public AnyCoroIdInst { - enum { SizeArg, AlignArg, StorageArg, PrototypeArg, AllocArg, DeallocArg }; + enum { SizeArg, AlignArg, StorageArg, PrototypeArg, AllocArg, DeallocArg, TypeIdArg }; public: void checkWellFormed() const; @@ -267,6 +267,19 @@ class LLVM_LIBRARY_VISIBILITY AnyCoroIdRetconInst : public AnyCoroIdInst { return cast(getArgOperand(DeallocArg)->stripPointerCasts()); } + /// Return the TypeId to be used for allocating typed memory + ConstantInt *getTypeId() const { + if (arg_size() <= TypeIdArg) + return nullptr; + assert(hasTypeId() && "Invalid number of arguments"); + return cast(getArgOperand(TypeIdArg)); + } + + /// Return true if TypeId is present in the list of arguments, false otherwise + bool hasTypeId() const { + return arg_size() == TypeIdArg + 1; + } + // 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/CoroInternal.h b/llvm/lib/Transforms/Coroutines/CoroInternal.h index 5716fd0ea4ab9..38396bdb34e08 100644 --- a/llvm/lib/Transforms/Coroutines/CoroInternal.h +++ b/llvm/lib/Transforms/Coroutines/CoroInternal.h @@ -130,6 +130,7 @@ struct LLVM_LIBRARY_VISIBILITY Shape { Function *Dealloc; BasicBlock *ReturnBlock; bool IsFrameInlineInStorage; + ConstantInt* TypeId; }; struct AsyncLoweringStorage { diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp index 1a92bc1636257..35c8bd332f342 100644 --- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp +++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp @@ -343,6 +343,7 @@ void coro::Shape::buildFrom(Function &F) { this->RetconLowering.Dealloc = ContinuationId->getDeallocFunction(); this->RetconLowering.ReturnBlock = nullptr; this->RetconLowering.IsFrameInlineInStorage = false; + this->RetconLowering.TypeId = ContinuationId->getTypeId(); // Determine the result value types, and make sure they match up with // the values passed to the suspends. @@ -465,7 +466,12 @@ Value *coro::Shape::emitAlloc(IRBuilder<> &Builder, Value *Size, Size = Builder.CreateIntCast(Size, Alloc->getFunctionType()->getParamType(0), /*is signed*/ false); - auto *Call = Builder.CreateCall(Alloc, Size); + ConstantInt* TypeId = RetconLowering.TypeId; + CallInst *Call; + if (TypeId == nullptr) + Call = Builder.CreateCall(Alloc, Size); + else + Call = Builder.CreateCall(Alloc, {Size, TypeId}); propagateCallAttrsFromCallee(Call, Alloc); addCallToCallGraph(CG, Call, Alloc); return Call; @@ -558,9 +564,14 @@ static void checkWFAlloc(const Instruction *I, Value *V) { if (!FT->getReturnType()->isPointerTy()) fail(I, "llvm.coro.* allocator must return a pointer", F); - if (FT->getNumParams() != 1 || - !FT->getParamType(0)->isIntegerTy()) - fail(I, "llvm.coro.* allocator must take integer as only param", F); + if (FT->getNumParams() > 2 || FT->getNumParams() == 0) + fail(I, "llvm.coro.* allocator must take either one or two params", F); + + if (FT->getNumParams() == 1 && !FT->getParamType(0)->isIntegerTy()) + fail(I, "llvm.coro.* allocator must take integer as its first param", F); + + if (FT->getNumParams() == 2 && !FT->getParamType(1)->isIntegerTy()) + fail(I, "llvm.coro.* allocator must take uint64_t as its second param", F); } /// Check that the given value is a well-formed deallocator. 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 2dabc72a51014..4eb49de050064 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-alloca-opaque-ptr.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-alloca-opaque-ptr.ll @@ -17,7 +17,7 @@ define {ptr, ptr, i32} @f(ptr %buffer, i32 %n, { i32 } %dummy) { ; CHECK-NEXT: ret { ptr, ptr, i32 } [[TMP2]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_f, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_f, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -51,7 +51,7 @@ define {ptr, i32} @g(ptr %buffer, i32 %n) { ; CHECK-NEXT: ret { ptr, i32 } [[TMP2]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_g, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_g, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -73,7 +73,7 @@ cleanup: unreachable } -declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +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(...) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll b/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll index 9b00d7929684f..c19a4e95bb968 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll @@ -16,7 +16,7 @@ define {ptr, ptr, i32} @f(ptr %buffer, i32 %n) { ; CHECK-NEXT: ret { ptr, ptr, i32 } [[TMP2]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_f, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_f, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -51,7 +51,7 @@ define {ptr, i32} @g(ptr %buffer, i32 %n) { ; CHECK-NEXT: ret { ptr, i32 } [[TMP2]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_g, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_g, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -84,7 +84,7 @@ define {ptr, i32} @h(ptr %buffer, i32 %n) { ; CHECK-NEXT: ret { ptr, i32 } [[TMP0]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_h, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_h, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -117,7 +117,7 @@ define {ptr, i32} @i(ptr %buffer, i32 %n) { ; CHECK-NEXT: ret { ptr, i32 } [[TMP0]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_i, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_i, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -149,7 +149,7 @@ define {ptr, i32} @j(ptr %buffer, i32 %n) { ; CHECK-NEXT: ret { ptr, i32 } [[TMP0]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_j, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_j, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %forward @@ -190,7 +190,7 @@ define {ptr, i32} @k(ptr %buffer, i32 %n, i1 %cond) { ; CHECK-NEXT: br label [[CORO_RETURN]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_g, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_g, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br i1 %cond, label %alloca_block, label %non_alloca_block @@ -221,7 +221,7 @@ cleanup: unreachable } -declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +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(...) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-frame.ll b/llvm/test/Transforms/Coroutines/coro-retcon-frame.ll index a81cdf475ae31..44979c4d97e5e 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-frame.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-frame.ll @@ -18,7 +18,7 @@ entry: store i64 0, ptr %proj.1, align 8 store i64 0, ptr %proj.2, align 8 %escape_addr = ptrtoint ptr %tmp to i64 - %id = call token @llvm.coro.id.retcon.once(i32 32, i32 8, ptr %buffer, ptr @prototype_f, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 32, i32 8, ptr %buffer, ptr @prototype_f, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) %proj.2.2 = getelementptr inbounds { i64, i64 }, ptr %tmp, i64 0, i32 1 call void @init(ptr %proj.1) @@ -49,7 +49,7 @@ end: ; CHECK: resume: ; CHECK: call void @use(ptr %0) -declare token @llvm.coro.id.retcon.once(i32, i32, ptr, ptr, ptr, ptr) +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, token) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll b/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll index e7593cc8c6f81..b2bd61efcc79d 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll @@ -7,7 +7,7 @@ target triple = "x86_64-apple-macosx10.12.0" define internal {ptr, i32} @f(ptr %buffer, ptr %array) { entry: - %id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @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) %load = load i32, ptr %array %load.pos = icmp sgt i32 %load, 0 @@ -34,7 +34,7 @@ cleanup: unreachable } -declare token @llvm.coro.id.retcon.once(i32, i32, ptr, ptr, ptr, ptr) +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, token) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll b/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll index 2ee515f0a1a91..2ddb531b28dcd 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll @@ -6,7 +6,7 @@ target triple = "x86_64-apple-macosx10.12.0" define {ptr, i32} @f(ptr %buffer, ptr %array) { entry: - %id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @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) %load = load i32, ptr %array %load.pos = icmp sgt i32 %load, 0 @@ -47,7 +47,7 @@ entry: 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) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @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 @@ -93,7 +93,7 @@ entry: ; 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 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, token) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll b/llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll index c33e60e98cd8b..fc1de45862472 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll @@ -6,7 +6,7 @@ target triple = "x86_64-apple-macosx10.12.0" define {ptr, ptr} @f(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 @prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @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) %oldvalue = load i32, ptr %ptr store i32 %oldvalue, ptr %temp @@ -27,7 +27,7 @@ cleanup: 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) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @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 @@ -49,7 +49,7 @@ cleanup: 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) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @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 @@ -68,7 +68,7 @@ cleanup: } -declare token @llvm.coro.id.retcon.once(i32, i32, ptr, ptr, ptr, ptr) +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, token) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll b/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll index f456b6e7bc858..f4902a2c0b176 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll @@ -11,7 +11,7 @@ define ptr @f(ptr %buffer, i32 %n) { ; CHECK-NEXT: ret ptr @f.resume.0 ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -58,7 +58,7 @@ define hidden { ptr, ptr } @g(ptr %buffer, ptr %ptr) { ; CHECK-NEXT: ret { ptr, ptr } [[TMP1]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @g_prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @g_prototype, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -74,7 +74,7 @@ cleanup: ; preds = %loop unreachable } -declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +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, token) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll b/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll index fd16ba96181b9..30df2ec15b2da 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll @@ -6,7 +6,7 @@ define { ptr, i32 } @f(ptr %buffer, i32 %n) { entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @f_prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @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 @@ -35,7 +35,7 @@ cleanup: unreachable } -declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +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, token) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll index 4c10cb3805c7c..527862d3a3775 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll @@ -10,7 +10,7 @@ define ptr @f(ptr %buffer, i32 %n) { ; CHECK-NEXT: ret ptr @f.resume.0 ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -63,7 +63,7 @@ entry: ; 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(i32, i32, ptr, ptr, ptr, ptr) +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, token) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll index 2caa6430ca012..be5b20bc3238e 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll @@ -3,7 +3,7 @@ define ptr @f(ptr %buffer, i32 %n) presplitcoroutine { entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) %value0 = call i32 (...) @llvm.coro.suspend.retcon.i32() %sum0 = call i32 @add(i32 %n, i32 %value0) @@ -19,7 +19,7 @@ entry: unreachable } -declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +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, token) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-swift-coroFrameAlloc.ll b/llvm/test/Transforms/Coroutines/coro-retcon-swift-coroFrameAlloc.ll new file mode 100644 index 0000000000000..8fe4373c7cef3 --- /dev/null +++ b/llvm/test/Transforms/Coroutines/coro-retcon-swift-coroFrameAlloc.ll @@ -0,0 +1,49 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes='module(coro-early),cgscc(coro-split),function(simplifycfg,early-cse)' -S | FileCheck %s +target datalayout = "E-p:64:64" + +%swift.type = type { i64 } +%swift.opaque = type opaque +%T4red215EmptyCollectionV = type opaque +%TSi = type <{ i64 }> + +define hidden swiftcc { ptr, ptr } @no_suspends(ptr %buffer, i64 %arg) #1 { +; CHECK-LABEL: @no_suspends( +; CHECK-NEXT: AllocaSpillBB: +; CHECK-NEXT: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 32, i32 8, ptr [[BUFFER:%.*]], ptr @prototype, ptr @swift_coroFrameAlloc, ptr @free, i32 32) +; CHECK-NEXT: call void @print(i64 [[ARG:%.*]]) +; CHECK-NEXT: call void @llvm.trap() +; CHECK-NEXT: unreachable +; + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 32, i32 8, ptr %buffer, ptr @prototype, ptr @swift_coroFrameAlloc, ptr @free, i32 32) + %begin = call ptr @llvm.coro.begin(token %id, ptr null) + call void @print(i64 %arg) + call void @llvm.trap() + unreachable + +bb1: + call void @print(i64 %arg) + call i1 @llvm.coro.end(ptr %begin, i1 false, token none) + unreachable +} + +declare swiftcc void @prototype(ptr noalias dereferenceable(32), i1) +declare void @print(i64) + +declare noalias ptr @swift_coroFrameAlloc(i64, i64) #5 +declare void @free(ptr nocapture) #5 + +declare token @llvm.coro.id.retcon.once(i32, i32, ptr, ptr, ptr, ptr, ...) #5 +declare ptr @llvm.coro.begin(token, ptr writeonly) #5 +declare token @llvm.coro.alloca.alloc.i64(i64, i32) #5 +declare ptr @llvm.coro.alloca.get(token) #5 +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, token) #5 + +declare void @llvm.trap() + +attributes #1 = { noreturn nounwind } +attributes #5 = { nounwind } diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-unreachable.ll b/llvm/test/Transforms/Coroutines/coro-retcon-unreachable.ll index 8ed03849fb63b..9784fd7dca416 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-unreachable.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-unreachable.ll @@ -10,12 +10,12 @@ target datalayout = "E-p:64:64" define hidden swiftcc { ptr, ptr } @no_suspends(ptr %buffer, i64 %arg) #1 { ; CHECK-LABEL: @no_suspends( ; CHECK-NEXT: AllocaSpillBB: -; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 32, i32 8, ptr [[BUFFER:%.*]], ptr @prototype, ptr @malloc, ptr @free) +; CHECK-NEXT: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 32, i32 8, ptr [[BUFFER:%.*]], ptr @prototype, ptr @malloc, ptr @free) ; CHECK-NEXT: call void @print(i64 [[ARG:%.*]]) ; CHECK-NEXT: call void @llvm.trap() ; CHECK-NEXT: unreachable ; - %id = call token @llvm.coro.id.retcon.once(i32 32, i32 8, ptr %buffer, ptr @prototype, ptr @malloc, ptr @free) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 32, i32 8, ptr %buffer, ptr @prototype, ptr @malloc, ptr @free) %begin = call ptr @llvm.coro.begin(token %id, ptr null) call void @print(i64 %arg) call void @llvm.trap() @@ -33,7 +33,7 @@ declare void @print(i64) declare noalias ptr @malloc(i64) #5 declare void @free(ptr nocapture) #5 -declare token @llvm.coro.id.retcon.once(i32, i32, ptr, ptr, ptr, ptr) #5 +declare token @llvm.coro.id.retcon.once(i32, i32, ptr, ptr, ptr, ptr, ...) #5 declare ptr @llvm.coro.begin(token, ptr writeonly) #5 declare token @llvm.coro.alloca.alloc.i64(i64, i32) #5 declare ptr @llvm.coro.alloca.get(token) #5 diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-value.ll b/llvm/test/Transforms/Coroutines/coro-retcon-value.ll index 6a150c6a79807..7d9663ef83baa 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-value.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-value.ll @@ -10,7 +10,7 @@ define {ptr, i32} @f(ptr %buffer, i32 %n) { ; CHECK-NEXT: ret { ptr, i32 } [[TMP0]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -61,7 +61,7 @@ entry: ; 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(i32, i32, ptr, ptr, ptr, ptr) +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, token) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon.ll b/llvm/test/Transforms/Coroutines/coro-retcon.ll index b12a646ef53f9..71520f9b9b410 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon.ll @@ -18,7 +18,7 @@ define ptr @f(ptr %buffer, i32 %n) { ; CORO-NEXT: ret ptr @f.resume.0 ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -91,7 +91,7 @@ define hidden { ptr, ptr } @g(ptr %buffer, ptr %ptr) { ; CORO-NEXT: ret { ptr, ptr } [[TMP2]] ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @g_prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @g_prototype, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -127,7 +127,7 @@ define ptr @nosuspend(ptr %buffer, i32 %n) { ; CORO-NEXT: ret ptr null ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @prototype, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) %a = alloca i32 store i32 %n, ptr %a @@ -141,7 +141,7 @@ cleanup: ret ptr %hdl } -declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +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, token) diff --git a/llvm/test/Transforms/Coroutines/coro-split-swift_coroFrameAlloc.ll b/llvm/test/Transforms/Coroutines/coro-split-swift_coroFrameAlloc.ll new file mode 100644 index 0000000000000..ff35c9e2ebe5d --- /dev/null +++ b/llvm/test/Transforms/Coroutines/coro-split-swift_coroFrameAlloc.ll @@ -0,0 +1,60 @@ +; Tests that coro-split pass splits the coroutine into f, f.resume and f.destroy +; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s + +define ptr @test_simple(ptr noalias dereferenceable(32) %0) presplitcoroutine { +entry: + %call.aggresult = alloca <{ i64, i64, i64, i64, i64 }>, align 8 + %1 = alloca <{ i64, i64, i64, i64, i64 }>, align 8 + %2 = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 32, i32 8, ptr %0, ptr @prototype, ptr @swift_coroFrameAlloc, ptr @free, i64 123) + %3 = call ptr @llvm.coro.begin(token %2, ptr null) + call swiftcc void @marker(i32 1000) + call void @llvm.lifetime.start.p0(i64 40, ptr %call.aggresult) + call swiftcc void @val(ptr noalias nocapture sret(<{ i64, i64, i64, i64, i64 }>) %call.aggresult) + %call.aggresult.elt = getelementptr inbounds <{ i64, i64, i64, i64, i64 }>, ptr %call.aggresult, i32 0, i32 0 + %4 = load i64, ptr %call.aggresult.elt, align 8 + %call.aggresult.elt1 = getelementptr inbounds <{ i64, i64, i64, i64, i64 }>, ptr %call.aggresult, i32 0, i32 1 + %5 = load i64, ptr %call.aggresult.elt1, align 8 + %call.aggresult.elt2 = getelementptr inbounds <{ i64, i64, i64, i64, i64 }>, ptr %call.aggresult, i32 0, i32 2 + %6 = load i64, ptr %call.aggresult.elt2, align 8 + %call.aggresult.elt3 = getelementptr inbounds <{ i64, i64, i64, i64, i64 }>, ptr %call.aggresult, i32 0, i32 3 + %7 = load i64, ptr %call.aggresult.elt3, align 8 + %call.aggresult.elt4 = getelementptr inbounds <{ i64, i64, i64, i64, i64 }>, ptr %call.aggresult, i32 0, i32 4 + %8 = load i64, ptr %call.aggresult.elt4, align 8 + call void @llvm.lifetime.end.p0(i64 40, ptr %call.aggresult) + %9 = call i1 (...) @llvm.coro.suspend.retcon.i1() + br i1 %9, label %11, label %10 + +10: ; preds = %entry + call swiftcc void @marker(i32 2000) + %.elt = getelementptr inbounds <{ i64, i64, i64, i64, i64 }>, ptr %1, i32 0, i32 0 + store i64 %4, ptr %.elt, align 8 + %.elt5 = getelementptr inbounds <{ i64, i64, i64, i64, i64 }>, ptr %1, i32 0, i32 1 + store i64 %5, ptr %.elt5, align 8 + %.elt6 = getelementptr inbounds <{ i64, i64, i64, i64, i64 }>, ptr %1, i32 0, i32 2 + store i64 %6, ptr %.elt6, align 8 + %.elt7 = getelementptr inbounds <{ i64, i64, i64, i64, i64 }>, ptr %1, i32 0, i32 3 + store i64 %7, ptr %.elt7, align 8 + %.elt8 = getelementptr inbounds <{ i64, i64, i64, i64, i64 }>, ptr %1, i32 0, i32 4 + store i64 %8, ptr %.elt8, align 8 + call swiftcc void @use(ptr noalias nocapture dereferenceable(40) %1) + br label %coro.end + +11: ; preds = %entry + call swiftcc void @marker(i32 3000) + br label %coro.end + +coro.end: ; preds = %10, %11 + %12 = call i1 @llvm.coro.end(ptr %3, i1 false, token none) + unreachable +} + +declare void @free(ptr) +declare ptr @swift_coroFrameAlloc(i64, i64) +declare swiftcc void @marker(i32) #1 +declare swiftcc void @use(ptr noalias nocapture dereferenceable(40)) +declare swiftcc void @val(ptr noalias nocapture sret(<{ i64, i64, i64, i64, i64 }>)) +declare void @prototype(ptr, i1 zeroext) + +; CHECK-LABEL: @test_simple( +; CHECK-NEXT: entry: +; CHECK: call ptr @swift_coroFrameAlloc(i64 40, i64 123) \ No newline at end of file diff --git a/llvm/test/Transforms/Coroutines/coro-swifterror.ll b/llvm/test/Transforms/Coroutines/coro-swifterror.ll index de28ed5608168..46c64ec8df539 100644 --- a/llvm/test/Transforms/Coroutines/coro-swifterror.ll +++ b/llvm/test/Transforms/Coroutines/coro-swifterror.ll @@ -15,7 +15,7 @@ define ptr @f(ptr %buffer, i32 %n, ptr swifterror %errorslot) { ; CHECK-NEXT: ret ptr @f.resume.0 ; entry: - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @f_prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @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 @@ -58,7 +58,7 @@ define ptr @g(ptr %buffer, i32 %n) { entry: %errorslot = alloca swifterror ptr, align 4 store ptr null, ptr %errorslot - %id = call token @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @g_prototype, ptr @allocate, ptr @deallocate) + %id = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon(i32 8, i32 4, ptr %buffer, ptr @g_prototype, ptr @allocate, ptr @deallocate) %hdl = call ptr @llvm.coro.begin(token %id, ptr null) br label %loop @@ -82,7 +82,7 @@ cleanup: -declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr) +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(...) diff --git a/llvm/test/Transforms/FunctionAttrs/noreturn.ll b/llvm/test/Transforms/FunctionAttrs/noreturn.ll index fa80f6c2eced4..4f3b36507ebfd 100644 --- a/llvm/test/Transforms/FunctionAttrs/noreturn.ll +++ b/llvm/test/Transforms/FunctionAttrs/noreturn.ll @@ -80,10 +80,10 @@ define void @unreachable() { ; CHECK-NOT: Function Attrs: {{.*}}noreturn ; 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 token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 0, i32 0, ptr null, ptr @coro, ptr null, ptr null) 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 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, ...)