|
| 1 | +; RUN: opt < %s -coro-split -S | FileCheck %s |
| 2 | + |
| 3 | +target datalayout = "p:64:64:64" |
| 4 | + |
| 5 | +declare void @prototype_f(i8*, i1) |
| 6 | + |
| 7 | +declare noalias i8* @allocate(i32 %size) |
| 8 | +declare void @deallocate(i8* %ptr) |
| 9 | +declare void @init(i64 *%ptr) |
| 10 | +declare void @use(i8* %ptr) |
| 11 | +declare void @use_addr_val(i64 %val, {i64, i64}*%addr) |
| 12 | + |
| 13 | +define { i8*, {i64, i64}* } @f(i8* %buffer) "coroutine.presplit"="1" { |
| 14 | +entry: |
| 15 | + %tmp = alloca { i64, i64 }, align 8 |
| 16 | + %proj.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 0 |
| 17 | + %proj.2 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 1 |
| 18 | + store i64 0, i64* %proj.1, align 8 |
| 19 | + store i64 0, i64* %proj.2, align 8 |
| 20 | + %cast = bitcast { i64, i64 }* %tmp to i8* |
| 21 | + %escape_addr = ptrtoint {i64, i64}* %tmp to i64 |
| 22 | + %id = call token @llvm.coro.id.retcon.once(i32 32, i32 8, i8* %buffer, i8* bitcast (void (i8*, i1)* @prototype_f to i8*), i8* bitcast (i8* (i32)* @allocate to i8*), i8* bitcast (void (i8*)* @deallocate to i8*)) |
| 23 | + %hdl = call i8* @llvm.coro.begin(token %id, i8* null) |
| 24 | + %proj.2.2 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 1 |
| 25 | + call void @init(i64 * %proj.1) |
| 26 | + call void @init(i64 * %proj.2.2) |
| 27 | + call void @use_addr_val(i64 %escape_addr, {i64, i64}* %tmp) |
| 28 | + %abort = call i1 (...) @llvm.coro.suspend.retcon.i1({i64, i64}* %tmp) |
| 29 | + br i1 %abort, label %end, label %resume |
| 30 | + |
| 31 | +resume: |
| 32 | + call void @use(i8* %cast) |
| 33 | + br label %end |
| 34 | + |
| 35 | +end: |
| 36 | + call i1 @llvm.coro.end(i8* %hdl, i1 0) |
| 37 | + unreachable |
| 38 | +} |
| 39 | +; Make sure we don't lose writes to the frame. |
| 40 | +; CHECK-LABEL: define { i8*, { i64, i64 }* } @f(i8* %buffer) { |
| 41 | +; CHECK: [[FRAMEPTR:%.*]] = bitcast i8* %buffer to %f.Frame* |
| 42 | +; CHECK: [[TMP:%.*]] = getelementptr inbounds %f.Frame, %f.Frame* [[FRAMEPTR]], i32 0, i32 0 |
| 43 | +; CHECK: [[PROJ1:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP]], i64 0, i32 0 |
| 44 | +; CHECK: [[PROJ2:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP]], i64 0, i32 1 |
| 45 | +; CHECK: store i64 0, i64* [[PROJ1]] |
| 46 | +; CHECK: store i64 0, i64* [[PROJ2]] |
| 47 | +; CHECK: [[ESCAPED_ADDR:%.*]] = ptrtoint { i64, i64 }* [[TMP]] to i64 |
| 48 | +; CHECK: call void @init(i64* [[PROJ1]]) |
| 49 | +; CHECK: call void @init(i64* [[PROJ2]]) |
| 50 | +; CHECK: call void @use_addr_val(i64 [[ESCAPED_ADDR]], { i64, i64 }* [[TMP]]) |
| 51 | + |
| 52 | +; CHECK-LABEL: define internal void @f.resume.0(i8* {{.*}} %0, i1 %1) { |
| 53 | +; CHECK: [[FRAMEPTR:%.*]] = bitcast i8* %0 to %f.Frame* |
| 54 | +; CHECK: resume: |
| 55 | +; CHECK: [[TMP:%.*]] = getelementptr inbounds %f.Frame, %f.Frame* [[FRAMEPTR]], i32 0, i32 0 |
| 56 | +; CHECK: [[CAST:%.*]] = bitcast { i64, i64 }* [[TMP]] to i8* |
| 57 | +; CHECK: call void @use(i8* [[CAST]]) |
| 58 | + |
| 59 | +declare token @llvm.coro.id.retcon.once(i32, i32, i8*, i8*, i8*, i8*) |
| 60 | +declare i8* @llvm.coro.begin(token, i8*) |
| 61 | +declare i1 @llvm.coro.suspend.retcon.i1(...) |
| 62 | +declare i1 @llvm.coro.end(i8*, i1) |
| 63 | + |
0 commit comments