mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Compute, update and handle borrowed-from instruction in various utilities and passes. Also, used borrowed-from to simplify `gatherBorrowIntroducers` and `gatherEnclosingValues`. Replace those utilities by `Value.getBorrowIntroducers` and `Value.getEnclosingValues`, which return a lazily computed Sequence of borrowed/enclosing values.
232 lines
10 KiB
Plaintext
232 lines
10 KiB
Plaintext
// RUN: %target-sil-opt -disable-swift-verification -sil-ownership-verifier-enable-testing -ownership-verifier-textual-error-dumper -enable-sil-verify-all=0 %s -o /dev/null 2>&1 | %FileCheck %s
|
|
// REQUIRES: asserts
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
//////////////////
|
|
// Declarations //
|
|
//////////////////
|
|
|
|
class Klass {}
|
|
|
|
struct WrapperStruct {
|
|
var cls : Klass
|
|
}
|
|
|
|
sil shared [noinline] @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> () {
|
|
bb0(%0 : $Klass):
|
|
%1 = tuple ()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-NOT: Function: 'borrowed_extract_dominate_correct'
|
|
sil [ossa] @borrowed_extract_dominate_correct : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
|
|
%copy0 = copy_value %0 : $WrapperStruct
|
|
%borrow0 = begin_borrow %copy0 : $WrapperStruct
|
|
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
|
|
%func = function_ref @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%call1 = apply %func(%elem0) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %borrow0 : $WrapperStruct
|
|
destroy_value %copy0 : $WrapperStruct
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// CHECK-LABEL: Error#: 0. Begin Error in Function: 'borrowed_extract_dominate_incorrect'
|
|
// CHECK: Found outside of lifetime use?!
|
|
// CHECK: Value: %3 = begin_borrow %2 : $WrapperStruct
|
|
// CHECK: Consuming User: end_borrow %3 : $WrapperStruct
|
|
// CHECK: Non Consuming User: %7 = apply %6(%4) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
// CHECK: Block: bb0
|
|
// CHECK-LABEL: Error#: 0. End Error in Function: 'borrowed_extract_dominate_incorrect'
|
|
// CHECK-NOT: Error#: {{[0-9][0-9]*}}. End Error in Function: 'borrowed_extract_dominate_incorrect'
|
|
sil [ossa] @borrowed_extract_dominate_incorrect : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
|
|
%copy0 = copy_value %0 : $WrapperStruct
|
|
%borrow0 = begin_borrow %copy0 : $WrapperStruct
|
|
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
|
|
end_borrow %borrow0 : $WrapperStruct
|
|
%func = function_ref @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%call1 = apply %func(%elem0) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
destroy_value %copy0 : $WrapperStruct
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// CHECK-NOT: Function: 'borrowed_extract_dominate_discrepency_simple_correct'
|
|
sil [ossa] @borrowed_extract_dominate_discrepency_simple_correct : $@convention(thin) (@guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct):
|
|
%elem = struct_extract %0 : $WrapperStruct, #WrapperStruct.cls
|
|
br bb1(%elem : $Klass)
|
|
|
|
bb1(%phi : @guaranteed $Klass):
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-NOT: Function: 'simple_extract_as_phi_arg_incorrect'
|
|
sil [ossa] @simple_extract_as_phi_arg_incorrect : $@convention(thin) (@guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct):
|
|
%elem = struct_extract %0 : $WrapperStruct, #WrapperStruct.cls
|
|
br bb1(%elem : $Klass)
|
|
|
|
bb1(%newelem : @guaranteed $Klass):
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: Error#: 0. Begin Error in Function: 'borrowed_extract_dominate_discrepency_incorrect1'
|
|
// CHECK: Found outside of lifetime use?!
|
|
// CHECK: Value: %7 = argument of bb1 : $WrapperStruct
|
|
// CHECK: Consuming User: end_borrow %7 : $WrapperStruct
|
|
// CHECK: Non Consuming User: %10 = apply %9(%6) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
// CHECK: Block: bb1
|
|
// CHECK-LABEL: Error#: 0. End Error in Function: 'borrowed_extract_dominate_discrepency_incorrect1'
|
|
sil [ossa] @borrowed_extract_dominate_discrepency_incorrect1 : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
|
|
%copy0 = copy_value %0 : $WrapperStruct
|
|
%borrow0 = begin_borrow %copy0 : $WrapperStruct
|
|
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
|
|
br bb1(%elem0 : $Klass, %borrow0 : $WrapperStruct)
|
|
|
|
bb1(%elem : @guaranteed $Klass, %newborrow : @guaranteed $WrapperStruct):
|
|
end_borrow %newborrow : $WrapperStruct
|
|
%func = function_ref @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%call1 = apply %func(%elem) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
destroy_value %copy0 : $WrapperStruct
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// CHECK-LABEL: Error#: 0. Begin Error in Function: 'borrowed_extract_dominate_discrepency_incorrect2'
|
|
// CHECK: Found outside of lifetime use?!
|
|
// CHECK: Value: %2 = copy_value %0 : $WrapperStruct
|
|
// CHECK: Consuming User: destroy_value %2 : $WrapperStruct
|
|
// CHECK: Non Consuming User: end_borrow %7 : $WrapperStruct
|
|
// CHECK: Block: bb1
|
|
// CHECK-LABEL: Error#: 0. End Error in Function: 'borrowed_extract_dominate_discrepency_incorrect2'
|
|
// CHECK-NOT: Error#: {{[0-9][0-9]*}}. End Error in Function: 'borrowed_extract_dominate_discrepency_incorrect2'
|
|
sil [ossa] @borrowed_extract_dominate_discrepency_incorrect2 : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
|
|
%copy0 = copy_value %0 : $WrapperStruct
|
|
%borrow0 = begin_borrow %copy0 : $WrapperStruct
|
|
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
|
|
br bb1(%elem0 : $Klass, %borrow0 : $WrapperStruct)
|
|
|
|
bb1(%elem : @guaranteed $Klass, %newborrow : @guaranteed $WrapperStruct):
|
|
%func = function_ref @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> ()
|
|
destroy_value %copy0 : $WrapperStruct
|
|
%call1 = apply %func(%elem) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %newborrow : $WrapperStruct
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// CHECK-NOT: Function: 'borrowed_extract_not_dominate_correct'
|
|
sil [ossa] @borrowed_extract_not_dominate_correct : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
%copy0 = copy_value %0 : $WrapperStruct
|
|
%borrow0 = begin_borrow %copy0 : $WrapperStruct
|
|
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
|
|
br bb3(%elem0 : $Klass, %borrow0 : $WrapperStruct, %copy0 : $WrapperStruct)
|
|
|
|
bb2:
|
|
%copy1 = copy_value %1 : $WrapperStruct
|
|
%borrow1 = begin_borrow %copy1 : $WrapperStruct
|
|
%elem1 = struct_extract %borrow1 : $WrapperStruct, #WrapperStruct.cls
|
|
br bb3(%elem1 : $Klass, %borrow1 : $WrapperStruct, %copy1 : $WrapperStruct)
|
|
|
|
bb3(%elem : @guaranteed $Klass, %newborrow : @guaranteed $WrapperStruct, %newowned : @owned $WrapperStruct):
|
|
%func = function_ref @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%call1 = apply %func(%elem) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %newborrow : $WrapperStruct
|
|
destroy_value %newowned : $WrapperStruct
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// CHECK-NOT: Error#: {{[0-9][0-9]*}}. End Error in Function: 'borrowed_extract_not_dominate_incorrect1'
|
|
sil [ossa] @borrowed_extract_not_dominate_incorrect1 : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
%copy0 = copy_value %0 : $WrapperStruct
|
|
%borrow0 = begin_borrow %copy0 : $WrapperStruct
|
|
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
|
|
br bb3(%elem0 : $Klass, %borrow0 : $WrapperStruct, %copy0 : $WrapperStruct)
|
|
|
|
bb2:
|
|
%copy1 = copy_value %1 : $WrapperStruct
|
|
%borrow1 = begin_borrow %copy1 : $WrapperStruct
|
|
%elem1 = struct_extract %borrow1 : $WrapperStruct, #WrapperStruct.cls
|
|
br bb3(%elem1 : $Klass, %borrow1 : $WrapperStruct, %copy1 : $WrapperStruct)
|
|
|
|
bb3(%elem : @guaranteed $Klass, %newborrow : @guaranteed $WrapperStruct, %newowned : @owned $WrapperStruct):
|
|
%func = function_ref @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%call1 = apply %func(%elem) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %newborrow : $WrapperStruct
|
|
destroy_value %newowned : $WrapperStruct
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// CHECK-NOT: Function: 'borrowed_extract_dominates_one_path'
|
|
sil [ossa] @borrowed_extract_dominates_one_path : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
|
|
%copy1 = copy_value %1 : $WrapperStruct
|
|
%borrow1 = begin_borrow %copy1 : $WrapperStruct
|
|
%elem1 = struct_extract %borrow1 : $WrapperStruct, #WrapperStruct.cls
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
end_borrow %borrow1 : $WrapperStruct
|
|
%copy0 = copy_value %0 : $WrapperStruct
|
|
%borrow0 = begin_borrow %copy0 : $WrapperStruct
|
|
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
|
|
br bb3(%elem0 : $Klass, %borrow0 : $WrapperStruct, %copy0 : $WrapperStruct)
|
|
|
|
bb2:
|
|
%copy2 = copy_value %1 : $WrapperStruct
|
|
br bb3(%elem1 : $Klass, %borrow1 : $WrapperStruct, %copy2 : $WrapperStruct)
|
|
|
|
bb3(%elem : @guaranteed $Klass, %newborrow : @guaranteed $WrapperStruct, %newowned : @owned $WrapperStruct):
|
|
end_borrow %newborrow : $WrapperStruct
|
|
destroy_value %newowned : $WrapperStruct
|
|
destroy_value %copy1 : $WrapperStruct
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
// CHECK-NOT: Function: 'borrowed_extract_dominates_one_path_loop'
|
|
sil [ossa] @borrowed_extract_dominates_one_path_loop : $@convention(thin) (@guaranteed WrapperStruct) -> () {
|
|
bb0(%0 : @guaranteed $WrapperStruct):
|
|
%1b = copy_value %0 : $WrapperStruct
|
|
%1a = begin_borrow %1b : $WrapperStruct
|
|
%elem0 = struct_extract %1a : $WrapperStruct, #WrapperStruct.cls
|
|
br bb1(%elem0 : $Klass, %1a : $WrapperStruct, %1b : $WrapperStruct)
|
|
|
|
bb1(%elem : @guaranteed $Klass, %2a : @guaranteed $WrapperStruct, %2b : @owned $WrapperStruct):
|
|
cond_br undef, bb2, bb3
|
|
|
|
bb2:
|
|
%3 = copy_value %2a : $WrapperStruct
|
|
%3a = begin_borrow %3 : $WrapperStruct
|
|
%elem1 = struct_extract %3a : $WrapperStruct, #WrapperStruct.cls
|
|
end_borrow %2a : $WrapperStruct
|
|
destroy_value %2b : $WrapperStruct
|
|
br bb1(%elem1 : $Klass, %3a : $WrapperStruct, %3 : $WrapperStruct)
|
|
|
|
bb3:
|
|
end_borrow %2a : $WrapperStruct
|
|
destroy_value %2b : $WrapperStruct
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|