mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
A dead borrowed-from can only be removed if the argument (= operand) is also removed. Fixes a compiler crash.
169 lines
6.3 KiB
Plaintext
169 lines
6.3 KiB
Plaintext
// RUN: %target-sil-opt -enable-sil-verify-all %s -simplification | %FileCheck %s
|
|
|
|
// REQUIRES: swift_in_compiler
|
|
|
|
import Builtin
|
|
import Swift
|
|
import SwiftShims
|
|
|
|
class Buffer {}
|
|
|
|
sil_global @_swiftEmptyArrayStorage : $_SwiftEmptyArrayStorage
|
|
|
|
// CHECK-LABEL: sil [ossa] @remove_end_begin_cow_pair
|
|
// CHECK-NOT: end_cow_mutation
|
|
// CHECK-NOT: begin_cow_mutation
|
|
// CHECK: return %0
|
|
// CHECK: } // end sil function 'remove_end_begin_cow_pair'
|
|
sil [ossa] @remove_end_begin_cow_pair : $@convention(thin) (@owned Buffer) -> @owned Buffer {
|
|
bb0(%0 : @owned $Buffer):
|
|
%e = end_cow_mutation %0 : $Buffer
|
|
debug_value %e : $Buffer, var, name "x"
|
|
(%u, %b) = begin_cow_mutation %e : $Buffer
|
|
return %b : $Buffer
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @dont_remove_end_begin_cow_pair1
|
|
// CHECK: end_cow_mutation
|
|
// CHECK: begin_cow_mutation
|
|
// CHECK: } // end sil function 'dont_remove_end_begin_cow_pair1'
|
|
sil [ossa] @dont_remove_end_begin_cow_pair1 : $@convention(thin) (@owned Buffer) -> @owned (Buffer, Buffer) {
|
|
bb0(%0 : @owned $Buffer):
|
|
%e = end_cow_mutation %0 : $Buffer
|
|
%c = copy_value %e : $Buffer
|
|
(%u, %b) = begin_cow_mutation %e : $Buffer
|
|
%t = tuple (%c : $Buffer, %b : $Buffer)
|
|
return %t : $(Buffer, Buffer)
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @dont_remove_end_begin_cow_pair2
|
|
// CHECK: end_cow_mutation
|
|
// CHECK: begin_cow_mutation
|
|
// CHECK: } // end sil function 'dont_remove_end_begin_cow_pair2'
|
|
sil [ossa] @dont_remove_end_begin_cow_pair2 : $@convention(thin) (@owned Buffer) -> @owned (Builtin.Int1, Buffer) {
|
|
bb0(%0 : @owned $Buffer):
|
|
%e = end_cow_mutation %0 : $Buffer
|
|
(%u, %b) = begin_cow_mutation %e : $Buffer
|
|
%t = tuple (%u : $Builtin.Int1, %b : $Buffer)
|
|
return %t : $(Builtin.Int1, Buffer)
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @dont_remove_end_begin_cow_pair3
|
|
// CHECK: end_cow_mutation
|
|
// CHECK: begin_cow_mutation
|
|
// CHECK: } // end sil function 'dont_remove_end_begin_cow_pair3'
|
|
sil [ossa] @dont_remove_end_begin_cow_pair3 : $@convention(thin) (@owned Buffer) -> @owned Buffer {
|
|
bb0(%0 : @owned $Buffer):
|
|
%e = end_cow_mutation [keep_unique] %0 : $Buffer
|
|
(%u, %b) = begin_cow_mutation %e : $Buffer
|
|
return %b : $Buffer
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @remove_begin_end_cow_pair
|
|
// CHECK-NOT: end_cow_mutation
|
|
// CHECK-NOT: begin_cow_mutation
|
|
// CHECK: return %0
|
|
// CHECK: } // end sil function 'remove_begin_end_cow_pair'
|
|
sil [ossa] @remove_begin_end_cow_pair : $@convention(thin) (@owned Buffer) -> @owned Buffer {
|
|
bb0(%0 : @owned $Buffer):
|
|
(%u, %b) = begin_cow_mutation %0 : $Buffer
|
|
debug_value %u : $Builtin.Int1, var, name "x"
|
|
debug_value %b : $Buffer, var, name "y"
|
|
%e = end_cow_mutation %b : $Buffer
|
|
return %e : $Buffer
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @dont_remove_begin_end_cow_pair1
|
|
// CHECK: begin_cow_mutation
|
|
// CHECK: end_cow_mutation
|
|
// CHECK: } // end sil function 'dont_remove_begin_end_cow_pair1'
|
|
sil [ossa] @dont_remove_begin_end_cow_pair1 : $@convention(thin) (@owned Buffer) -> @owned (Buffer, Buffer) {
|
|
bb0(%0 : @owned $Buffer):
|
|
(%u, %b) = begin_cow_mutation %0 : $Buffer
|
|
%c = copy_value %b : $Buffer
|
|
%e = end_cow_mutation %b : $Buffer
|
|
%t = tuple (%c : $Buffer, %e : $Buffer)
|
|
return %t : $(Buffer, Buffer)
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @dont_remove_begin_end_cow_pair2
|
|
// CHECK: begin_cow_mutation
|
|
// CHECK: end_cow_mutation
|
|
// CHECK: } // end sil function 'dont_remove_begin_end_cow_pair2'
|
|
sil [ossa] @dont_remove_begin_end_cow_pair2 : $@convention(thin) (@owned Buffer) -> @owned (Builtin.Int1, Buffer) {
|
|
bb0(%0 : @owned $Buffer):
|
|
(%u, %b) = begin_cow_mutation %0 : $Buffer
|
|
%e = end_cow_mutation %b : $Buffer
|
|
%t = tuple (%u : $Builtin.Int1, %e : $Buffer)
|
|
return %t : $(Builtin.Int1, Buffer)
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @dont_remove_begin_end_cow_pair3
|
|
// CHECK: begin_cow_mutation
|
|
// CHECK: end_cow_mutation
|
|
// CHECK: } // end sil function 'dont_remove_begin_end_cow_pair3'
|
|
sil [ossa] @dont_remove_begin_end_cow_pair3 : $@convention(thin) (@owned Buffer) -> @owned Buffer {
|
|
bb0(%0 : @owned $Buffer):
|
|
(%u, %b) = begin_cow_mutation %0 : $Buffer
|
|
%e = end_cow_mutation [keep_unique] %b : $Buffer
|
|
return %e : $Buffer
|
|
}
|
|
// CHECK-LABEL: sil @optimize_empty_cow_singleton
|
|
// CHECK: [[I:%[0-9]+]] = integer_literal $Builtin.Int1, 0
|
|
// CHECK: begin_cow_mutation
|
|
// CHECK: [[T:%[0-9]+]] = tuple ([[I]]
|
|
// CHECK: return [[T]]
|
|
// CHECK: } // end sil function 'optimize_empty_cow_singleton'
|
|
sil @optimize_empty_cow_singleton : $@convention(thin) () -> (Builtin.Int1, @owned Builtin.BridgeObject) {
|
|
bb0:
|
|
%3 = global_addr @_swiftEmptyArrayStorage : $*_SwiftEmptyArrayStorage
|
|
%4 = address_to_pointer %3 : $*_SwiftEmptyArrayStorage to $Builtin.RawPointer
|
|
%5 = raw_pointer_to_ref %4 : $Builtin.RawPointer to $__EmptyArrayStorage
|
|
%6 = unchecked_ref_cast %5 : $__EmptyArrayStorage to $Builtin.BridgeObject
|
|
(%u, %b) = begin_cow_mutation %6 : $Builtin.BridgeObject
|
|
%t = tuple (%u : $Builtin.Int1, %b : $Builtin.BridgeObject)
|
|
return %t : $(Builtin.Int1, Builtin.BridgeObject)
|
|
}
|
|
|
|
sil_global private @outlined_global : $_ContiguousArrayStorage<Int>
|
|
|
|
// CHECK-LABEL: sil @remove_arc_of_global_value
|
|
// CHECK-NOT: retain
|
|
// CHECK-NOT: release
|
|
// CHECK-NOT: fix_lifetime
|
|
// CHECK-NOT: debug_value
|
|
// CHECK: } // end sil function 'remove_arc_of_global_value'
|
|
sil @remove_arc_of_global_value : $@convention(thin) () -> Int {
|
|
bb0:
|
|
%0 = global_value @outlined_global : $_ContiguousArrayStorage<Int>
|
|
strong_retain %0 : $_ContiguousArrayStorage<Int>
|
|
debug_value %0 : $_ContiguousArrayStorage<Int>, let, name "x"
|
|
%2 = upcast %0 : $_ContiguousArrayStorage<Int> to $__ContiguousArrayStorageBase
|
|
strong_retain %2 : $__ContiguousArrayStorageBase
|
|
%13 = ref_tail_addr [immutable] %2 : $__ContiguousArrayStorageBase, $Int
|
|
%16 = load %13 : $*Int
|
|
fix_lifetime %0 : $_ContiguousArrayStorage<Int>
|
|
strong_release %2 : $__ContiguousArrayStorageBase
|
|
strong_release %0 : $_ContiguousArrayStorage<Int>
|
|
return %16 : $Int
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_dead_borrowed_from
|
|
// CHECK: borrowed {{.*}} from
|
|
// CHECK: } // end sil function 'test_dead_borrowed_from'
|
|
sil [ossa] @test_dead_borrowed_from : $@convention(thin) (@guaranteed Buffer, @guaranteed Buffer) -> () {
|
|
bb0(%0 : @guaranteed $Buffer, %1 : @guaranteed $Buffer):
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3(%0 : $Buffer)
|
|
|
|
bb2:
|
|
br bb3(%1 : $Buffer)
|
|
|
|
bb3(%9 : @guaranteed $Buffer):
|
|
%10 = borrowed %9 : $Buffer from (%1 : $Buffer)
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|