diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 76ca7f691607d..0a5c5707f30e7 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->isVarArg() && 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/Inputs/coro-retcon-frame-auto-upgrade-test.ll.bc b/llvm/test/Transforms/Coroutines/Inputs/coro-retcon-frame-auto-upgrade-test.ll.bc new file mode 100644 index 0000000000000..0538c7912a692 Binary files /dev/null and b/llvm/test/Transforms/Coroutines/Inputs/coro-retcon-frame-auto-upgrade-test.ll.bc differ diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-frame-auto-upgrade-test.ll b/llvm/test/Transforms/Coroutines/coro-retcon-frame-auto-upgrade-test.ll new file mode 100644 index 0000000000000..d17929538f0e4 --- /dev/null +++ b/llvm/test/Transforms/Coroutines/coro-retcon-frame-auto-upgrade-test.ll @@ -0,0 +1,59 @@ +; RUN: llvm-dis < %S/Inputs/coro-retcon-frame-auto-upgrade-test.ll.bc 2>&1 | FileCheck %s + +; ModuleID = '../llvm-project/llvm/test/Transforms/Coroutines/coro-retcon-frame-auto-upgrade.bc' +; CHECK: source_filename = "../llvm-project/llvm/test/Transforms/Coroutines/coro-retcon-frame-auto-upgrade.ll" +; CHECK: target datalayout = "p:64:64:64" + +; CHECK: declare void @prototype_f(ptr, i1) + +; CHECK: declare noalias ptr @allocate(i32) + +; CHECK: declare void @deallocate(ptr) + +; CHECK: declare void @init(ptr) + +; CHECK: declare void @use(ptr) + +; CHECK: declare void @use_addr_val(i64, ptr) + +; Function Attrs: presplitcoroutine +; CHECK: define { ptr, ptr } @f(ptr %buffer) #0 { +; CHECK: entry: +; CHECK: %tmp = alloca { i64, i64 }, align 8 +; CHECK: %proj.1 = getelementptr inbounds { i64, i64 }, ptr %tmp, i64 0, i32 0 +; CHECK: %proj.2 = getelementptr inbounds { i64, i64 }, ptr %tmp, i64 0, i32 1 +; CHECK: store i64 0, ptr %proj.1, align 8 +; CHECK: store i64 0, ptr %proj.2, align 8 +; CHECK: %escape_addr = ptrtoint ptr %tmp to i64 +; CHECK: %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) +; CHECK: %hdl = call ptr @llvm.coro.begin(token %id, ptr null) +; CHECK: %proj.2.2 = getelementptr inbounds { i64, i64 }, ptr %tmp, i64 0, i32 1 +; CHECK: call void @init(ptr %proj.1) +; CHECK: call void @init(ptr %proj.2.2) +; CHECK: call void @use_addr_val(i64 %escape_addr, ptr %tmp) +; CHECK: %abort = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr %tmp) +; CHECK: br i1 %abort, label %end, label %resume + +; CHECK: resume: ; preds = %entry +; CHECK: call void @use(ptr %tmp) +; CHECK: br label %end + +; CHECK: end: ; preds = %resume, %entry +; CHECK: %0 = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none) +; CHECK: unreachable +; CHECK: } + +; Function Attrs: nounwind +; CHECK: declare ptr @llvm.coro.begin(token, ptr writeonly) #1 + +; Function Attrs: nounwind +; CHECK: declare i1 @llvm.coro.suspend.retcon.i1(...) #1 + +; Function Attrs: nounwind +; CHECK: declare i1 @llvm.coro.end(ptr, i1, token) #1 + +; Function Attrs: nounwind +; CHECK: declare token @llvm.coro.id.retcon.once(i32, i32, ptr, ptr, ptr, ptr, ...) #1 + +; CHECK: attributes #0 = { presplitcoroutine } +; CHECK: attributes #1 = { nounwind } \ No newline at end of file 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) +