File: yield_result.sil

package info (click to toggle)
swiftlang 6.1.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,791,604 kB
  • sloc: cpp: 9,901,740; ansic: 2,201,431; asm: 1,091,827; python: 308,252; objc: 82,166; f90: 80,126; lisp: 38,358; pascal: 25,559; sh: 20,429; ml: 5,058; perl: 4,745; makefile: 4,484; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (155 lines) | stat: -rw-r--r-- 7,855 bytes parent folder | download
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// RUN: %target-swift-frontend -emit-irgen %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-cpu --check-prefix=CHECK-%target-ptrsize -DINT=i%target-ptrsize

import Builtin

sil @marker : $(Builtin.Int64) -> ()

sil @coro_ret : $@yield_once @convention(thin) () -> (@yields Builtin.Int64, Builtin.Int64)
sil @coro_ret_pair : $@yield_once @convention(thin) () -> (@yields Builtin.Int64, Builtin.Int64, Builtin.Int64)

// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @test_simple
// CHECK-32-SAME:  ptr noalias dereferenceable([[BUFFER_SIZE:16]]) %0)
// CHECK-64-SAME:  (ptr noalias dereferenceable([[BUFFER_SIZE:32]]) %0)
// CHECK-SAME:  [[CORO_ATTRIBUTES:#[0-9]+]]
sil @test_simple : $@yield_once () -> (Builtin.Int64) {
entry:
  // CHECK-32:      [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$sBi64_IetAd_TC{{(.ptrauth)?}}", ptr @malloc, ptr @free)
  // CHECK-64:      [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$sBi64_IetAd_TC{{(.ptrauth)?}}", ptr @malloc, ptr @free)
  // CHECK-NEXT:    [[BEGIN:%.*]] = call ptr @llvm.coro.begin(token [[ID]], ptr null)

  // CHECK-NEXT:    call swiftcc void @marker(i64 1000)
  %marker = function_ref @marker : $@convention(thin) (Builtin.Int64) -> ()
  %1000 = integer_literal $Builtin.Int64, 1000
  apply %marker(%1000) : $@convention(thin) (Builtin.Int64) -> ()
  
  // CHECK-NEXT:    [[IS_UNWIND:%.*]] = call i1 (...) @llvm.coro.suspend.retcon.i1()
  // CHECK-NEXT:    br i1 [[IS_UNWIND]], label [[UNWIND_BB:%.*]], label [[RESUME_BB:%.*]]
  yield (), resume resume, unwind unwind

resume:
  // CHECK:         call swiftcc void @marker(i64 2000)
  %2000 = integer_literal $Builtin.Int64, 2000
  apply %marker(%2000) : $@convention(thin) (Builtin.Int64) -> ()
  // CHECK:         br label %coro.end
  return %2000 : $Builtin.Int64

unwind:
  // CHECK:         call swiftcc void @marker(i64 3000)
  %3000 = integer_literal $Builtin.Int64, 3000
  apply %marker(%3000) : $@convention(thin) (Builtin.Int64) -> ()
  // CHECK:         br label %coro.end
  unwind

  // CHECK:       coro.end:
  // CHECK: [[RESULT:%.*]] = phi i64 [ 2000, [[RESUME_BB]] ], [ undef, [[UNWIND_BB]] ]
  // CHECK: [[TOKEN:%.*]] = call token (...) @llvm.coro.end.results(i64 [[RESULT]])
  // CHECK:         call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false, token [[TOKEN]])
  // CHECK-NEXT:    unreachable
}

// CHECK-LABEL:     declare{{( dllimport)?}}{{( protected)?}} swiftcc i64 @"$sBi64_IetAd_TC{{(.ptrauth)?}}"
// CHECK-SAME:      (ptr noalias dereferenceable([[BUFFER_SIZE]]), i1)

// CHECK-LABEL: test_coro_ret
sil @test_coro_ret : $() -> (Builtin.Int64, Builtin.Int64, Builtin.Int64) {
entry:
  %marker = function_ref @marker : $@convention(thin) (Builtin.Int64) -> ()

  %coro1 = function_ref @coro_ret : $@yield_once @convention(thin) () -> (@yields Builtin.Int64, Builtin.Int64)
  (%first, %token1) = begin_apply %coro1() : $@yield_once @convention(thin) () -> (@yields Builtin.Int64, Builtin.Int64)

// CHECK: [[T0:%.*]] = alloca {{\[}}[[BUFFER_SIZE1:.*]] x i8
// CHECK: [[T1:%.*]] = alloca {{\[}}[[BUFFER_SIZE2:.*]] x i8
// CHECK: [[BUFFER1:%.*]] = getelementptr inbounds {{\[}}[[BUFFER_SIZE1]] x i8], ptr [[T0]], i32 0, i32 0
// CHECK: [[CORO1:%.*]] = call ptr @llvm.coro.prepare.retcon(ptr @coro_ret)
// CHECK: [[FRAME1:%.*]] = call swiftcc { ptr, i64 } [[CORO1]](ptr noalias dereferenceable([[BUFFER_SIZE1]]) [[BUFFER1]]
// CHECK: [[CONT1:%.*]]  = extractvalue { ptr, i64 } [[FRAME1]], 0
  
  apply %marker(%first) : $@convention(thin) (Builtin.Int64) -> ()

  %ret = end_apply %token1 as $Builtin.Int64

// CHECK: call swiftcc i64 [[CONT1]](ptr noalias dereferenceable([[BUFFER_SIZE1]]) [[BUFFER1]], i1 false)
  
  apply %marker(%ret) : $@convention(thin) (Builtin.Int64) -> ()

  %coro2 = function_ref @coro_ret_pair : $@yield_once @convention(thin) () -> (@yields Builtin.Int64, Builtin.Int64, Builtin.Int64)
  (%second, %token2) = begin_apply %coro2() : $@yield_once @convention(thin) () -> (@yields Builtin.Int64, Builtin.Int64, Builtin.Int64)

// CHECK: [[BUFFER2:%.*]] = getelementptr inbounds {{\[}}[[BUFFER_SIZE2]] x i8], ptr [[T1]], i32 0, i32 0
// CHECK: [[CORO2:%.*]] = call ptr @llvm.coro.prepare.retcon(ptr @coro_ret_pair)
// CHECK: [[FRAME2:%.*]] = call swiftcc { ptr, i64 } [[CORO2]](ptr noalias dereferenceable([[BUFFER_SIZE2]]) [[BUFFER2]]
// CHECK: [[CONT2:%.*]]  = extractvalue { ptr, i64 } [[FRAME2]], 0

  %ret2 = end_apply %token2 as $(Builtin.Int64, Builtin.Int64)

// CHECK: call swiftcc { i64, i64 } [[CONT2]](ptr noalias dereferenceable([[BUFFER_SIZE2]]) [[BUFFER2]], i1 false)
  
  %ret2_1 = tuple_extract %ret2 : $(Builtin.Int64, Builtin.Int64), 0 
  %ret2_2 = tuple_extract %ret2 : $(Builtin.Int64, Builtin.Int64), 1

  apply %marker(%second) : $@convention(thin) (Builtin.Int64) -> ()

  %retf = tuple (%ret : $Builtin.Int64, %ret2_1 : $Builtin.Int64, %ret2_2 : $Builtin.Int64)
  return %retf : $(Builtin.Int64, Builtin.Int64, Builtin.Int64)
}

