Files
swift-mirror/test/SILOptimizer/moveonly_addresschecker_debuginfo.sil
Kavon Farvardin 0420310623 NCGenerics: it's no longer "experimental"
resolves rdar://127701059
2024-05-08 10:49:12 -07:00

220 lines
8.5 KiB
Plaintext

// RUN: %target-sil-opt -module-name moveonly_addresschecker -emit-verbose-sil -sil-move-only-checker -enable-sil-verify-all %s | %FileCheck %s
sil_stage raw
public class CopyableKlass {}
@_moveOnly
public struct NonTrivialStruct {
var k: CopyableKlass
}
sil @get_nontrivial_struct : $@convention(thin) () -> @owned NonTrivialStruct
sil @use_nontrivial_struct : $@convention(thin) (@guaranteed NonTrivialStruct) -> ()
sil @consume_nontrivial_struct : $@convention(thin) (@owned NonTrivialStruct) -> ()
sil @consume_nontrivial_struct_addr : $@convention(thin) (@in NonTrivialStruct) -> ()
// CHECK-LABEL: sil [ossa] @non_lifetime_ending_use_test_inst : $@convention(thin) () -> () {
// CHECK: [[STACK:%.*]] = alloc_stack $NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC:.*]]
// CHECK: store {{%.*}} to [init] [[STACK]]
// CHECK: [[BORROW:%.*]] = load_borrow [[STACK]]
// CHECK: apply {{%.*}}([[BORROW]])
// CHECK-NEXT: end_borrow [[BORROW]]
// CHECK-NEXT: debug_value undef : $*NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC]]
// CHECK: } // end sil function 'non_lifetime_ending_use_test_inst'
sil [ossa] @non_lifetime_ending_use_test_inst : $@convention(thin) () -> () {
%f = function_ref @get_nontrivial_struct : $@convention(thin) () -> @owned NonTrivialStruct
%0 = apply %f() : $@convention(thin) () -> @owned NonTrivialStruct
%1 = alloc_stack $NonTrivialStruct, let, name "v"
%2 = mark_unresolved_non_copyable_value [consumable_and_assignable] %1 : $*NonTrivialStruct
store %0 to [init] %2 : $*NonTrivialStruct
br bb1
bb1:
%3 = load [copy] %2 : $*NonTrivialStruct
%f2 = function_ref @use_nontrivial_struct : $@convention(thin) (@guaranteed NonTrivialStruct) -> ()
apply %f2(%3) : $@convention(thin) (@guaranteed NonTrivialStruct) -> ()
destroy_value %3 : $NonTrivialStruct
destroy_addr %2 : $*NonTrivialStruct
dealloc_stack %1 : $*NonTrivialStruct
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: sil [ossa] @non_lifetime_ending_use_test_boundary_edge : $@convention(thin) () -> () {
// CHECK: [[STACK:%.*]] = alloc_stack $NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC:.*]]
// CHECK: store {{%.*}} to [init] [[STACK]]
// CHECK: cond_br undef, bb1, bb2
// CHECK: bb1:
// CHECK: [[BORROW:%.*]] = load_borrow [[STACK]]
// CHECK: apply {{%.*}}([[BORROW]])
// CHECK-NEXT: end_borrow [[BORROW]]
// CHECK: br bb3
//
// CHECK: bb2:
// CHECK-NEXT: br bb3
// CHECK: bb3:
// CHECK-NEXT: debug_value undef : $*NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC]]
// CHECK-NEXT: destroy_addr [[STACK]]
// CHECK: } // end sil function 'non_lifetime_ending_use_test_boundary_edge'
sil [ossa] @non_lifetime_ending_use_test_boundary_edge : $@convention(thin) () -> () {
%f = function_ref @get_nontrivial_struct : $@convention(thin) () -> @owned NonTrivialStruct
%0 = apply %f() : $@convention(thin) () -> @owned NonTrivialStruct
%1 = alloc_stack $NonTrivialStruct, let, name "v"
%2 = mark_unresolved_non_copyable_value [consumable_and_assignable] %1 : $*NonTrivialStruct
store %0 to [init] %2 : $*NonTrivialStruct
cond_br undef, bb1, bb2
bb1:
%3 = load [copy] %2 : $*NonTrivialStruct
%f2 = function_ref @use_nontrivial_struct : $@convention(thin) (@guaranteed NonTrivialStruct) -> ()
apply %f2(%3) : $@convention(thin) (@guaranteed NonTrivialStruct) -> ()
destroy_value %3 : $NonTrivialStruct
br bb3
bb2:
br bb3
bb3:
destroy_addr %2 : $*NonTrivialStruct
dealloc_stack %1 : $*NonTrivialStruct
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: sil [ossa] @lifetime_ending_use : $@convention(thin) () -> () {
// CHECK: [[STACK:%.*]] = alloc_stack $NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC:.*]]
// CHECK: store {{%.*}} to [init] [[STACK]]
// CHECK: cond_br undef, bb1, bb2
// CHECK: bb1:
//
// TODO: We should be smarter here and redefine the debug_value to be on the
// take value and then when that value is destroyed, insert the actual
// debug_value undef.
//
// CHECK: [[TAKE:%.*]] = load [take] [[STACK]]
// CHECK-NEXT: debug_value undef : $*NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC]]
// CHECK-NEXT: // function_ref
// CHECK-NEXT: function_ref
// CHECK-NEXT: apply {{%.*}}([[TAKE]])
// CHECK: br bb3
//
// CHECK: bb2:
// CHECK-NEXT: destroy_addr [[STACK]]
// CHECK-NEXT: debug_value undef : $*NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC]]
// CHECK: } // end sil function 'lifetime_ending_use'
sil [ossa] @lifetime_ending_use : $@convention(thin) () -> () {
%f = function_ref @get_nontrivial_struct : $@convention(thin) () -> @owned NonTrivialStruct
%0 = apply %f() : $@convention(thin) () -> @owned NonTrivialStruct
%1 = alloc_stack $NonTrivialStruct, let, name "v"
%2 = mark_unresolved_non_copyable_value [consumable_and_assignable] %1 : $*NonTrivialStruct
store %0 to [init] %2 : $*NonTrivialStruct
cond_br undef, bb1, bb2
bb1:
%3 = load [copy] %2 : $*NonTrivialStruct
%f2 = function_ref @consume_nontrivial_struct : $@convention(thin) (@owned NonTrivialStruct) -> ()
apply %f2(%3) : $@convention(thin) (@owned NonTrivialStruct) -> ()
br bb3
bb2:
br bb3
bb3:
destroy_addr %2 : $*NonTrivialStruct
dealloc_stack %1 : $*NonTrivialStruct
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: sil [ossa] @lifetime_ending_use_addr : $@convention(thin) () -> () {
// CHECK: [[STACK:%.*]] = alloc_stack $NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC:.*]]
// CHECK: store {{%.*}} to [init] [[STACK]]
// CHECK: cond_br undef, bb1, bb2
// CHECK: bb1:
// CHECK: apply {{%.*}}([[STACK]])
// CHECK-NEXT: debug_value undef : $*NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC]]
// CHECK: br bb3
//
// CHECK: bb2:
// CHECK-NEXT: destroy_addr [[STACK]]
// CHECK-NEXT: debug_value undef : $*NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC]]
// CHECK: } // end sil function 'lifetime_ending_use_addr'
sil [ossa] @lifetime_ending_use_addr : $@convention(thin) () -> () {
%f = function_ref @get_nontrivial_struct : $@convention(thin) () -> @owned NonTrivialStruct
%0 = apply %f() : $@convention(thin) () -> @owned NonTrivialStruct
%1 = alloc_stack $NonTrivialStruct, let, name "v"
%2 = mark_unresolved_non_copyable_value [consumable_and_assignable] %1 : $*NonTrivialStruct
store %0 to [init] %2 : $*NonTrivialStruct
cond_br undef, bb1, bb2
bb1:
%f2 = function_ref @consume_nontrivial_struct_addr : $@convention(thin) (@in NonTrivialStruct) -> ()
apply %f2(%2) : $@convention(thin) (@in NonTrivialStruct) -> ()
br bb3
bb2:
br bb3
bb3:
destroy_addr %2 : $*NonTrivialStruct
dealloc_stack %1 : $*NonTrivialStruct
%9999 = tuple ()
return %9999 : $()
}
// CHECK-LABEL: sil [ossa] @dead_def_test_inst : $@convention(thin) () -> () {
// CHECK: [[STACK:%.*]] = alloc_stack $NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC:.*]]
// CHECK: store {{%.*}} to [init] [[STACK]]
// CHECK: cond_br undef, bb1, bb3
//
// CHECK: bb1:
// CHECK: apply {{%.*}}([[STACK]])
// CHECK-NEXT: debug_value undef : $*NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC]]
// CHECK-NEXT: br bb2
//
// CHECK: bb2:
// CHECK: [[NEW_VAL:%.*]] = apply {{%.*}}() :
// CHECK-NEXT: store [[NEW_VAL]] to [init] [[STACK]]
// CHECK-NEXT: destroy_addr [[STACK]]
// CHECK-NEXT: debug_value undef : $*NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC]]
// CHECK-NEXT: br bb4
//
// CHECK: bb3:
// CHECK-NEXT: destroy_addr [[STACK]]
// CHECK-NEXT: debug_value undef : $*NonTrivialStruct, let, name "v" // {{.*}}; line:[[DEBUG_LOC]]
// CHECK: br bb4
// CHECK: } // end sil function 'dead_def_test_inst'
sil [ossa] @dead_def_test_inst : $@convention(thin) () -> () {
%f = function_ref @get_nontrivial_struct : $@convention(thin) () -> @owned NonTrivialStruct
%0 = apply %f() : $@convention(thin) () -> @owned NonTrivialStruct
%1 = alloc_stack $NonTrivialStruct, let, name "v"
%2 = mark_unresolved_non_copyable_value [consumable_and_assignable] %1 : $*NonTrivialStruct
store %0 to [init] %2 : $*NonTrivialStruct
cond_br undef, bb1, bb2
bb1:
// TODO: Fix bug where we do not propagate this use to bb0 and thus think that
// store %0 is a dead def.
%f2 = function_ref @consume_nontrivial_struct_addr : $@convention(thin) (@in NonTrivialStruct) -> ()
apply %f2(%2) : $@convention(thin) (@in NonTrivialStruct) -> ()
br bb1a
bb1a:
%0a = apply %f() : $@convention(thin) () -> @owned NonTrivialStruct
store %0a to [init] %2 : $*NonTrivialStruct
br bb3
bb2:
br bb3
bb3:
destroy_addr %2 : $*NonTrivialStruct
dealloc_stack %1 : $*NonTrivialStruct
%9999 = tuple ()
return %9999 : $()
}