@@ -875,6 +875,7 @@ bb0(%instance : @owned $C):
875
875
// CHECK-NOT: destroy_value
876
876
// CHECK-LABEL: } // end sil function 'dont_extend_beyond_nonoverlapping_endaccess_after_destroyvalue_in_consuming_block'
877
877
sil [ossa] @dont_extend_beyond_nonoverlapping_endaccess_after_destroyvalue_in_consuming_block : $@convention(thin) () -> () {
878
+ bb0:
878
879
%instance = apply undef() : $@convention(thin) () -> @owned C
879
880
%addr = alloc_stack [lexical] $C, var
880
881
%access = begin_access [static] [modify] %addr : $*C
@@ -885,3 +886,52 @@ sil [ossa] @dont_extend_beyond_nonoverlapping_endaccess_after_destroyvalue_in_co
885
886
%retval = tuple()
886
887
return %retval : $()
887
888
}
889
+
890
+ sil @closureGetter : $@convention(thin) () -> @owned Optional<@Sendable @callee_guaranteed () -> ()>
891
+
892
+ // This pattern is produced by SILGen doUncheckedConversion.
893
+ // rdar://100527903 (Overrelease of optional closure when using shorthand syntax)
894
+ //
895
+ // Copy propagation cannot handle a PointerEscape.
896
+ //
897
+ // CHECK-LABEL: sil hidden [ossa] @testBitwiseClosureEscape : $@convention(thin) () -> () {
898
+ // CHECK: [[V:%.*]] = apply %0() : $@convention(thin) () -> @owned Optional<@Sendable @callee_guaranteed () -> ()>
899
+ // CHECK: [[CP1:%.*]] = copy_value [[V]] : $Optional<@Sendable @callee_guaranteed () -> ()>
900
+ // CHECK: destroy_value [[V]] : $Optional<@Sendable @callee_guaranteed () -> ()>
901
+ // CHECK: [[CAST:%.*]] = unchecked_bitwise_cast [[CP1]] : $Optional<@Sendable @callee_guaranteed () -> ()> to $Optional<@callee_guaranteed () -> ()>
902
+ // CHECK-NEXT: [[CASTCP:%.*]] = copy_value [[CAST]] : $Optional<@callee_guaranteed () -> ()>
903
+ // CHECK: store [[CASTCP]] to [init]
904
+ // CHECK: destroy_value [[CP1]] : $Optional<@Sendable @callee_guaranteed () -> ()>
905
+ // CHECK-LABEL: } // end sil function 'testBitwiseClosureEscape'
906
+ sil hidden [ossa] @testBitwiseClosureEscape : $@convention(thin) () -> () {
907
+ bb0:
908
+ %2 = function_ref @closureGetter : $@convention(thin) () -> @owned Optional<@Sendable @callee_guaranteed () -> ()>
909
+ %3 = apply %2() : $@convention(thin) () -> @owned Optional<@Sendable @callee_guaranteed () -> ()>
910
+ %13 = copy_value %3 : $Optional<@Sendable @callee_guaranteed () -> ()>
911
+ %14 = alloc_stack $Optional<@callee_guaranteed () -> ()>
912
+ destroy_value %3 : $Optional<@Sendable @callee_guaranteed () -> ()>
913
+ %17 = unchecked_bitwise_cast %13 : $Optional<@Sendable @callee_guaranteed () -> ()> to $Optional<@callee_guaranteed () -> ()>
914
+ %18 = copy_value %17 : $Optional<@callee_guaranteed () -> ()>
915
+ store %18 to [init] %14 : $*Optional<@callee_guaranteed () -> ()>
916
+ destroy_addr %14 : $*Optional<@callee_guaranteed () -> ()>
917
+ destroy_value %13 : $Optional<@Sendable @callee_guaranteed () -> ()>
918
+ dealloc_stack %14 : $*Optional<@callee_guaranteed () -> ()>
919
+ %99 = tuple ()
920
+ return %99 : $()
921
+ }
922
+
923
+ // Lexical destroy hoisting cannot handle a PointerEscape.
924
+ //
925
+ // CHECK-LABEL: sil [ossa] @testNoLexicalHoistEscape : $@convention(thin) (@owned Optional<@Sendable @callee_guaranteed () -> ()>) -> @owned Optional<@callee_guaranteed () -> ()> {
926
+ // CHECK: bb0(%0 : @owned $Optional<@Sendable @callee_guaranteed () -> ()>):
927
+ // CHECK: [[CAST:%.*]] = unchecked_bitwise_cast %0 : $Optional<@Sendable @callee_guaranteed () -> ()> to $Optional<@callee_guaranteed () -> ()>
928
+ // CHECK: [[COPY:%.*]] = copy_value [[CAST]] : $Optional<@callee_guaranteed () -> ()>
929
+ // CHECK: destroy_value %0 : $Optional<@Sendable @callee_guaranteed () -> ()>
930
+ // CHECK-LABEL: } // end sil function 'testNoLexicalHoistEscape'
931
+ sil [ossa] @testNoLexicalHoistEscape : $@convention(thin) (@owned Optional<@Sendable @callee_guaranteed () -> ()>) -> @owned Optional<@callee_guaranteed () -> ()> {
932
+ bb0(%0 : @owned $Optional<@Sendable @callee_guaranteed () -> ()>):
933
+ %cast = unchecked_bitwise_cast %0 : $Optional<@Sendable @callee_guaranteed () -> ()> to $Optional<@callee_guaranteed () -> ()>
934
+ %copy = copy_value %cast : $Optional<@callee_guaranteed () -> ()>
935
+ destroy_value %0 : $Optional<@Sendable @callee_guaranteed () -> ()>
936
+ return %copy : $Optional<@callee_guaranteed () -> ()>
937
+ }
0 commit comments