| // RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -enable-loop-arc=0 -arc-sequence-opts %s | %FileCheck %s |
| // RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -enable-loop-arc=1 -arc-sequence-opts %s | %FileCheck %s |
| |
| import Builtin |
| import Swift |
| import SwiftShims |
| |
| class MD5 { |
| init() |
| final var w: [UInt32] |
| } |
| |
| // CHECK-LABEL:sil @test_unique_check_arc : $@convention(method) (@owned MD5) -> () |
| sil @test_unique_check_arc : $@convention(method) (@owned MD5) -> () { |
| // CHECK: bb0 |
| bb0(%0 : $MD5): |
| %1 = integer_literal $Builtin.Int32, 0 |
| %2 = integer_literal $Builtin.Int32, 16 |
| %3 = struct $Int32 (%1 : $Builtin.Int32) |
| br bb1(%1 : $Builtin.Int32) |
| |
| // CHECK: bb1 |
| bb1(%5 : $Builtin.Int32): |
| %7 = builtin "cmp_eq_Int32"(%5 : $Builtin.Int32, %2 : $Builtin.Int32) : $Builtin.Int1 |
| cond_br %7, bb3, bb2 |
| |
| // CHECK: bb2 |
| bb2: |
| %9 = integer_literal $Builtin.Int32, 1 |
| %11 = integer_literal $Builtin.Int1, -1 |
| %12 = builtin "sadd_with_overflow_Int32"(%5 : $Builtin.Int32, %9 : $Builtin.Int32, %11 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) |
| %13 = tuple_extract %12 : $(Builtin.Int32, Builtin.Int1), 0 |
| // CHECK-NOT: strong_retain |
| // CHECK-NOT: strong_release |
| strong_retain %0 : $MD5 |
| %314 = ref_element_addr %0 : $MD5, #MD5.w |
| %318 = load %314 : $*Array<UInt32> |
| %319 = alloc_stack $Array<UInt32> |
| store %318 to %319 : $*Array<UInt32> |
| dealloc_stack %319 : $*Array<UInt32> |
| %179 = is_unique %314 : $*Array<UInt32> |
| cond_br %179, bb4, bb5 |
| |
| // CHECK: bb3 |
| // CHECK-NEXT: strong_release |
| // CHECK-NEXT: tuple |
| // CHECK-NEXT: return |
| bb3: |
| strong_release %0 : $MD5 |
| %273 = tuple () |
| return %273 : $() |
| |
| bb4: |
| br bb5 |
| |
| // CHECK-NOT: strong_release |
| bb5: |
| strong_release %0 : $MD5 |
| br bb1(%13 : $Builtin.Int32) |
| |
| } |
| |
| class C {} |
| |
| // Check that retains are not moved across an is_unique that may alias. |
| sil @test_uniq_alias : $@convention(method) (@owned C) -> Builtin.Int1 { |
| // CHECK: bb0 |
| bb0(%0 : $C): |
| %1 = alloc_stack $C, var, name "x" |
| store %0 to %1 : $*C |
| // CHECK: strong_retain %0 : $C |
| strong_retain %0 : $C |
| // CHECK: is_unique %1 : $*C |
| %4 = is_unique %1 : $*C |
| // CHECK-NOT: strong_retain |
| fix_lifetime %0 : $C |
| // CHECK: strong_release %0 : $C |
| strong_release %0 : $C |
| // CHECK: [[LOADED:%[0-9]+]] = load %1 : $*C |
| %8 = load %1 : $*C |
| // CHECK: strong_release [[LOADED]] : $C |
| strong_release %8 : $C |
| dealloc_stack %1 : $*C |
| return %4 : $Builtin.Int1 |
| } |
| |
| // The following test could optimize to: |
| // %2 = load %1 : $*C // user: %4 |
| // %3 = is_unique %0 : $*C // user: %5 |
| // fix_lifetime %2 : $C // id: %4 |
| // |
| // But ARC is currently conservative. When this is fixed, |
| // change _CHECK: strong... into _CHECK_NOT: strong... |
| sil @test_uniq_noalias : $@convention(thin) (@inout C, @inout C) -> Builtin.Int1 { |
| // CHECK: bb0 |
| bb0(%0 : $*C, %1 : $*C): |
| %2 = load %1 : $*C |
| // CHECK: strong_retain %2 : $C |
| strong_retain %2 : $C |
| // CHECK: is_unique %0 : $*C |
| %4 = is_unique %0 : $*C |
| fix_lifetime %2 : $C |
| // CHECK: strong_release %2 : $C |
| strong_release %2 : $C |
| return %4 : $Builtin.Int1 |
| } |