Files
swift-mirror/test/IRGen/yield_result.sil
Anthony Latsis 17fc00f8a7 [test] IRGen: Adjust FileCheck patterns for new nuw attribute in upstream LLVM
This attribute was introduced in
7eca38ce76d5d1915f4ab7e665964062c0b37697 (llvm-project).

Match it using a wildcard regex, since it is not relevant to these
tests.

This is intended to reduce future conflicts with rebranch.
2025-05-04 03:28:56 +01:00

156 lines
7.9 KiB
Plaintext

// RUN: %target-swift-frontend -emit-irgen -disable-emit-type-malloc-for-coro-frame %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 (i32, i32, ptr, ptr, ptr, ptr, ...) @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 (i32, i32, ptr, ptr, ptr, ptr, ...) @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 (i32, i32, ptr, ptr, ptr, ptr, ...) @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 (i32, i32, ptr, ptr, ptr, ptr, ...) @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 : $()
}