1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
4 declare ptr @malloc(i64)
6 %i8.array = type { [100 x i8] }
7 declare void @consume.i8.array(ptr)
9 @testbool = external local_unnamed_addr global i8, align 1
11 ; testval does not contain an explicit lifetime end. We must assume that it may
12 ; live across suspension.
13 define void @HasNoLifetimeEnd() presplitcoroutine {
14 ; CHECK-LABEL: define void @HasNoLifetimeEnd() {
16 ; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr @HasNoLifetimeEnd.resumers)
17 ; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i64 16)
18 ; CHECK-NEXT: [[VFRAME:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
19 ; CHECK-NEXT: store ptr @HasNoLifetimeEnd.resume, ptr [[VFRAME]], align 8
20 ; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds [[HASNOLIFETIMEEND_FRAME:%.*]], ptr [[VFRAME]], i32 0, i32 1
21 ; CHECK-NEXT: store ptr @HasNoLifetimeEnd.destroy, ptr [[DESTROY_ADDR]], align 8
22 ; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds [[HASNOLIFETIMEEND_FRAME]], ptr [[VFRAME]], i32 0, i32 2
23 ; CHECK-NEXT: call void @consume.i8.array(ptr [[INDEX_ADDR1]])
24 ; CHECK-NEXT: [[INDEX_ADDR2:%.*]] = getelementptr inbounds [[HASNOLIFETIMEEND_FRAME]], ptr [[VFRAME]], i32 0, i32 3
25 ; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR2]], align 1
26 ; CHECK-NEXT: ret void
29 %testval = alloca %i8.array
30 %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
31 %alloc = call ptr @malloc(i64 16) #3
32 %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc)
34 call void @llvm.lifetime.start.p0(i64 100, ptr %testval)
35 call void @consume.i8.array(ptr %testval)
37 %save = call token @llvm.coro.save(ptr null)
38 %suspend = call i8 @llvm.coro.suspend(token %save, i1 false)
39 switch i8 %suspend, label %exit [
40 i8 0, label %await.ready
46 call i1 @llvm.coro.end(ptr null, i1 false, token none)
50 define void @LifetimeEndAfterCoroEnd() presplitcoroutine {
51 ; CHECK-LABEL: define void @LifetimeEndAfterCoroEnd() {
53 ; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr @LifetimeEndAfterCoroEnd.resumers)
54 ; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i64 16)
55 ; CHECK-NEXT: [[VFRAME:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
56 ; CHECK-NEXT: store ptr @LifetimeEndAfterCoroEnd.resume, ptr [[VFRAME]], align 8
57 ; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds [[LIFETIMEENDAFTERCOROEND_FRAME:%.*]], ptr [[VFRAME]], i32 0, i32 1
58 ; CHECK-NEXT: store ptr @LifetimeEndAfterCoroEnd.destroy, ptr [[DESTROY_ADDR]], align 8
59 ; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds [[LIFETIMEENDAFTERCOROEND_FRAME]], ptr [[VFRAME]], i32 0, i32 2
60 ; CHECK-NEXT: call void @consume.i8.array(ptr [[INDEX_ADDR1]])
61 ; CHECK-NEXT: [[INDEX_ADDR2:%.*]] = getelementptr inbounds [[LIFETIMEENDAFTERCOROEND_FRAME]], ptr [[VFRAME]], i32 0, i32 3
62 ; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR2]], align 1
63 ; CHECK-NEXT: ret void
66 %testval = alloca %i8.array
67 %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
68 %alloc = call ptr @malloc(i64 16) #3
69 %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc)
71 call void @llvm.lifetime.start.p0(i64 100, ptr %testval)
72 call void @consume.i8.array(ptr %testval)
74 %save = call token @llvm.coro.save(ptr null)
75 %suspend = call i8 @llvm.coro.suspend(token %save, i1 false)
76 switch i8 %suspend, label %exit [
77 i8 0, label %await.ready
83 call i1 @llvm.coro.end(ptr null, i1 false, token none)
84 call void @llvm.lifetime.end.p0(i64 100, ptr %testval)
88 define void @BranchWithoutLifetimeEnd() presplitcoroutine {
89 ; CHECK-LABEL: define void @BranchWithoutLifetimeEnd() {
91 ; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr @BranchWithoutLifetimeEnd.resumers)
92 ; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i64 16)
93 ; CHECK-NEXT: [[VFRAME:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
94 ; CHECK-NEXT: store ptr @BranchWithoutLifetimeEnd.resume, ptr [[VFRAME]], align 8
95 ; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds [[BRANCHWITHOUTLIFETIMEEND_FRAME:%.*]], ptr [[VFRAME]], i32 0, i32 1
96 ; CHECK-NEXT: store ptr @BranchWithoutLifetimeEnd.destroy, ptr [[DESTROY_ADDR]], align 8
97 ; CHECK-NEXT: [[TESTVAL:%.*]] = getelementptr inbounds [[BRANCHWITHOUTLIFETIMEEND_FRAME]], ptr [[VFRAME]], i32 0, i32 2
98 ; CHECK-NEXT: call void @consume.i8.array(ptr [[TESTVAL]])
99 ; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr @testbool, align 1
100 ; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds [[BRANCHWITHOUTLIFETIMEEND_FRAME]], ptr [[VFRAME]], i32 0, i32 3
101 ; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
102 ; CHECK-NEXT: ret void
105 %testval = alloca %i8.array
106 %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
107 %alloc = call ptr @malloc(i64 16) #3
108 %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc)
110 call void @llvm.lifetime.start.p0(i64 100, ptr %testval)
111 call void @consume.i8.array(ptr %testval)
113 %0 = load i8, ptr @testbool, align 1
114 %tobool = trunc nuw i8 %0 to i1
115 br i1 %tobool, label %if.then, label %if.end
118 call void @llvm.lifetime.end.p0(i64 100, ptr %testval)
122 %save = call token @llvm.coro.save(ptr null)
123 %suspend = call i8 @llvm.coro.suspend(token %save, i1 false)
124 switch i8 %suspend, label %exit [
125 i8 0, label %await.ready
131 call i1 @llvm.coro.end(ptr null, i1 false, token none)
136 declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr)
137 declare ptr @llvm.coro.begin(token, ptr writeonly) #3
138 declare ptr @llvm.coro.frame() #5
139 declare i8 @llvm.coro.suspend(token, i1) #3
140 declare i1 @llvm.coro.end(ptr, i1, token) #3
141 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4
142 declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4