@@ -5,6 +5,11 @@ sil_stage canonical
5
5
import Builtin
6
6
import Swift
7
7
8
+ public struct S {
9
+ var o: AnyObject
10
+ }
11
+ sil @dummy : $@convention(thin) () -> ()
12
+
8
13
// CHECK-LABEL: sil [ossa] @dead1 :
9
14
// CHECK: bb0
10
15
// CHECK-NEXT: return %0
@@ -289,3 +294,69 @@ bb0(%0 : @owned $(String, (Int, Int, String))):
289
294
return %1 : $String
290
295
}
291
296
297
+ // Test fix_lifetime of a struct and tuple. It cannot be removed
298
+ // without proving reference uniqueness first.
299
+ // rdar://36038096 ([SR-6608] DeadCodeElimination removes fix_lifetime instructions.)
300
+ //
301
+ // CHECK-LABEL: @testFixLifetimeTuple : $@convention(thin) (@owned S, @owned AnyObject) -> () {
302
+ // CHECK: bb0(%0 : $S, %1 : $AnyObject):
303
+ // CHECK: [[TUPLE:%.*]] = tuple (%0 : $S, %1 : $AnyObject)
304
+ // CHECK: apply
305
+ // CHECK: fix_lifetime [[TUPLE]] : $(S, AnyObject)
306
+ // CHECK: strong_release %1 : $AnyObject
307
+ // CHECK: strong_release %{{.*}} : $AnyObject
308
+ // CHECK-LABEL: } // end sil function 'testFixLifetimeTuple'
309
+ sil @testFixLifetimeTuple : $@convention(thin) (@owned S, @owned AnyObject) -> () {
310
+ bb0(%0 : $S, %1 : $AnyObject):
311
+ %4 = struct_extract %0 : $S, #S.o
312
+ %7 = tuple (%0 : $S, %1 : $AnyObject)
313
+ %8 = function_ref @dummy : $@convention(thin) () -> ()
314
+ %9 = apply %8() : $@convention(thin) () -> ()
315
+ fix_lifetime %7 : $(S, AnyObject)
316
+ strong_release %1 : $AnyObject
317
+ strong_release %4 : $AnyObject
318
+ %15 = tuple ()
319
+ return %15 : $()
320
+ }
321
+
322
+ // Test fix_lifetime of a load_borrow. It cannot be removed without
323
+ // proving reference uniqueness first.
324
+ // rdar://74759728 (The compiler/optimizer seems to be shortening the lifetime too early)
325
+ //
326
+ // Test case derived from $defer #1 <A><A1>() in _ArrayBuffer.withUnsafeBufferPointer<A>(_:)
327
+ //
328
+ // Original source that exposed the issue with -Ounchecked -sanitize=address:
329
+ //
330
+ // public func makeRawData(name: String) -> UnsafeMutableRawPointer {
331
+ // var array: [UInt8] = []
332
+ // array.append(contentsOf: name.utf8)
333
+ // array.append(0)
334
+ //
335
+ // let rawData = array.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) -> UnsafeMutableRawPointer in
336
+ // let rawData = malloc(Int(buffer.count))!
337
+ // rawData.copyMemory(from: buffer.baseAddress!, byteCount: buffer.count)
338
+ // return rawData
339
+ // }
340
+ // return rawData
341
+ // }
342
+ //
343
+ // CHECK-LABEL: sil [ossa] @testDCEFixLifetime : $@convention(thin) (@guaranteed S) -> () {
344
+ // %0 "self" // users: %3, %1
345
+ // CHECK: bb0(%0 : @guaranteed $S):
346
+ // CHECK: [[LD:%.*]] = load_borrow
347
+ // CHECK: fix_lifetime [[LD]] : $S
348
+ // CHECK: end_borrow [[LD]] : $S
349
+ // CHECK-LABEL: } // end sil function 'testDCEFixLifetime'
350
+ sil [ossa] @testDCEFixLifetime : $@convention(thin) (@guaranteed S) -> () {
351
+ // %0 "self"
352
+ bb0(%0 : @guaranteed $S):
353
+ debug_value %0 : $S, let, name "self", argno 1
354
+ %2 = alloc_stack $S
355
+ %3 = store_borrow %0 to %2 : $*S
356
+ %4 = load_borrow %2 : $*S
357
+ fix_lifetime %4 : $S
358
+ end_borrow %4 : $S
359
+ dealloc_stack %2 : $*S
360
+ %8 = tuple ()
361
+ return %8 : $()
362
+ }
0 commit comments