File: coro-only-destroy-when-complete.ll

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 1,998,492 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (137 lines) | stat: -rw-r--r-- 5,361 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
; RUN: opt < %s -passes='cgscc(coro-split),early-cse,dce,simplifycfg' -S | FileCheck %s

%"struct.std::__n4861::noop_coroutine_promise" = type { i8 }
%struct.Promise = type { %"struct.std::__n4861::coroutine_handle" }
%"struct.std::__n4861::coroutine_handle" = type { ptr }

define ptr @foo() #1 {
entry:
  %__promise = alloca %struct.Promise, align 8
  %0 = call token @llvm.coro.id(i32 16, ptr nonnull %__promise, ptr nonnull @foo, ptr null)
  %1 = call i1 @llvm.coro.alloc(token %0)
  br i1 %1, label %coro.alloc, label %init.suspend

coro.alloc:                                       ; preds = %entry
  %2 = tail call i64 @llvm.coro.size.i64()
  %call = call noalias noundef nonnull ptr @_Znwm(i64 noundef %2) #11
  br label %init.suspend

init.suspend:                                     ; preds = %entry, %coro.alloc
  %3 = phi ptr [ null, %entry ], [ %call, %coro.alloc ]
  %4 = call ptr @llvm.coro.begin(token %0, ptr %3) #12
  call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %__promise) #3
  store ptr null, ptr %__promise, align 8
  %5 = call token @llvm.coro.save(ptr null)
  %6 = call i8 @llvm.coro.suspend(token %5, i1 false)
  switch i8 %6, label %coro.ret [
  i8 0, label %await.suspend
  i8 1, label %cleanup1
  ]

await.suspend:                                    ; preds = %init.suspend
  %7 = call token @llvm.coro.save(ptr null)
  %8 = call i8 @llvm.coro.suspend(token %7, i1 false)
  switch i8 %8, label %coro.ret [
  i8 0, label %await2.suspend
  i8 1, label %cleanup2
  ]

await2.suspend:                                   ; preds = %await.suspend
  %call27 = call ptr @_Z5Innerv() #3
  %9 = call token @llvm.coro.save(ptr null)
  %10 = getelementptr inbounds i8, ptr %__promise, i64 -16
  store ptr %10, ptr %call27, align 8
  %11 = getelementptr inbounds i8, ptr %call27, i64 -16
  %12 = call ptr @llvm.coro.subfn.addr(ptr nonnull %11, i8 0)
  call fastcc void %12(ptr nonnull %11) #3
  %13 = call i8 @llvm.coro.suspend(token %9, i1 false)
  switch i8 %13, label %coro.ret [
  i8 0, label %final.suspend
  i8 1, label %cleanup3
  ]

final.suspend:                                    ; preds = %await2.suspend
  %14 = call ptr @llvm.coro.subfn.addr(ptr nonnull %11, i8 1)
  call fastcc void %14(ptr nonnull %11) #3
  %15 = call token @llvm.coro.save(ptr null)
  %retval.sroa.0.0.copyload.i = load ptr, ptr %__promise, align 8
  %16 = call ptr @llvm.coro.subfn.addr(ptr %retval.sroa.0.0.copyload.i, i8 0)
  call fastcc void %16(ptr %retval.sroa.0.0.copyload.i) #3
  %17 = call i8 @llvm.coro.suspend(token %15, i1 true) #12
  switch i8 %17, label %coro.ret [
  i8 0, label %final.ready
  i8 1, label %cleanup62
  ]

final.ready:                                      ; preds = %final.suspend
  call void @exit(i32 noundef 1)
  unreachable

cleanup1:
  call void @dtor1()
  br label %cleanup62

cleanup2:
  call void @dtor2()
  br label %cleanup62

cleanup3:
  call void @dtor3()
  br label %cleanup62

cleanup62:                                        ; preds = %await2.suspend, %await.suspend, %init.suspend, %final.suspend
  call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %__promise) #3
  %18 = call ptr @llvm.coro.free(token %0, ptr %4)
  %.not = icmp eq ptr %18, null
  br i1 %.not, label %coro.ret, label %coro.free

coro.free:                                        ; preds = %cleanup62
  call void @_ZdlPv(ptr noundef nonnull %18) #3
  br label %coro.ret

coro.ret:                                         ; preds = %coro.free, %cleanup62, %final.suspend, %await2.suspend, %await.suspend, %init.suspend
  %19 = call i1 @llvm.coro.end(ptr null, i1 false, token none) #12
  ret ptr %__promise
}

declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #2
declare i1 @llvm.coro.alloc(token) #3
declare dso_local noundef nonnull ptr @_Znwm(i64 noundef) local_unnamed_addr #4
declare i64 @llvm.coro.size.i64() #5
declare ptr @llvm.coro.begin(token, ptr writeonly) #3
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #6
declare token @llvm.coro.save(ptr) #7
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #6
declare i8 @llvm.coro.suspend(token, i1) #3
declare ptr @_Z5Innerv() local_unnamed_addr
declare dso_local void @_ZdlPv(ptr noundef) local_unnamed_addr #8
declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2
declare i1 @llvm.coro.end(ptr, i1, token) #3
declare void @exit(i32 noundef)
declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #10
declare void @dtor1()
declare void @dtor2()
declare void @dtor3()

attributes #0 = { mustprogress nounwind uwtable }
attributes #1 = { nounwind presplitcoroutine uwtable coro_only_destroy_when_complete }
attributes #2 = { argmemonly nofree nounwind readonly }
attributes #3 = { nounwind }
attributes #4 = { nobuiltin allocsize(0) }
attributes #5 = { nofree nosync nounwind readnone }
attributes #6 = { argmemonly mustprogress nocallback nofree nosync nounwind willreturn }
attributes #7 = { nomerge nounwind }
attributes #8 = { nobuiltin nounwind }
attributes #9 = { noreturn }
attributes #10 = { argmemonly nounwind readonly }
attributes #11 = { nounwind allocsize(0) }
attributes #12 = { noduplicate }

; CHECK: define{{.*}}@foo.destroy(
; CHECK-NEXT: entry.destroy:
; CHECK-NEXT: call void @_ZdlPv
; CHECK-NEXT: ret void

; CHECK: define{{.*}}@foo.cleanup(
; CHECK-NEXT: entry.cleanup:
; CHECK-NEXT: ret void