@@ -116,6 +116,13 @@ struct NativeObjectWrapper {
116
116
117
117
sil @owned_user_object_pair : $@convention(thin) (@owned NativeObjectPair) -> ()
118
118
119
+ class X {}
120
+ struct S {}
121
+
122
+ sil @getX : $@convention(thin) () -> @owned X
123
+ sil @getS : $@convention(thin) (@owned X) -> @out S
124
+ sil @loadWeakX_from : $@convention(thin) (@in_guaranteed S) -> @owned FakeOptional<X>
125
+
119
126
///////////
120
127
// Tests //
121
128
///////////
@@ -923,3 +930,51 @@ bb0:
923
930
destroy_value %0 : ${ var Bool }
924
931
return %11 : $Bool
925
932
}
933
+
934
+ // Don't do this optimization:
935
+ // Eliminate copy of lexical value which ends after lifetime of copy IF there
936
+ // may be deinit barriers between the final consume and the copy.
937
+ //
938
+ // CHECK-LABEL: sil [ossa] @testDestroyedLexicalValue : {{.*}} {
939
+ // CHECK: [[GET:%[^,]+]] = function_ref @getX
940
+ // CHECK: [[X:%[^,]+]] = apply [[GET]]()
941
+ // CHECK: [[MX:%[^,]+]] = move_value [lexical] [[X]]
942
+ // CHECK: destroy_value [[MX]] : $X
943
+ // CHECK-LABEL: } // end sil function 'testDestroyedLexicalValue'
944
+ sil [ossa] @testDestroyedLexicalValue : $@convention(thin) () -> @owned FakeOptional<X> {
945
+ bb0:
946
+ %getX = function_ref @getX : $@convention(thin) () -> @owned X
947
+ %x = apply %getX() : $@convention(thin) () -> @owned X
948
+ %mx = move_value [lexical] %x : $X
949
+ %a = alloc_stack [lexical] $S, let, name "s"
950
+ %c = copy_value %mx : $X
951
+ %getS = function_ref @getS : $@convention(thin) (@owned X) -> @out S
952
+ %s = apply %getS(%a, %c) : $@convention(thin) (@owned X) -> @out S
953
+ %loadWeakX_from = function_ref @loadWeakX_from : $@convention(thin) (@in_guaranteed S) -> @owned FakeOptional<X>
954
+ %o = apply %loadWeakX_from(%a) : $@convention(thin) (@in_guaranteed S) -> @owned FakeOptional<X>
955
+ // ^^^^^ Deinit barrier
956
+ destroy_addr %a : $*S
957
+ dealloc_stack %a : $*S
958
+ destroy_value %mx : $X
959
+ return %o : $FakeOptional<X>
960
+ }
961
+
962
+ // CHECK-LABEL: sil [ossa] @testDestroyedLexicalValueNoBarriers : {{.*}} {
963
+ // CHECK-NOT: destroy_value
964
+ // CHECK-LABEL: } // end sil function 'testDestroyedLexicalValueNoBarriers'
965
+ sil [ossa] @testDestroyedLexicalValueNoBarriers : $@convention(thin) () -> () {
966
+ bb0:
967
+ %getX = function_ref @getX : $@convention(thin) () -> @owned X
968
+ %x = apply %getX() : $@convention(thin) () -> @owned X
969
+ %mx = move_value [lexical] %x : $X
970
+ %a = alloc_stack [lexical] $S, let, name "s"
971
+ %c = copy_value %mx : $X
972
+ %getS = function_ref @getS : $@convention(thin) (@owned X) -> @out S
973
+ %s = apply %getS(%a, %c) : $@convention(thin) (@owned X) -> @out S
974
+ destroy_addr %a : $*S
975
+ dealloc_stack %a : $*S
976
+ destroy_value %mx : $X
977
+ %r = tuple ()
978
+ return %r : $()
979
+ }
980
+
0 commit comments