mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
When an optimization updates borrowed-from instruction it might be necessary to remove the old enclosing values from the borrowed-from instructions. An optimization might transform the SIL in a way that an existing enclosing value is not valid anymore. Fixes a compiler crash: rdar://142991910
122 lines
4.2 KiB
Plaintext
122 lines
4.2 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -enable-objc-interop -enforce-exclusivity=none -enable-sil-verify-all %s -sil-combine -sil-combine-disable-alloc-stack-opts | %FileCheck %s
|
|
|
|
// This file tests routines in SILCombinerMiscVisitors.cpp
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
|
|
//////////////////
|
|
// Declarations //
|
|
//////////////////
|
|
|
|
class Klass {}
|
|
|
|
struct S {
|
|
var a: Klass
|
|
}
|
|
|
|
sil @nativeobject_guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
|
|
|
|
///////////
|
|
// Tests //
|
|
///////////
|
|
|
|
// We test both the ossa and non-ossa variants.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @fix_lifetime_promotion_ossa : $@convention(thin) (@owned Klass) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] :
|
|
// CHECK: [[STACK:%.*]] = alloc_stack $Klass
|
|
// CHECK: store [[ARG]] to [init] [[STACK]]
|
|
// CHECK: [[BORROW:%.*]] = load_borrow [[STACK]]
|
|
// CHECK: fix_lifetime [[BORROW]]
|
|
// CHECK: end_borrow [[BORROW]]
|
|
// CHECK: destroy_addr [[STACK]]
|
|
// CHECK: dealloc_stack [[STACK]]
|
|
// CHECK: } // end sil function 'fix_lifetime_promotion_ossa'
|
|
sil [ossa] @fix_lifetime_promotion_ossa : $@convention(thin) (@owned Klass) -> () {
|
|
bb0(%0 : @owned $Klass):
|
|
%1 = alloc_stack $Klass
|
|
store %0 to [init] %1 : $*Klass
|
|
fix_lifetime %1 : $*Klass
|
|
destroy_addr %1 : $*Klass
|
|
dealloc_stack %1 : $*Klass
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @fix_lifetime_promotion : $@convention(thin) (@owned Klass) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] :
|
|
// CHECK: [[STACK:%.*]] = alloc_stack $Klass
|
|
// CHECK: store [[ARG]] to [[STACK]]
|
|
// CHECK: [[BORROW:%.*]] = load [[STACK]]
|
|
// CHECK: fix_lifetime [[BORROW]]
|
|
// CHECK: destroy_addr [[STACK]]
|
|
// CHECK: dealloc_stack [[STACK]]
|
|
// CHECK: } // end sil function 'fix_lifetime_promotion'
|
|
sil @fix_lifetime_promotion : $@convention(thin) (@owned Klass) -> () {
|
|
bb0(%0 : $Klass):
|
|
%1 = alloc_stack $Klass
|
|
store %0 to %1 : $*Klass
|
|
fix_lifetime %1 : $*Klass
|
|
destroy_addr %1 : $*Klass
|
|
dealloc_stack %1 : $*Klass
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// We should have a single load [copy] here.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @remove_loadcopy_with_only_destroy_users : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> () {
|
|
// CHECK: load [copy]
|
|
// CHECK-NOT: load [copy]
|
|
// CHECK: } // end sil function 'remove_loadcopy_with_only_destroy_users'
|
|
sil [ossa] @remove_loadcopy_with_only_destroy_users : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%1 = load [copy] %0 : $*Builtin.NativeObject
|
|
destroy_value %1 : $Builtin.NativeObject
|
|
%2 = load [copy] %0 : $*Builtin.NativeObject
|
|
%f = function_ref @nativeobject_guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
|
|
apply %f(%2) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
|
|
destroy_value %2 : $Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// We should have a single load_borrow here.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @remove_loadborrow_with_only_destroy_users : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> () {
|
|
// CHECK: load_borrow
|
|
// CHECK-NOT: load_borrow
|
|
// CHECK: } // end sil function 'remove_loadborrow_with_only_destroy_users'
|
|
sil [ossa] @remove_loadborrow_with_only_destroy_users : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%1 = load_borrow %0 : $*Builtin.NativeObject
|
|
end_borrow %1 : $Builtin.NativeObject
|
|
%2 = load_borrow %0 : $*Builtin.NativeObject
|
|
%f = function_ref @nativeobject_guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
|
|
apply %f(%2) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_updating_borrowed_from :
|
|
// CHECK: borrowed {{.*}} from (%0 : $S)
|
|
// CHECK-LABEL: } // end sil function 'test_updating_borrowed_from'
|
|
sil [ossa] @test_updating_borrowed_from : $@convention(thin) (@guaranteed S) -> () {
|
|
bb0(%0 : @guaranteed $S):
|
|
%1 = destructure_struct %0 : $S
|
|
%2 = copy_value %1 : $Klass
|
|
%3 = begin_borrow %2 : $Klass
|
|
br bb1(%3 : $Klass)
|
|
|
|
bb1(%5 : @reborrow $Klass):
|
|
%6 = borrowed %5 : $Klass from (%2 : $Klass)
|
|
end_borrow %6 : $Klass
|
|
destroy_value %2 : $Klass
|
|
%9 = tuple ()
|
|
return %9 : $()
|
|
}
|
|
|