@@ -90,6 +90,7 @@ public protocol ErrorType {
90
90
var _code: Builtin.Int32 { get }
91
91
}
92
92
93
+ sil [fragile] @use : $@convention(thin) (Builtin.NativeObject) -> ()
93
94
sil [fragile] @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
94
95
95
96
sil [fragile] @owned_return : $@convention(thin) () -> (@owned @box Builtin.Int32)
@@ -99,7 +100,6 @@ sil [fragile] @guaranteed_throwing_use : $@convention(thin) (@guaranteed Builtin
99
100
/////////////////
100
101
// Basic Tests //
101
102
/////////////////
102
-
103
103
// CHECK-LABEL: sil @simple_retain_release_pair : $@convention(thin) (Builtin.NativeObject) -> ()
104
104
// CHECK: bb0
105
105
// CHECK-NEXT: tuple ()
@@ -2073,3 +2073,47 @@ bb2(%4 : $ErrorType):
2073
2073
throw %4 : $ErrorType
2074
2074
}
2075
2075
2076
+ // In this control flow, ARC runs multiple iterations to get rid of and move the retain and releases.
2077
+ // In the first iteration, we will try to move id1/id3 towards each other.
2078
+ // we create new instructions and remove the old ones. However we had a bug to insert these newly created
2079
+ // instructions into the "interesting" instruction list. As a result, the in second iteration,
2080
+ // we end up ignoring the newly created id3. and will be able to move id2 across a potential release (id3).
2081
+ //
2082
+ // CHECK-LABEL: sil @interleaved_retain_release_with_multiple_arc_iteration
2083
+ // CHECK: strong_retain
2084
+ // CHECK: apply
2085
+ // CHECK: apply
2086
+ // CHECK: strong_retain
2087
+ // CHECK: strong_release
2088
+ sil @interleaved_retain_release_with_multiple_arc_iteration : $@convention(thin) (Builtin.NativeObject, @inout Builtin.NativeObject) -> () {
2089
+ bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
2090
+ %6 = function_ref @use : $@convention(thin) (Builtin.NativeObject) -> ()
2091
+ %2 = load %1 : $*Builtin.NativeObject
2092
+
2093
+ strong_retain %2 : $Builtin.NativeObject // id 1
2094
+ apply %6(%2) : $@convention(thin) (Builtin.NativeObject) -> ()
2095
+ apply %6(%2) : $@convention(thin) (Builtin.NativeObject) -> ()
2096
+
2097
+ strong_retain %0 : $Builtin.NativeObject // id 2
2098
+
2099
+ %10 = tuple()
2100
+
2101
+ strong_release %2 : $Builtin.NativeObject // id 3
2102
+
2103
+ strong_retain %0 : $Builtin.NativeObject // id 4
2104
+ apply %6(%0) : $@convention(thin) (Builtin.NativeObject) -> ()
2105
+ apply %6(%0) : $@convention(thin) (Builtin.NativeObject) -> ()
2106
+ strong_release %0 : $Builtin.NativeObject // id 5
2107
+ strong_release %0 : $Builtin.NativeObject // id 6
2108
+ br bb2
2109
+
2110
+ // These are here to make sure we run 2nd iteration in arcopt.
2111
+ bb2:
2112
+ strong_retain %0 : $Builtin.NativeObject
2113
+ strong_retain %0 : $Builtin.NativeObject
2114
+ strong_release %0 : $Builtin.NativeObject
2115
+ strong_release %0 : $Builtin.NativeObject
2116
+ %5 = tuple()
2117
+ return %5 : $()
2118
+ }
2119
+
0 commit comments