mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Optimizations can rely on alias analysis to know that an in-argument (or parts of it) is not actually read. We have to do the same in the verifier: if alias analysis says that an in-argument is not read, there is no need that the memory location is initialized. Fixes a false verifier error. rdar://106806899
728 lines
23 KiB
Plaintext
728 lines
23 KiB
Plaintext
// RUN: %target-sil-opt -o /dev/null %s
|
|
// REQUIRES: asserts
|
|
// REQUIRES: swift_in_compiler
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
import SwiftShims
|
|
|
|
// A non-trivial type
|
|
class T {
|
|
init()
|
|
}
|
|
|
|
struct Inner {
|
|
var a: T
|
|
var b: T
|
|
}
|
|
|
|
struct Outer {
|
|
var x: T
|
|
var y: Inner
|
|
var z: T
|
|
var i: Int
|
|
}
|
|
|
|
struct Mixed {
|
|
var t: T
|
|
var i: Int
|
|
}
|
|
|
|
sil [ossa] @test_struct : $@convention(thin) (@in Outer) -> @owned T {
|
|
bb0(%0 : $*Outer):
|
|
%1 = struct_element_addr %0 : $*Outer, #Outer.y
|
|
%2 = struct_element_addr %0 : $*Outer, #Outer.x
|
|
%10 = struct_element_addr %0 : $*Outer, #Outer.z
|
|
%3 = load [copy] %2 : $*T
|
|
br bb1
|
|
bb1:
|
|
cond_br undef, bb2, bb6
|
|
bb2:
|
|
cond_br undef, bb3, bb4
|
|
bb3:
|
|
%4 = struct_element_addr %1 : $*Inner, #Inner.a
|
|
%5 = copy_value %3 : $T
|
|
store %5 to [assign] %4 : $*T
|
|
br bb5
|
|
bb4:
|
|
%6 = struct_element_addr %0 : $*Outer, #Outer.y
|
|
%7 = struct_element_addr %6 : $*Inner, #Inner.b
|
|
destroy_addr %7 : $*T
|
|
%8 = copy_value %3 : $T
|
|
store %8 to [init] %7 : $*T
|
|
br bb5
|
|
bb5:
|
|
br bb1
|
|
bb6:
|
|
destroy_addr %1 : $*Inner
|
|
destroy_addr %2 : $*T
|
|
destroy_addr %10 : $*T
|
|
return %3 : $T
|
|
}
|
|
|
|
sil [ossa] @test_struct2 : $@convention(thin) (@in Outer, @owned T) -> () {
|
|
bb0(%0 : $*Outer, %1 : @owned $T):
|
|
%2 = struct_element_addr %0 : $*Outer, #Outer.x
|
|
store %1 to [assign] %2 : $*T
|
|
destroy_addr %0 : $*Outer
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
sil @throwing_func : $@convention(thin) () -> (@out T, @error Error)
|
|
|
|
sil [ossa] @test_try_apply : $@convention(thin) () -> (@out T, @error Error) {
|
|
bb0(%0 : $*T):
|
|
%1 = function_ref @throwing_func : $@convention(thin) () -> (@out T, @error Error)
|
|
try_apply %1(%0) : $@convention(thin) () -> (@out T, @error Error), normal bb1, error bb2
|
|
|
|
bb1(%2 : $()):
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
|
|
bb2(%4 : @owned $Error):
|
|
throw %4 : $Error
|
|
|
|
}
|
|
|
|
sil [ossa] @test_alloc_stack_simple : $@convention(thin) (@in_guaranteed T) -> () {
|
|
bb0(%0 : $*T):
|
|
%2 = alloc_stack $T
|
|
copy_addr %0 to [init] %2 : $*T
|
|
br bb1
|
|
|
|
bb1:
|
|
destroy_addr %2 : $*T
|
|
dealloc_stack %2 : $*T
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
sil [ossa] @test_alloc_stack_nested : $@convention(thin) (@in_guaranteed T) -> () {
|
|
bb0(%0 : $*T):
|
|
%1 = alloc_stack $T
|
|
copy_addr %0 to [init] %1 : $*T
|
|
%2 = alloc_stack $T
|
|
copy_addr %0 to [init] %2 : $*T
|
|
destroy_addr %2 : $*T
|
|
dealloc_stack %2 : $*T
|
|
cond_br undef, bb1, bb2
|
|
bb1:
|
|
%3 = alloc_stack $T
|
|
%4 = alloc_stack $T
|
|
copy_addr %0 to [init] %3 : $*T
|
|
copy_addr %0 to [init] %4 : $*T
|
|
destroy_addr %3 : $*T
|
|
destroy_addr %4 : $*T
|
|
dealloc_stack %4 : $*T
|
|
dealloc_stack %3 : $*T
|
|
br bb3
|
|
bb2:
|
|
br bb3
|
|
bb3:
|
|
destroy_addr %1 : $*T
|
|
dealloc_stack %1 : $*T
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
sil [ossa] @test_unreachable_block : $@convention(thin) (@owned T) -> () {
|
|
bb0(%0 : @owned $T):
|
|
%2 = alloc_stack $T
|
|
store %0 to [init] %2 : $*T
|
|
br bb2
|
|
|
|
bb1:
|
|
br bb2
|
|
|
|
bb2:
|
|
destroy_addr %2 : $*T
|
|
dealloc_stack %2 : $*T
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
sil [ossa] @test_mixed_cfg_merge : $@convention(thin) (@owned T, Int) -> () {
|
|
bb0(%0 : @owned $T, %1 : $Int):
|
|
%2 = alloc_stack $Mixed
|
|
%3 = struct_element_addr %2 : $*Mixed, #Mixed.t
|
|
%4 = struct_element_addr %2 : $*Mixed, #Mixed.i
|
|
store %0 to [init] %3 : $*T
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
store %1 to [trivial] %4 : $*Int
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
destroy_addr %2 : $*Mixed
|
|
dealloc_stack %2 : $*Mixed
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
sil [ossa] @test_many_locations_in_block : $@convention(thin) <A, B, C, D, E, G, H, I> (@in_guaranteed A, @in_guaranteed B, @in_guaranteed C, @in_guaranteed D, @in_guaranteed E, @in_guaranteed G, @in_guaranteed H, @in_guaranteed I) -> (@out A, @out B, @out C, @out D, @out E, @out G, @out H, @out I) {
|
|
bb0(%0 : $*A, %1 : $*B, %2 : $*C, %3 : $*D, %4 : $*E, %5 : $*G, %6 : $*H, %7 : $*I, %9 : $*A, %10 : $*B, %11 : $*C, %12 : $*D, %13 : $*E, %14 : $*G, %15 : $*H, %16 : $*I):
|
|
%18 = alloc_stack $(A, B, C, D, E, G, H, I), let, name "a", argno 1
|
|
%19 = tuple_element_addr %18 : $*(A, B, C, D, E, G, H, I), 0
|
|
copy_addr %9 to [init] %19 : $*A
|
|
%21 = tuple_element_addr %18 : $*(A, B, C, D, E, G, H, I), 1
|
|
copy_addr %10 to [init] %21 : $*B
|
|
%23 = tuple_element_addr %18 : $*(A, B, C, D, E, G, H, I), 2
|
|
copy_addr %11 to [init] %23 : $*C
|
|
%25 = tuple_element_addr %18 : $*(A, B, C, D, E, G, H, I), 3
|
|
copy_addr %12 to [init] %25 : $*D
|
|
%27 = tuple_element_addr %18 : $*(A, B, C, D, E, G, H, I), 4
|
|
copy_addr %13 to [init] %27 : $*E
|
|
%29 = tuple_element_addr %18 : $*(A, B, C, D, E, G, H, I), 5
|
|
copy_addr %14 to [init] %29 : $*G
|
|
%31 = tuple_element_addr %18 : $*(A, B, C, D, E, G, H, I), 6
|
|
copy_addr %15 to [init] %31 : $*H
|
|
%33 = tuple_element_addr %18 : $*(A, B, C, D, E, G, H, I), 7
|
|
copy_addr %16 to [init] %33 : $*I
|
|
%41 = alloc_stack $(A, B, C, D, E, G, H, I)
|
|
copy_addr %18 to [init] %41 : $*(A, B, C, D, E, G, H, I)
|
|
%43 = tuple_element_addr %41 : $*(A, B, C, D, E, G, H, I), 0
|
|
%44 = tuple_element_addr %41 : $*(A, B, C, D, E, G, H, I), 1
|
|
%45 = tuple_element_addr %41 : $*(A, B, C, D, E, G, H, I), 2
|
|
%46 = tuple_element_addr %41 : $*(A, B, C, D, E, G, H, I), 3
|
|
%47 = tuple_element_addr %41 : $*(A, B, C, D, E, G, H, I), 4
|
|
%48 = tuple_element_addr %41 : $*(A, B, C, D, E, G, H, I), 5
|
|
%49 = tuple_element_addr %41 : $*(A, B, C, D, E, G, H, I), 6
|
|
%50 = tuple_element_addr %41 : $*(A, B, C, D, E, G, H, I), 7
|
|
copy_addr [take] %43 to [init] %0 : $*A
|
|
%52 = alloc_stack $(A, B, C, D, E, G, H, I)
|
|
copy_addr %18 to [init] %52 : $*(A, B, C, D, E, G, H, I)
|
|
%54 = tuple_element_addr %52 : $*(A, B, C, D, E, G, H, I), 0
|
|
%55 = tuple_element_addr %52 : $*(A, B, C, D, E, G, H, I), 1
|
|
%56 = tuple_element_addr %52 : $*(A, B, C, D, E, G, H, I), 2
|
|
%57 = tuple_element_addr %52 : $*(A, B, C, D, E, G, H, I), 3
|
|
%58 = tuple_element_addr %52 : $*(A, B, C, D, E, G, H, I), 4
|
|
%59 = tuple_element_addr %52 : $*(A, B, C, D, E, G, H, I), 5
|
|
%60 = tuple_element_addr %52 : $*(A, B, C, D, E, G, H, I), 6
|
|
%61 = tuple_element_addr %52 : $*(A, B, C, D, E, G, H, I), 7
|
|
copy_addr [take] %55 to [init] %1 : $*B
|
|
%63 = alloc_stack $(A, B, C, D, E, G, H, I)
|
|
copy_addr %18 to [init] %63 : $*(A, B, C, D, E, G, H, I)
|
|
%65 = tuple_element_addr %63 : $*(A, B, C, D, E, G, H, I), 0
|
|
%66 = tuple_element_addr %63 : $*(A, B, C, D, E, G, H, I), 1
|
|
%67 = tuple_element_addr %63 : $*(A, B, C, D, E, G, H, I), 2
|
|
%68 = tuple_element_addr %63 : $*(A, B, C, D, E, G, H, I), 3
|
|
%69 = tuple_element_addr %63 : $*(A, B, C, D, E, G, H, I), 4
|
|
%70 = tuple_element_addr %63 : $*(A, B, C, D, E, G, H, I), 5
|
|
%71 = tuple_element_addr %63 : $*(A, B, C, D, E, G, H, I), 6
|
|
%72 = tuple_element_addr %63 : $*(A, B, C, D, E, G, H, I), 7
|
|
copy_addr [take] %67 to [init] %2 : $*C
|
|
%74 = alloc_stack $(A, B, C, D, E, G, H, I)
|
|
copy_addr %18 to [init] %74 : $*(A, B, C, D, E, G, H, I)
|
|
%76 = tuple_element_addr %74 : $*(A, B, C, D, E, G, H, I), 0
|
|
%77 = tuple_element_addr %74 : $*(A, B, C, D, E, G, H, I), 1
|
|
%78 = tuple_element_addr %74 : $*(A, B, C, D, E, G, H, I), 2
|
|
%79 = tuple_element_addr %74 : $*(A, B, C, D, E, G, H, I), 3
|
|
%80 = tuple_element_addr %74 : $*(A, B, C, D, E, G, H, I), 4
|
|
%81 = tuple_element_addr %74 : $*(A, B, C, D, E, G, H, I), 5
|
|
%82 = tuple_element_addr %74 : $*(A, B, C, D, E, G, H, I), 6
|
|
%83 = tuple_element_addr %74 : $*(A, B, C, D, E, G, H, I), 7
|
|
copy_addr [take] %79 to [init] %3 : $*D
|
|
%85 = alloc_stack $(A, B, C, D, E, G, H, I)
|
|
copy_addr %18 to [init] %85 : $*(A, B, C, D, E, G, H, I)
|
|
%87 = tuple_element_addr %85 : $*(A, B, C, D, E, G, H, I), 0
|
|
%88 = tuple_element_addr %85 : $*(A, B, C, D, E, G, H, I), 1
|
|
%89 = tuple_element_addr %85 : $*(A, B, C, D, E, G, H, I), 2
|
|
%90 = tuple_element_addr %85 : $*(A, B, C, D, E, G, H, I), 3
|
|
%91 = tuple_element_addr %85 : $*(A, B, C, D, E, G, H, I), 4
|
|
%92 = tuple_element_addr %85 : $*(A, B, C, D, E, G, H, I), 5
|
|
%93 = tuple_element_addr %85 : $*(A, B, C, D, E, G, H, I), 6
|
|
%94 = tuple_element_addr %85 : $*(A, B, C, D, E, G, H, I), 7
|
|
copy_addr [take] %91 to [init] %4 : $*E
|
|
%96 = alloc_stack $(A, B, C, D, E, G, H, I)
|
|
copy_addr %18 to [init] %96 : $*(A, B, C, D, E, G, H, I)
|
|
%98 = tuple_element_addr %96 : $*(A, B, C, D, E, G, H, I), 0
|
|
%99 = tuple_element_addr %96 : $*(A, B, C, D, E, G, H, I), 1
|
|
%100 = tuple_element_addr %96 : $*(A, B, C, D, E, G, H, I), 2
|
|
%101 = tuple_element_addr %96 : $*(A, B, C, D, E, G, H, I), 3
|
|
%102 = tuple_element_addr %96 : $*(A, B, C, D, E, G, H, I), 4
|
|
%103 = tuple_element_addr %96 : $*(A, B, C, D, E, G, H, I), 5
|
|
%104 = tuple_element_addr %96 : $*(A, B, C, D, E, G, H, I), 6
|
|
%105 = tuple_element_addr %96 : $*(A, B, C, D, E, G, H, I), 7
|
|
copy_addr [take] %103 to [init] %5 : $*G
|
|
%107 = alloc_stack $(A, B, C, D, E, G, H, I)
|
|
copy_addr %18 to [init] %107 : $*(A, B, C, D, E, G, H, I)
|
|
%109 = tuple_element_addr %107 : $*(A, B, C, D, E, G, H, I), 0
|
|
%110 = tuple_element_addr %107 : $*(A, B, C, D, E, G, H, I), 1
|
|
%111 = tuple_element_addr %107 : $*(A, B, C, D, E, G, H, I), 2
|
|
%112 = tuple_element_addr %107 : $*(A, B, C, D, E, G, H, I), 3
|
|
%113 = tuple_element_addr %107 : $*(A, B, C, D, E, G, H, I), 4
|
|
%114 = tuple_element_addr %107 : $*(A, B, C, D, E, G, H, I), 5
|
|
%115 = tuple_element_addr %107 : $*(A, B, C, D, E, G, H, I), 6
|
|
%116 = tuple_element_addr %107 : $*(A, B, C, D, E, G, H, I), 7
|
|
copy_addr [take] %115 to [init] %6 : $*H
|
|
%118 = alloc_stack $(A, B, C, D, E, G, H, I)
|
|
copy_addr %18 to [init] %118 : $*(A, B, C, D, E, G, H, I)
|
|
%120 = tuple_element_addr %118 : $*(A, B, C, D, E, G, H, I), 0
|
|
%121 = tuple_element_addr %118 : $*(A, B, C, D, E, G, H, I), 1
|
|
%122 = tuple_element_addr %118 : $*(A, B, C, D, E, G, H, I), 2
|
|
%123 = tuple_element_addr %118 : $*(A, B, C, D, E, G, H, I), 3
|
|
%124 = tuple_element_addr %118 : $*(A, B, C, D, E, G, H, I), 4
|
|
%125 = tuple_element_addr %118 : $*(A, B, C, D, E, G, H, I), 5
|
|
%126 = tuple_element_addr %118 : $*(A, B, C, D, E, G, H, I), 6
|
|
%127 = tuple_element_addr %118 : $*(A, B, C, D, E, G, H, I), 7
|
|
copy_addr [take] %127 to [init] %7 : $*I
|
|
destroy_addr %126 : $*H
|
|
destroy_addr %125 : $*G
|
|
destroy_addr %124 : $*E
|
|
destroy_addr %123 : $*D
|
|
destroy_addr %122 : $*C
|
|
destroy_addr %121 : $*B
|
|
destroy_addr %120 : $*A
|
|
dealloc_stack %118 : $*(A, B, C, D, E, G, H, I)
|
|
destroy_addr %116 : $*I
|
|
destroy_addr %114 : $*G
|
|
destroy_addr %113 : $*E
|
|
destroy_addr %112 : $*D
|
|
destroy_addr %111 : $*C
|
|
destroy_addr %110 : $*B
|
|
destroy_addr %109 : $*A
|
|
dealloc_stack %107 : $*(A, B, C, D, E, G, H, I)
|
|
destroy_addr %105 : $*I
|
|
destroy_addr %104 : $*H
|
|
destroy_addr %102 : $*E
|
|
destroy_addr %101 : $*D
|
|
destroy_addr %100 : $*C
|
|
destroy_addr %99 : $*B
|
|
destroy_addr %98 : $*A
|
|
dealloc_stack %96 : $*(A, B, C, D, E, G, H, I)
|
|
destroy_addr %94 : $*I
|
|
destroy_addr %93 : $*H
|
|
destroy_addr %92 : $*G
|
|
destroy_addr %90 : $*D
|
|
destroy_addr %89 : $*C
|
|
destroy_addr %88 : $*B
|
|
destroy_addr %87 : $*A
|
|
dealloc_stack %85 : $*(A, B, C, D, E, G, H, I)
|
|
destroy_addr %83 : $*I
|
|
destroy_addr %82 : $*H
|
|
destroy_addr %81 : $*G
|
|
destroy_addr %80 : $*E
|
|
destroy_addr %78 : $*C
|
|
destroy_addr %77 : $*B
|
|
destroy_addr %76 : $*A
|
|
dealloc_stack %74 : $*(A, B, C, D, E, G, H, I)
|
|
destroy_addr %72 : $*I
|
|
destroy_addr %71 : $*H
|
|
destroy_addr %70 : $*G
|
|
destroy_addr %69 : $*E
|
|
destroy_addr %68 : $*D
|
|
destroy_addr %66 : $*B
|
|
destroy_addr %65 : $*A
|
|
dealloc_stack %63 : $*(A, B, C, D, E, G, H, I)
|
|
destroy_addr %61 : $*I
|
|
destroy_addr %60 : $*H
|
|
destroy_addr %59 : $*G
|
|
destroy_addr %58 : $*E
|
|
destroy_addr %57 : $*D
|
|
destroy_addr %56 : $*C
|
|
destroy_addr %54 : $*A
|
|
dealloc_stack %52 : $*(A, B, C, D, E, G, H, I)
|
|
destroy_addr %50 : $*I
|
|
destroy_addr %49 : $*H
|
|
destroy_addr %48 : $*G
|
|
destroy_addr %47 : $*E
|
|
destroy_addr %46 : $*D
|
|
destroy_addr %45 : $*C
|
|
destroy_addr %44 : $*B
|
|
dealloc_stack %41 : $*(A, B, C, D, E, G, H, I)
|
|
destroy_addr %18 : $*(A, B, C, D, E, G, H, I)
|
|
dealloc_stack %18 : $*(A, B, C, D, E, G, H, I)
|
|
%196 = tuple ()
|
|
return %196 : $()
|
|
}
|
|
|
|
sil @getInner : $@convention(thin) () -> (@owned T, @error Error)
|
|
|
|
sil [ossa] @test_mismatch_at_unreachable : $@convention(thin) () -> @owned Inner {
|
|
bb0:
|
|
%1 = alloc_stack $Inner, var, name "self"
|
|
%3 = function_ref @getInner : $@convention(thin) () -> (@owned T, @error Error)
|
|
try_apply %3() : $@convention(thin) () -> (@owned T, @error Error), normal bb1, error bb5
|
|
|
|
bb1(%5 : @owned $T):
|
|
%7 = struct_element_addr %1 : $*Inner, #Inner.a
|
|
store %5 to [init] %7 : $*T
|
|
%11 = function_ref @getInner : $@convention(thin) () -> (@owned T, @error Error)
|
|
try_apply %11() : $@convention(thin) () -> (@owned T, @error Error), normal bb2, error bb6
|
|
|
|
bb2(%13 : @owned $T):
|
|
%15 = struct_element_addr %1 : $*Inner, #Inner.b
|
|
store %13 to [init] %15 : $*T
|
|
br bb3
|
|
|
|
bb3:
|
|
%19 = load [take] %1 : $*Inner
|
|
dealloc_stack %1 : $*Inner
|
|
return %19 : $Inner
|
|
|
|
// An inconsistent state is allowed at unreachable blocks.
|
|
bb4(%23 : @owned $Error):
|
|
unreachable
|
|
|
|
bb5(%43 : @owned $Error):
|
|
br bb4(%43 : $Error)
|
|
|
|
bb6(%45 : @owned $Error):
|
|
br bb4(%45 : $Error)
|
|
}
|
|
|
|
sil [ossa] @test_memory_lifetime_select_enum : $@convention(thin) (@in_guaranteed Optional<T>) -> () {
|
|
bb0(%0 : $*Optional<T>):
|
|
%2 = integer_literal $Builtin.Int1, 0
|
|
%3 = integer_literal $Builtin.Int1, 1
|
|
%4 = select_enum_addr %0 : $*Optional<T>, case #Optional.none!enumelt: %2, case #Optional.some!enumelt: %3 : $Builtin.Int1
|
|
cond_br %4, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @test_switch_enum_addr : $@convention(thin) (@in Optional<T>) -> () {
|
|
bb0(%0 : $*Optional<T>):
|
|
switch_enum_addr %0 : $*Optional<T>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
|
|
|
|
bb1:
|
|
%2 = unchecked_take_enum_data_addr %0 : $*Optional<T>, #Optional.some!enumelt
|
|
destroy_addr %2 : $*T
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
sil [ossa] @test_switch_enum : $@convention(thin) (@in Optional<T>) -> () {
|
|
bb0(%0 : $*Optional<T>):
|
|
%1 = load_borrow %0 : $*Optional<T>
|
|
switch_enum %1 : $Optional<T>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
|
|
|
|
bb1(%3 : @guaranteed $T):
|
|
end_borrow %1 : $Optional<T>
|
|
%2 = unchecked_take_enum_data_addr %0 : $*Optional<T>, #Optional.some!enumelt
|
|
destroy_addr %2 : $*T
|
|
br bb3
|
|
|
|
bb2:
|
|
end_borrow %1 : $Optional<T>
|
|
br bb3
|
|
|
|
bb3:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
sil [ossa] @test_init_enum : $@convention(thin) (@in_guaranteed T) -> @out Optional<T> {
|
|
bb0(%0 : $*Optional<T>, %1 : $*T):
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
inject_enum_addr %0 : $*Optional<T>, #Optional.none!enumelt
|
|
br bb3
|
|
|
|
bb2:
|
|
%5 = init_enum_data_addr %0 : $*Optional<T>, #Optional.some!enumelt
|
|
copy_addr %1 to [init] %5 : $*T
|
|
inject_enum_addr %0 : $*Optional<T>, #Optional.some!enumelt
|
|
br bb3
|
|
|
|
bb3:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
sil [ossa] @test_store_to_enum : $@convention(thin) (@owned T) -> () {
|
|
bb0(%0 : @owned $T):
|
|
%1 = alloc_stack $Optional<T>
|
|
%2 = enum $Optional<T>, #Optional.some!enumelt, %0 : $T
|
|
store %2 to [init] %1 : $*Optional<T>
|
|
destroy_addr %1 : $*Optional<T>
|
|
%3 = enum $Optional<T>, #Optional.none!enumelt
|
|
store %3 to [trivial] %1 : $*Optional<T>
|
|
dealloc_stack %1 : $*Optional<T>
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
sil [ossa] @test_store_enum_tuple : $@convention(thin) (Int) -> () {
|
|
bb0(%0 : $Int):
|
|
%2 = enum $Optional<T>, #Optional.none!enumelt
|
|
%3 = tuple (%0 : $Int, %2 : $Optional<T>)
|
|
%8 = alloc_stack $(Int, Optional<T>)
|
|
store %3 to [trivial] %8 : $*(Int, Optional<T>)
|
|
dealloc_stack %8 : $*(Int, Optional<T>)
|
|
%13 = tuple ()
|
|
return %13 : $()
|
|
}
|
|
|
|
sil [ossa] @test_select_enum_addr : $@convention(thin) (@in_guaranteed Optional<T>) -> Builtin.Int1 {
|
|
bb0(%0 : $*Optional<T>):
|
|
%1 = integer_literal $Builtin.Int1, -1
|
|
%2 = integer_literal $Builtin.Int1, 0
|
|
%3 = select_enum_addr %0 : $*Optional<T>, case #Optional.some!enumelt: %1, case #Optional.none!enumelt: %2 : $Builtin.Int1
|
|
return %3 : $Builtin.Int1
|
|
}
|
|
|
|
sil [ossa] @closure : $@convention(thin) (@in_guaranteed T) -> ()
|
|
|
|
sil [ossa] @test_non_escaping_closure : $@convention(thin) (@in_guaranteed T) -> () {
|
|
bb0(%0 : $*T):
|
|
%func = function_ref @closure : $@convention(thin) (@in_guaranteed T) -> ()
|
|
%pa = partial_apply [callee_guaranteed] [on_stack] %func(%0) : $@convention(thin) (@in_guaranteed T) -> ()
|
|
destroy_value %pa : $@noescape @callee_guaranteed () -> ()
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
sil [ossa] @test_escaping_closure : $@convention(thin) (@in T) -> () {
|
|
bb0(%0 : $*T):
|
|
%func = function_ref @closure : $@convention(thin) (@in_guaranteed T) -> ()
|
|
%pa = partial_apply %func(%0) : $@convention(thin) (@in_guaranteed T) -> ()
|
|
destroy_value %pa : $@callee_owned () -> ()
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
sil [ossa] @test_store_borrow : $@convention(thin) (@guaranteed T) -> () {
|
|
bb0(%0 : @guaranteed $T):
|
|
%s = alloc_stack $T
|
|
%sb = store_borrow %0 to %s : $*T
|
|
end_borrow %sb : $*T
|
|
dealloc_stack %s : $*T
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
sil [ossa] @test_cast_br_take_always : $@convention(thin) <U, V> (@in U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $V
|
|
checked_cast_addr_br take_always U in %0 : $*U to V in %s : $*V, bb1, bb2
|
|
bb1:
|
|
destroy_addr %s : $*V
|
|
br bb3
|
|
bb2:
|
|
br bb3
|
|
bb3:
|
|
dealloc_stack %s : $*V
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
sil [ossa] @test_cast_br_take_on_success : $@convention(thin) <U, V> (@in U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $V
|
|
checked_cast_addr_br take_on_success U in %0 : $*U to V in %s : $*V, bb1, bb2
|
|
bb1:
|
|
destroy_addr %s : $*V
|
|
br bb3
|
|
bb2:
|
|
destroy_addr %0 : $*U
|
|
br bb3
|
|
bb3:
|
|
dealloc_stack %s : $*V
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
sil [ossa] @test_cast_br_copy_on_success : $@convention(thin) <U, V> (@in U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $V
|
|
checked_cast_addr_br copy_on_success U in %0 : $*U to V in %s : $*V, bb1, bb2
|
|
bb1:
|
|
destroy_addr %0 : $*U
|
|
destroy_addr %s : $*V
|
|
br bb3
|
|
bb2:
|
|
destroy_addr %0 : $*U
|
|
br bb3
|
|
bb3:
|
|
dealloc_stack %s : $*V
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
sil [ossa] @test_unconditional_checked_cast : $@convention(thin) <U, V> (@in U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $V
|
|
unconditional_checked_cast_addr U in %0 : $*U to V in %s : $*V
|
|
destroy_addr %s : $*V
|
|
dealloc_stack %s : $*V
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
sil [ossa] @test_unchecked_ref_cast : $@convention(thin) <U : AnyObject, V : AnyObject> (@in U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $V
|
|
unchecked_ref_cast_addr U in %0 : $*U to V in %s : $*V
|
|
destroy_addr %s : $*V
|
|
dealloc_stack %s : $*V
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
protocol P {}
|
|
|
|
sil [ossa] @test_existentials : $@convention(thin) <U: P> (@in_guaranteed U) -> () {
|
|
bb0(%0 : $*U):
|
|
%s = alloc_stack $P
|
|
%i = init_existential_addr %s : $*P, $U
|
|
copy_addr %0 to [init] %i : $*U
|
|
%o = open_existential_addr immutable_access %s : $*P to $*@opened("5B62392E-7C62-11EB-BF90-D0817AD9985D", P) Self
|
|
%s2 = alloc_stack $@opened("5B62392E-7C62-11EB-BF90-D0817AD9985D", P) Self
|
|
copy_addr %o to [init] %s2 : $*@opened("5B62392E-7C62-11EB-BF90-D0817AD9985D", P) Self
|
|
destroy_addr %s2 : $*@opened("5B62392E-7C62-11EB-BF90-D0817AD9985D", P) Self
|
|
dealloc_stack %s2 : $*@opened("5B62392E-7C62-11EB-BF90-D0817AD9985D", P) Self
|
|
destroy_addr %s : $*P
|
|
dealloc_stack %s : $*P
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
sil [ossa] @test_init_two_existentials : $@convention(thin) <U: P, V: P> (@in_guaranteed U, @in_guaranteed V) -> () {
|
|
bb0(%0 : $*U, %1 : $*V):
|
|
%s = alloc_stack $P
|
|
%t = init_existential_addr %s : $*P, $U
|
|
copy_addr %0 to [init] %t : $*U
|
|
destroy_addr %s : $*P
|
|
%v = init_existential_addr %s : $*P, $V
|
|
copy_addr %1 to [init] %v : $*V
|
|
destroy_addr %s : $*P
|
|
dealloc_stack %s : $*P
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
sil [ossa] @test_existential_metatype : $@convention(thin) (@in_guaranteed P) -> () {
|
|
bb0(%0 : $*P):
|
|
%714 = existential_metatype $@thick P.Type, %0 : $*P
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
sil [ossa] @test_value_metatype : $@convention(thin) <U> (@in_guaranteed U) -> () {
|
|
bb0(%0 : $*U):
|
|
%1 = value_metatype $@thick U.Type, %0 : $*U
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
sil [ossa] @test_is_unique : $@convention(thin) (@in T) -> () {
|
|
bb0(%0 : $*T):
|
|
%1 = is_unique %0 : $*T
|
|
destroy_addr %0 : $*T
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
sil [ossa] @test_fix_lifetime : $@convention(thin) (@in_guaranteed T) -> () {
|
|
bb0(%0 : $*T):
|
|
fix_lifetime %0 : $*T
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
sil [ossa] @test_ignore_empty_types : $@convention(thin) (Int, @guaranteed @callee_guaranteed (@in_guaranteed (Int, ((), ()))) -> Int) -> Int {
|
|
bb0(%0 : $Int, %1 : @guaranteed $@callee_guaranteed (@in_guaranteed (Int, ((), ()))) -> Int):
|
|
%2 = alloc_stack $(Int, ((), ()))
|
|
%3 = tuple_element_addr %2 : $*(Int, ((), ())), 0
|
|
store %0 to [trivial] %3 : $*Int
|
|
%5 = apply %1(%2) : $@callee_guaranteed (@in_guaranteed (Int, ((), ()))) -> Int
|
|
dealloc_stack %2 : $*(Int, ((), ()))
|
|
return %5 : $Int
|
|
}
|
|
|
|
enum Result<T1, T2>{
|
|
case success(T1)
|
|
case failure(T2)
|
|
}
|
|
|
|
sil @try_get_error : $@convention(thin) () -> @error Error
|
|
|
|
sil [ossa] @test_init_enum_empty_case : $@convention(thin) () -> @error Error {
|
|
bb0:
|
|
%0 = alloc_stack $Result<(), Error>
|
|
%1 = function_ref @try_get_error : $@convention(thin) () -> @error Error
|
|
try_apply %1() : $@convention(thin) () -> @error Error, normal bb1, error bb2
|
|
|
|
bb1(%3 : $()):
|
|
inject_enum_addr %0 : $*Result<(), Error>, #Result.success!enumelt
|
|
br bb3
|
|
|
|
bb2(%6 : @owned $Error):
|
|
%7 = init_enum_data_addr %0 : $*Result<(), Error>, #Result.failure!enumelt
|
|
store %6 to [init] %7 : $*Error
|
|
inject_enum_addr %0 : $*Result<(), Error>, #Result.failure!enumelt
|
|
br bb3
|
|
|
|
bb3:
|
|
%11 = load [take] %0 : $*Result<(), Error>
|
|
destroy_value %11 : $Result<(), Error>
|
|
dealloc_stack %0 : $*Result<(), Error>
|
|
%14 = tuple ()
|
|
return %14 : $()
|
|
}
|
|
|
|
sil [ossa] @begin_apply_in_destroy : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @in U
|
|
destroy_addr %instance : $*Inner
|
|
end_apply %token
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
sil [ossa] @begin_apply_in_constant_destroy : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @in_constant U
|
|
destroy_addr %instance : $*Inner
|
|
end_apply %token
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
sil [ossa] @begin_apply_in_guaranteed_no_destroy : $@convention(thin) () -> () {
|
|
entry:
|
|
(%instance, %token) = begin_apply undef<Inner>() : $@yield_once @convention(thin) <U> () -> @yields @in_guaranteed U
|
|
end_apply %token
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
sil @read_inner_b : $@convention(thin) (@in_guaranteed Inner) -> () {
|
|
[%0: read s1]
|
|
}
|
|
|
|
sil [ossa] @test_partial_read_in_argument : $@convention(thin) (@in Inner) -> () {
|
|
bb0(%0: $*Inner):
|
|
%1 = struct_element_addr %0 : $*Inner, #Inner.a
|
|
destroy_addr %1 : $*T
|
|
%3 = function_ref @read_inner_b : $@convention(thin) (@in_guaranteed Inner) -> ()
|
|
%4 = apply %3(%0) : $@convention(thin) (@in_guaranteed Inner) -> ()
|
|
%5 = struct_element_addr %0 : $*Inner, #Inner.b
|
|
destroy_addr %5 : $*T
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|