// CHECK-LABEL: coro_ret_indirect
// CHECK-SAME: ptr{{.*}} [[CTX:%.*]], ptr{{.*}} [[INDIRECT_RET:%.*]], ptr{{.*}} [[ARG:%.*]], ptr{{.*}} [[TYPE:%.*]])
sil @coro_ret_indirect : $@yield_once @convention(thin) <T> (@in T) -> (@yields @in T, @out T) {
bb0(%outt : $*T, %t : $*T):
  // CHECK-32:      [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr [[CTX]], ptr @"$sxxxlIetAirYi_TC{{(.ptrauth)?}}", ptr @malloc, ptr @free)
  // CHECK-64:      [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr [[CTX]], ptr @"$sxxxlIetAirYi_TC{{(.ptrauth)?}}", ptr @malloc, ptr @free)

  // CHECK:    [[IS_UNWIND:%.*]] = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr [[ARG]])
  // CHECK:    br i1 [[IS_UNWIND]], label %[[UNWIND_BB:.*]], label %[[RESUME_BB:.*]]

  // CHECK:[[RESUME_BB]]:
  // CHECK: [[VW_PTR:%.*]] = getelementptr inbounds ptr, ptr [[TYPE]], [[INT]] -1
  // CHECK: [[VW:%.*]] = load ptr, ptr [[VW_PTR]]
  // CHECK-arm64e-NEXT: ptrtoint ptr [[VW_PTR]] to i64
  // CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend
  // CHECK-arm64e: [[VW:%.*]] = inttoptr i64 {{%.*}} to ptr
  // CHECK: [[ASSIGN_PTR:%.*]] = getelementptr inbounds ptr, ptr [[VW]], i32 3
  // CHECK: [[ASSIGN:%.*]] = load ptr, ptr [[ASSIGN_PTR]]
  // CHECK: call ptr [[ASSIGN]](ptr [[INDIRECT_RET]], ptr [[ARG]], ptr [[TYPE]]) #2

  yield (%t : $*T), resume bb1, unwind bb2

bb1:
  copy_addr %t to %outt : $*T
  %r = tuple ()
  return %r : $()

bb2:
  unwind
}

// CHECK-LABEL: @test_coro_ret_indirect
// CHECK-SAME: (i64 [[ARG:%.*]])
sil [ossa] @test_coro_ret_indirect : $(Builtin.Int64) -> () {
bb0(%0 : $Builtin.Int64):
  // CHECK: [[ARG_COPY:%.*]] = alloca i64
  // CHECK: [[INDIRECT_RET:%.*]] = alloca i64
  // CHECK: [[FRAME:%.*]] = alloca [[[BUFFER_SIZE]] x i8]
  %coro = function_ref @coro_ret_indirect : $@yield_once @convention(thin) <T> (@in T) -> (@yields @in T, @out T)
  %temp = alloc_stack $Builtin.Int64
  store %0 to [trivial] %temp : $*Builtin.Int64

  %out = alloc_stack $Builtin.Int64

  // CHECK: store i64 [[ARG]], ptr [[ARG_COPY]]
  // CHECK: [[CTX:%.*]] = getelementptr inbounds [[[BUFFER_SIZE]] x i8], ptr [[FRAME]], i32 0, i32 0
  // CHECK: [[CORO:%.*]] = call ptr @llvm.coro.prepare.retcon(ptr @coro_ret_indirect)
  // CHECK: [[FRAME:%.*]] = call swiftcc { ptr, ptr } [[CORO]](ptr{{.*}} [[CTX]], ptr [[INDIRECT_RET]], ptr noalias [[ARG_COPY]], ptr getelementptr inbounds (%swift.full_existential_type, ptr @{{.*}}

  (%f1, %token) = begin_apply %coro<Builtin.Int64>(%out, %temp) : $@yield_once @convention(thin) <T> (@in T) -> (@yields @in T, @out T)

  %f2 = end_apply %token as $()

  dealloc_stack %out : $*Builtin.Int64
  dealloc_stack %temp : $*Builtin.Int64

  %r = tuple ()
  return %r : $()
}