diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 76ca7f691607d..543ba4504a4c0 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -1102,6 +1102,13 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn, return true; } + if (F->arg_size() == 6 && Name == "coro.id.retcon.once") { + rename(F); + NewFn = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::coro_id_retcon_once); + return true; + } + break; } case 'd': @@ -4515,6 +4522,12 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { break; } + case Intrinsic::coro_id_retcon_once: { + SmallVector Args(CI->args()); + NewCall = Builder.CreateCall(NewFn, Args); + break; + } + case Intrinsic::vector_extract: { StringRef Name = F->getName(); Name = Name.substr(5); // Strip llvm diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-frame-old.ll b/llvm/test/Transforms/Coroutines/coro-retcon-frame-old.ll new file mode 100644 index 0000000000000..21a765b6ff006 --- /dev/null +++ b/llvm/test/Transforms/Coroutines/coro-retcon-frame-old.ll @@ -0,0 +1,56 @@ +; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s + +target datalayout = "p:64:64:64" + +declare void @prototype_f(ptr, i1) + +declare noalias ptr @allocate(i32 %size) +declare void @deallocate(ptr %ptr) +declare void @init(ptr %ptr) +declare void @use(ptr %ptr) +declare void @use_addr_val(i64 %val, ptr %addr) + +define { ptr, ptr } @f(ptr %buffer) presplitcoroutine { +entry: + %tmp = alloca { i64, i64 }, align 8 + %proj.1 = getelementptr inbounds { i64, i64 }, ptr %tmp, i64 0, i32 0 + %proj.2 = getelementptr inbounds { i64, i64 }, ptr %tmp, i64 0, i32 1 + 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 (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) + call void @init(ptr %proj.2.2) + call void @use_addr_val(i64 %escape_addr, ptr %tmp) + %abort = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr %tmp) + br i1 %abort, label %end, label %resume + +resume: + call void @use(ptr %tmp) + br label %end + +end: + call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) + unreachable +} +; Make sure we don't lose writes to the frame. +; CHECK-LABEL: define { ptr, ptr } @f(ptr %buffer) { +; CHECK: [[PROJ2:%.*]] = getelementptr inbounds { i64, i64 }, ptr %buffer, i64 0, i32 1 +; CHECK: store i64 0, ptr %buffer +; CHECK: store i64 0, ptr [[PROJ2]] +; CHECK: [[ESCAPED_ADDR:%.*]] = ptrtoint ptr %buffer to i64 +; CHECK: call void @init(ptr %buffer) +; CHECK: call void @init(ptr [[PROJ2]]) +; CHECK: call void @use_addr_val(i64 [[ESCAPED_ADDR]], ptr %buffer) + +; CHECK-LABEL: define internal void @f.resume.0(ptr {{.*}} %0, i1 %1) { +; CHECK: resume: +; CHECK: call void @use(ptr %0) + +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) +