mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
@guaranteed stored values will never be added to a phi in mem2reg because any uses of store borrowed locations have to be accessed via the store borrow return address and since we ban address phis altogether we will never have input sil which necessitates this. But, the DJ-edges based algorithm for inserting phi blocks in mem2reg can insert unnecessary phis which are removed later. Ensure fixPhiPredBlock handles both owned and guaranteed stored values correctly for this reason.
564 lines
17 KiB
Plaintext
564 lines
17 KiB
Plaintext
// RUN: %target-sil-opt -enable-sil-verify-all -enable-lexical-lifetimes %s -mem2reg | %FileCheck %s
|
|
import Builtin
|
|
|
|
class Klass {}
|
|
|
|
struct WrapperStruct {
|
|
var val:Klass
|
|
}
|
|
|
|
public enum FakeOptional {
|
|
case none
|
|
case some(Klass)
|
|
}
|
|
|
|
sil [ossa] @use_inguaranteed : $@convention(thin) (@in_guaranteed Klass) -> ()
|
|
sil [ossa] @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
sil [ossa] @use_owned : $@convention(thin) (@owned Klass) -> ()
|
|
sil [ossa] @get_owned : $@convention(thin) () -> @owned Klass
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_no_storeborrow1 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_no_storeborrow1'
|
|
sil [ossa] @test_no_storeborrow1 : $@convention(thin) (@owned Klass) -> () {
|
|
bb0(%0 : @owned $Klass):
|
|
%stk = alloc_stack [lexical] $Klass
|
|
store %0 to [init] %stk : $*Klass
|
|
%ld = load_borrow %stk : $*Klass
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%4 = apply %3(%ld) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %ld : $Klass
|
|
destroy_addr %stk : $*Klass
|
|
dealloc_stack %stk : $*Klass
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_no_storeborrow2 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_no_storeborrow2'
|
|
sil [ossa] @test_no_storeborrow2 : $@convention(method) (@owned Klass) -> () {
|
|
bb0(%0 : @owned $Klass):
|
|
%stk = alloc_stack [lexical] $Klass
|
|
store %0 to [init] %stk : $*Klass
|
|
%ld1 = load_borrow %stk : $*Klass
|
|
%f = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
apply %f(%ld1) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %ld1 : $Klass
|
|
cond_br undef, bb3, bb1
|
|
|
|
bb1:
|
|
%ld2 = load_borrow %stk : $*Klass
|
|
apply %f(%ld2) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %ld2 : $Klass
|
|
%tk1 = load [take] %stk : $*Klass
|
|
destroy_value %tk1 : $Klass
|
|
dealloc_stack %stk : $*Klass
|
|
br bb4
|
|
|
|
bb3:
|
|
%tk2 = load [take] %stk : $*Klass
|
|
destroy_value %tk2 : $Klass
|
|
dealloc_stack %stk : $*Klass
|
|
br bb4
|
|
|
|
bb4:
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_no_storeborrow3 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_no_storeborrow3'
|
|
sil [ossa] @test_no_storeborrow3 : $@convention(thin) (@owned Klass) -> () {
|
|
bb0(%0 : @owned $Klass):
|
|
%1 = alloc_stack [lexical] $Klass
|
|
store %0 to [init] %1 : $*Klass
|
|
%2 = load_borrow %1 : $*Klass
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%4 = apply %3(%2) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %2 : $Klass
|
|
destroy_addr %1 : $*Klass
|
|
dealloc_stack %1 : $*Klass
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_no_storeborrow4 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_no_storeborrow4'
|
|
sil [ossa] @test_no_storeborrow4 : $@convention(thin) (@owned Klass) -> () {
|
|
bb0(%0 : @owned $Klass):
|
|
%1 = alloc_stack [lexical] $Klass
|
|
store %0 to [init] %1 : $*Klass
|
|
%2 = load_borrow %1 : $*Klass
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%4 = apply %3(%2) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %2 : $Klass
|
|
destroy_addr %1 : $*Klass
|
|
dealloc_stack %1 : $*Klass
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
// load_borrow of projections are not optimized
|
|
// CHECK-LABEL: sil [ossa] @test_with_structs_and_borrows1 :
|
|
// CHECK: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_with_structs_and_borrows1'
|
|
sil [ossa] @test_with_structs_and_borrows1 : $@convention(thin) (@guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct):
|
|
%stk = alloc_stack [lexical] $WrapperStruct
|
|
%sb = store_borrow %0 to %stk : $*WrapperStruct
|
|
%ele = struct_element_addr %sb : $*WrapperStruct, #WrapperStruct.val
|
|
%ld = load_borrow %ele : $*Klass
|
|
%f = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
apply %f(%ld) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %ld : $Klass
|
|
end_borrow %sb : $*WrapperStruct
|
|
dealloc_stack %stk : $*WrapperStruct
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @storeborrow_only_lexicalallocas :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'storeborrow_only_lexicalallocas'
|
|
sil [ossa] @storeborrow_only_lexicalallocas : $@convention(thin) (@guaranteed Klass) -> () {
|
|
bb0(%0 : @guaranteed $Klass):
|
|
%1 = alloc_stack [lexical] $Klass
|
|
%sb = store_borrow %0 to %1 : $*Klass
|
|
end_borrow %sb : $*Klass
|
|
dealloc_stack %1 : $*Klass
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test1 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test1'
|
|
sil [ossa] @test1 : $@convention(thin) (@guaranteed Klass) -> () {
|
|
bb0(%0 : @guaranteed $Klass):
|
|
%1 = alloc_stack [lexical] $Klass
|
|
%sb = store_borrow %0 to %1 : $*Klass
|
|
%2 = load_borrow %sb : $*Klass
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%4 = apply %3(%2) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %2 : $Klass
|
|
end_borrow %sb : $*Klass
|
|
dealloc_stack %1 : $*Klass
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test2 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test2'
|
|
sil [ossa] @test2 : $@convention(thin) (@guaranteed Klass) -> () {
|
|
bb0(%0 : @guaranteed $Klass):
|
|
%1 = alloc_stack [lexical] $Klass
|
|
%sb = store_borrow %0 to %1 : $*Klass
|
|
%2 = load_borrow %sb : $*Klass
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%4 = apply %3(%2) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %2 : $Klass
|
|
%5 = load_borrow %sb : $*Klass
|
|
%6 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%7 = apply %3(%5) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %5 : $Klass
|
|
end_borrow %sb : $*Klass
|
|
dealloc_stack %1 : $*Klass
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test3 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test3'
|
|
sil [ossa] @test3 : $@convention(thin) (@guaranteed Klass, @guaranteed Klass) -> () {
|
|
bb0(%0 : @guaranteed $Klass, %1 : @guaranteed $Klass):
|
|
%2 = alloc_stack [lexical] $Klass
|
|
%sb1 = store_borrow %0 to %2 : $*Klass
|
|
%3 = load_borrow %sb1 : $*Klass
|
|
%4 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%5 = apply %4(%3) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %3 : $Klass
|
|
end_borrow %sb1 : $*Klass
|
|
%sb2 = store_borrow %1 to %2 : $*Klass
|
|
%6 = load_borrow %sb2 : $*Klass
|
|
%7 = apply %4(%6) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %6 : $Klass
|
|
end_borrow %sb2 : $*Klass
|
|
dealloc_stack %2 : $*Klass
|
|
%9 = tuple ()
|
|
return %9 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test4 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test4'
|
|
sil [ossa] @test4 : $@convention(thin) (@guaranteed Klass) -> () {
|
|
bb0(%0 : @guaranteed $Klass):
|
|
%1 = alloc_stack [lexical] $Klass
|
|
%sb = store_borrow %0 to %1 : $*Klass
|
|
%2 = load_borrow %sb : $*Klass
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%4 = apply %3(%2) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %2 : $Klass
|
|
%5 = load [copy] %sb : $*Klass
|
|
end_borrow %sb : $*Klass
|
|
%6 = function_ref @use_owned : $@convention(thin) (@owned Klass) -> ()
|
|
%7 = apply %6(%5) : $@convention(thin) (@owned Klass) -> ()
|
|
dealloc_stack %1 : $*Klass
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test6 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test6'
|
|
sil [ossa] @test6 : $@convention(thin) (@owned Klass) -> () {
|
|
bb0(%0 : @owned $Klass):
|
|
%1 = alloc_stack [lexical] $Klass
|
|
%b = begin_borrow %0 : $Klass
|
|
%sb = store_borrow %b to %1 : $*Klass
|
|
%2 = load_borrow %sb : $*Klass
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%4 = apply %3(%2) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %2 : $Klass
|
|
end_borrow %sb : $*Klass
|
|
end_borrow %b : $Klass
|
|
destroy_value %0 : $Klass
|
|
dealloc_stack %1 : $*Klass
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test7 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test7'
|
|
sil [ossa] @test7 : $@convention(thin) (@owned Klass) -> () {
|
|
bb0(%0 : @owned $Klass):
|
|
%1 = alloc_stack [lexical] $Klass
|
|
%b = begin_borrow %0 : $Klass
|
|
%sb = store_borrow %b to %1 : $*Klass
|
|
%2 = load_borrow %sb : $*Klass
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%4 = apply %3(%2) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %2 : $Klass
|
|
end_borrow %sb : $*Klass
|
|
end_borrow %b : $Klass
|
|
destroy_value %0 : $Klass
|
|
unreachable
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test8 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test8'
|
|
sil [ossa] @test8 : $@convention(thin) (@owned Klass) -> () {
|
|
bb0(%0 : @owned $Klass):
|
|
%1 = alloc_stack [lexical] $Klass
|
|
%b = begin_borrow %0 : $Klass
|
|
%sb = store_borrow %b to %1 : $*Klass
|
|
%2 = load [copy] %sb : $*Klass
|
|
end_borrow %sb : $*Klass
|
|
end_borrow %b : $Klass
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%4 = apply %3(%2) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
destroy_value %2 : $Klass
|
|
destroy_value %0 : $Klass
|
|
dealloc_stack %1 : $*Klass
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_control_flow4 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_control_flow4'
|
|
sil [ossa] @test_control_flow4 : $@convention(thin) (@guaranteed Klass) -> () {
|
|
bb0(%0 : @guaranteed $Klass):
|
|
%stk = alloc_stack [lexical] $Klass
|
|
%sb = store_borrow %0 to %stk : $*Klass
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
%ld1 = load_borrow %sb : $*Klass
|
|
fix_lifetime %ld1 : $Klass
|
|
end_borrow %ld1 : $Klass
|
|
end_borrow %sb : $*Klass
|
|
dealloc_stack %stk : $*Klass
|
|
%r = tuple ()
|
|
return %r : $()
|
|
|
|
bb2:
|
|
%ld2 = load_borrow %sb : $*Klass
|
|
fix_lifetime %ld2 : $Klass
|
|
end_borrow %ld2 : $Klass
|
|
end_borrow %sb : $*Klass
|
|
dealloc_stack %stk : $*Klass
|
|
unreachable
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_control_flow5 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_control_flow5'
|
|
sil [ossa] @test_control_flow5 : $@convention(thin) (@guaranteed Klass, @guaranteed Klass) -> () {
|
|
bb0(%0 : @guaranteed $Klass, %1 : @guaranteed $Klass):
|
|
%stk = alloc_stack [lexical] $Klass
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
%copy1 = copy_value %0 : $Klass
|
|
store %copy1 to [init] %stk : $*Klass
|
|
br bb3
|
|
|
|
bb2:
|
|
%copy2 = copy_value %1 : $Klass
|
|
store %copy2 to [init] %stk : $*Klass
|
|
br bb3
|
|
|
|
bb3:
|
|
%2 = load_borrow %stk : $*Klass
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%4 = apply %3(%2) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %2 : $Klass
|
|
destroy_addr %stk : $*Klass
|
|
dealloc_stack %stk : $*Klass
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
// Test no ownership verifier error
|
|
// CHECK-LABEL: sil [ossa] @test_control_flow6 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_control_flow6'
|
|
sil [ossa] @test_control_flow6 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = function_ref @get_owned : $@convention(thin) () -> @owned Klass
|
|
%1 = alloc_stack [lexical] $Klass
|
|
%2 = apply %0() : $@convention(thin) () -> @owned Klass
|
|
store %2 to [init] %1 : $*Klass
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
%5 = apply %0() : $@convention(thin) () -> @owned Klass
|
|
store %5 to [assign] %1 : $*Klass
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
%9 = load_borrow %1 : $*Klass
|
|
end_borrow %9 : $Klass
|
|
br bb4
|
|
|
|
bb4:
|
|
cond_br undef, bb8, bb9
|
|
|
|
bb8:
|
|
br bb4
|
|
|
|
bb9:
|
|
cond_br undef, bb10, bb11
|
|
|
|
bb10:
|
|
br bb12
|
|
|
|
bb11:
|
|
%19 = load [copy] %1 : $*Klass
|
|
%20 = function_ref @use_owned : $@convention(thin) (@owned Klass) -> ()
|
|
%21 = apply %20(%19) : $@convention(thin) (@owned Klass) -> ()
|
|
br bb12
|
|
|
|
bb12:
|
|
%23 = apply %0() : $@convention(thin) () -> @owned Klass
|
|
store %23 to [assign] %1 : $*Klass
|
|
cond_br undef, bb13, bb14
|
|
|
|
bb13:
|
|
%26 = load [take] %1 : $*Klass
|
|
destroy_value %26 : $Klass
|
|
dealloc_stack %1 : $*Klass
|
|
%29 = tuple ()
|
|
return %29 : $()
|
|
|
|
bb14:
|
|
unreachable
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_control_flow7 :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_control_flow7'
|
|
sil [ossa] @test_control_flow7 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%4 = alloc_stack [lexical] $Klass
|
|
%f = function_ref @get_owned : $@convention(thin) () -> @owned Klass
|
|
%5 = apply %f() : $@convention(thin) () -> @owned Klass
|
|
store %5 to [init] %4 : $*Klass
|
|
%7 = load_borrow %4 : $*Klass
|
|
end_borrow %7 : $Klass
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3
|
|
|
|
bb2:
|
|
%28 = load_borrow %4 : $*Klass
|
|
end_borrow %28 : $Klass
|
|
br bb3
|
|
|
|
bb3:
|
|
destroy_addr %4 : $*Klass
|
|
dealloc_stack %4 : $*Klass
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// Test no ownership verifier error
|
|
// CHECK-LABEL: sil [ossa] @test_two_stacklocs :
|
|
// CHECK: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_two_stacklocs'
|
|
sil [ossa] @test_two_stacklocs : $@convention(method) (@guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct):
|
|
%2 = struct_extract %0 : $WrapperStruct, #WrapperStruct.val
|
|
%3 = alloc_stack [lexical] $Klass
|
|
%4 = store_borrow %2 to %3 : $*Klass
|
|
%5 = load_borrow %4 : $*Klass
|
|
%6 = alloc_stack [lexical] $Klass
|
|
%7 = store_borrow %5 to %6 : $*Klass
|
|
%f = function_ref @use_inguaranteed : $@convention(thin) (@in_guaranteed Klass) -> ()
|
|
apply %f(%7) : $@convention(thin) (@in_guaranteed Klass) -> ()
|
|
end_borrow %7 : $*Klass
|
|
end_borrow %5 : $Klass
|
|
end_borrow %4 : $*Klass
|
|
dealloc_stack %6 : $*Klass
|
|
dealloc_stack %3 : $*Klass
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_optional :
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_optional'
|
|
sil [ossa] @test_optional : $@convention(thin) () -> () {
|
|
bb0:
|
|
%stk = alloc_stack [lexical] $FakeOptional
|
|
%none = enum $FakeOptional, #FakeOptional.none!enumelt
|
|
%sb = store_borrow %none to %stk : $*FakeOptional
|
|
%ld1 = load_borrow %sb : $*FakeOptional
|
|
end_borrow %ld1 : $FakeOptional
|
|
end_borrow %sb : $*FakeOptional
|
|
dealloc_stack %stk : $*FakeOptional
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_deinit_point :
|
|
// CHECK: alloc_stack
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_deinit_point'
|
|
sil [ossa] @test_deinit_point : $@convention(thin) (@guaranteed Klass) -> () {
|
|
bb0(%0 : @guaranteed $Klass):
|
|
%stk = alloc_stack [lexical] $Klass
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
%tmp = alloc_stack $Klass
|
|
%sb = store_borrow %0 to %tmp : $*Klass
|
|
%f = function_ref @use_inguaranteed : $@convention(thin) (@in_guaranteed Klass) -> ()
|
|
%c = apply %f(%sb) : $@convention(thin) (@in_guaranteed Klass) -> ()
|
|
end_borrow %sb : $*Klass
|
|
dealloc_stack %tmp : $*Klass
|
|
%copy = copy_value %0 : $Klass
|
|
store %copy to [init] %stk : $*Klass
|
|
%l = load [take] %stk : $*Klass
|
|
destroy_value %l : $Klass
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
dealloc_stack %stk : $*Klass
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'storeborrow_multi_only_lexicalallocas'
|
|
sil [ossa] @storeborrow_multi_only_lexicalallocas : $@convention(thin) (@in_guaranteed Klass) -> () {
|
|
bb0(%0 : $*Klass):
|
|
%l = load_borrow %0 : $*Klass
|
|
%1 = alloc_stack [lexical] $Klass
|
|
%sb = store_borrow %l to %1 : $*Klass
|
|
br bb1
|
|
|
|
bb1:
|
|
end_borrow %sb : $*Klass
|
|
end_borrow %l : $Klass
|
|
dealloc_stack %1 : $*Klass
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_nested_sbi :
|
|
// CHECK: alloc_stack
|
|
// CHECK-NOT: alloc_stack [lexical]
|
|
// CHECK-LABEL: } // end sil function 'test_nested_sbi'
|
|
sil [ossa] @test_nested_sbi : $@convention(thin) (@guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct):
|
|
%2 = alloc_stack [lexical] $WrapperStruct
|
|
%3 = store_borrow %0 to %2 : $*WrapperStruct
|
|
%6 = load_borrow %3 : $*WrapperStruct
|
|
%7 = alloc_stack [lexical] $WrapperStruct
|
|
%8 = store_borrow %6 to %7 : $*WrapperStruct
|
|
%9 = struct_element_addr %8 : $*WrapperStruct, #WrapperStruct.val
|
|
%16 = load_borrow %9 : $*Klass
|
|
end_borrow %16 : $Klass
|
|
end_borrow %8 : $*WrapperStruct
|
|
dealloc_stack %7 : $*WrapperStruct
|
|
end_borrow %6 : $WrapperStruct
|
|
%27 = load_borrow %3 : $*WrapperStruct
|
|
end_borrow %27 : $WrapperStruct
|
|
end_borrow %3 : $*WrapperStruct
|
|
dealloc_stack %2 : $*WrapperStruct
|
|
%33 = tuple ()
|
|
return %33 : $()
|
|
}
|
|
|
|
// Ensure we don't have an ownership verification error
|
|
sil [ossa] @test_store_borrow_phi : $@convention(thin) () -> () {
|
|
bb0:
|
|
br bb1
|
|
|
|
bb1:
|
|
%1 = apply undef() : $@convention(thin) () -> @owned Klass
|
|
%2 = begin_borrow %1 : $Klass
|
|
%3 = alloc_stack [lexical] $Klass
|
|
%4 = store_borrow %2 to %3 : $*Klass
|
|
%5 = load_borrow %4 : $*Klass
|
|
%6 = apply undef(%5) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %5 : $Klass
|
|
end_borrow %4 : $*Klass
|
|
cond_br undef, bb2, bb3
|
|
|
|
bb2:
|
|
br bb4
|
|
|
|
bb3:
|
|
br bb4
|
|
|
|
bb4:
|
|
dealloc_stack %3 : $*Klass
|
|
end_borrow %2 : $Klass
|
|
destroy_value %1 : $Klass
|
|
cond_br undef, bb5, bb6
|
|
|
|
bb5:
|
|
br bb1
|
|
|
|
bb6:
|
|
%17 = tuple ()
|
|
return %17 : $()
|
|
}
|