Home | History | Annotate | Download | only in CodeGenObjC
      1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
      2 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-UNOPT %s
      3 
      4 // This shouldn't crash.
      5 void test0(id (^maker)(void)) {
      6   maker();
      7 }
      8 
      9 int (^test1(int x))(void) {
     10   // CHECK-LABEL:    define i32 ()* @test1(
     11   // CHECK:      [[X:%.*]] = alloca i32,
     12   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
     13   // CHECK-NEXT: store i32 {{%.*}}, i32* [[X]]
     14   // CHECK:      [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to i32 ()*
     15   // CHECK-NEXT: [[T1:%.*]] = bitcast i32 ()* [[T0]] to i8*
     16   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]]) [[NUW:#[0-9]+]]
     17   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i32 ()*
     18   // CHECK-NEXT: [[T4:%.*]] = bitcast i32 ()* [[T3]] to i8*
     19   // CHECK-NEXT: [[T5:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T4]]) [[NUW]]
     20   // CHECK-NEXT: [[T6:%.*]] = bitcast i8* [[T5]] to i32 ()*
     21   // CHECK-NEXT: ret i32 ()* [[T6]]
     22   return ^{ return x; };
     23 }
     24 
     25 void test2(id x) {
     26 // CHECK-LABEL:    define void @test2(
     27 // CHECK:      [[X:%.*]] = alloca i8*,
     28 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
     29 // CHECK-NEXT: [[PARM:%.*]] = call i8* @objc_retain(i8* {{%.*}})
     30 // CHECK-NEXT: store i8* [[PARM]], i8** [[X]]
     31 // CHECK-NEXT: [[SLOTREL:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
     32 // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
     33 // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]],
     34 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
     35 // CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]],
     36 // CHECK-NEXT: bitcast
     37 // CHECK-NEXT: call void @test2_helper(
     38 // CHECK-NEXT: [[T0:%.*]] = load i8** [[SLOTREL]]
     39 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
     40 // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]]
     41 // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release
     42 // CHECK-NEXT: ret void
     43   extern void test2_helper(id (^)(void));
     44   test2_helper(^{ return x; });
     45 
     46 // CHECK-LABEL:    define internal void @__copy_helper_block_
     47 // CHECK:      [[T0:%.*]] = load i8**
     48 // CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
     49 // CHECK-NEXT: [[T0:%.*]] = load i8**
     50 // CHECK-NEXT: [[DST:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
     51 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[SRC]], i32 0, i32 5
     52 // CHECK-NEXT: [[T1:%.*]] = load i8** [[T0]]
     53 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) [[NUW]]
     54 // CHECK-NEXT: ret void
     55 
     56 // CHECK-LABEL:    define internal void @__destroy_helper_block_
     57 // CHECK:      [[T0:%.*]] = load i8**
     58 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
     59 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[T1]], i32 0, i32 5
     60 // CHECK-NEXT: [[T3:%.*]] = load i8** [[T2]]
     61 // CHECK-NEXT: call void @objc_release(i8* [[T3]])
     62 // CHECK-NEXT: ret void
     63 }
     64 
     65 void test3(void (^sink)(id*)) {
     66   __strong id strong;
     67   sink(&strong);
     68 
     69   // CHECK-LABEL:    define void @test3(
     70   // CHECK:      [[SINK:%.*]] = alloca void (i8**)*
     71   // CHECK-NEXT: [[STRONG:%.*]] = alloca i8*
     72   // CHECK-NEXT: [[TEMP:%.*]] = alloca i8*
     73   // CHECK-NEXT: bitcast void (i8**)* {{%.*}} to i8*
     74   // CHECK-NEXT: call i8* @objc_retain(
     75   // CHECK-NEXT: bitcast i8*
     76   // CHECK-NEXT: store void (i8**)* {{%.*}}, void (i8**)** [[SINK]]
     77   // CHECK-NEXT: store i8* null, i8** [[STRONG]]
     78 
     79   // CHECK-NEXT: load void (i8**)** [[SINK]]
     80   // CHECK-NEXT: bitcast
     81   // CHECK-NEXT: getelementptr
     82   // CHECK-NEXT: [[BLOCK:%.*]] = bitcast
     83   // CHECK-NEXT: [[V:%.*]] = load i8** [[STRONG]]
     84   // CHECK-NEXT: store i8* [[V]], i8** [[TEMP]]
     85   // CHECK-NEXT: [[F0:%.*]] = load i8**
     86   // CHECK-NEXT: [[F1:%.*]] = bitcast i8* [[F0]] to void (i8*, i8**)*
     87   // CHECK-NEXT: call void [[F1]](i8* [[BLOCK]], i8** [[TEMP]])
     88   // CHECK-NEXT: [[T0:%.*]] = load i8** [[TEMP]]
     89   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
     90   // CHECK-NEXT: call void (...)* @clang.arc.use(i8* [[V]]) [[NUW]]
     91   // CHECK-NEXT: [[T2:%.*]] = load i8** [[STRONG]]
     92   // CHECK-NEXT: store i8* [[T1]], i8** [[STRONG]]
     93   // CHECK-NEXT: call void @objc_release(i8* [[T2]])
     94 
     95   // CHECK-NEXT: [[T0:%.*]] = load i8** [[STRONG]]
     96   // CHECK-NEXT: call void @objc_release(i8* [[T0]])
     97 
     98   // CHECK-NEXT: load void (i8**)** [[SINK]]
     99   // CHECK-NEXT: bitcast
    100   // CHECK-NEXT: call void @objc_release
    101   // CHECK-NEXT: ret void
    102 
    103 }
    104 
    105 void test4(void) {
    106   id test4_source(void);
    107   void test4_helper(void (^)(void));
    108   __block id var = test4_source();
    109   test4_helper(^{ var = 0; });
    110 
    111   // CHECK-LABEL:    define void @test4()
    112   // CHECK:      [[VAR:%.*]] = alloca [[BYREF_T:%.*]],
    113   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
    114   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 2
    115   // 0x02000000 - has copy/dispose helpers strong
    116   // CHECK-NEXT: store i32 838860800, i32* [[T0]]
    117   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 6
    118   // CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source()
    119   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
    120   // CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]]
    121   // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 6
    122   // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
    123   // CHECK:      store i32 -1040187392,
    124   // CHECK:      [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
    125   // CHECK-NEXT: store i8* [[T0]], i8**
    126   // CHECK:      call void @test4_helper(
    127   // CHECK:      [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
    128   // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
    129   // CHECK-NEXT: [[T0:%.*]] = load i8** [[SLOT]]
    130   // CHECK-NEXT: call void @objc_release(i8* [[T0]])
    131   // CHECK: ret void
    132 
    133   // CHECK-LABEL:    define internal void @__Block_byref_object_copy_
    134   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
    135   // CHECK-NEXT: load i8**
    136   // CHECK-NEXT: bitcast i8* {{%.*}} to [[BYREF_T]]*
    137   // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
    138   // CHECK-NEXT: [[T2:%.*]] = load i8** [[T1]]
    139   // CHECK-NEXT: store i8* [[T2]], i8** [[T0]]
    140   // CHECK-NEXT: store i8* null, i8** [[T1]]
    141 
    142   // CHECK-LABEL:    define internal void @__Block_byref_object_dispose_
    143   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
    144   // CHECK-NEXT: [[T1:%.*]] = load i8** [[T0]]
    145   // CHECK-NEXT: call void @objc_release(i8* [[T1]])
    146 
    147   // CHECK-LABEL:    define internal void @__test4_block_invoke
    148   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds {{.*}}, i32 0, i32 6
    149   // CHECK-NEXT: [[T0:%.*]] = load i8** [[SLOT]], align 8
    150   // CHECK-NEXT: store i8* null, i8** [[SLOT]],
    151   // CHECK-NEXT: call void @objc_release(i8* [[T0]])
    152   // CHECK-NEXT: ret void
    153 
    154   // CHECK-LABEL:    define internal void @__copy_helper_block_
    155   // CHECK:      call void @_Block_object_assign(i8* {{%.*}}, i8* {{%.*}}, i32 8)
    156 
    157   // CHECK-LABEL:    define internal void @__destroy_helper_block_
    158   // CHECK:      call void @_Block_object_dispose(i8* {{%.*}}, i32 8)
    159 }
    160 
    161 void test5(void) {
    162   extern id test5_source(void);
    163   void test5_helper(void (^)(void));
    164   __unsafe_unretained id var = test5_source();
    165   test5_helper(^{ (void) var; });
    166 
    167   // CHECK-LABEL:    define void @test5()
    168   // CHECK:      [[VAR:%.*]] = alloca i8*
    169   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
    170   // CHECK: [[T0:%.*]] = call i8* @test5_source()
    171   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
    172   // CHECK-NEXT: store i8* [[T1]], i8** [[VAR]],
    173   // CHECK-NEXT: call void @objc_release(i8* [[T1]])
    174   // 0x40800000 - has signature but no copy/dispose, as well as BLOCK_HAS_EXTENDED_LAYOUT
    175   // CHECK:      store i32 -1073741824, i32*
    176   // CHECK:      [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
    177   // CHECK-NEXT: [[T0:%.*]] = load i8** [[VAR]]
    178   // CHECK-NEXT: store i8* [[T0]], i8** [[CAPTURE]]
    179   // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to
    180   // CHECK: call void @test5_helper
    181   // CHECK-NEXT: ret void
    182 }
    183 
    184 void test6(void) {
    185   id test6_source(void);
    186   void test6_helper(void (^)(void));
    187   __block __weak id var = test6_source();
    188   test6_helper(^{ var = 0; });
    189 
    190   // CHECK-LABEL:    define void @test6()
    191   // CHECK:      [[VAR:%.*]] = alloca [[BYREF_T:%.*]],
    192   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
    193   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 2
    194   // 0x02000000 - has copy/dispose helpers weak
    195   // CHECK-NEXT: store i32 1107296256, i32* [[T0]]
    196   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 6
    197   // CHECK-NEXT: [[T0:%.*]] = call i8* @test6_source()
    198   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
    199   // CHECK-NEXT: call i8* @objc_initWeak(i8** [[SLOT]], i8* [[T1]])
    200   // CHECK-NEXT: call void @objc_release(i8* [[T1]])
    201   // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]]* [[VAR]], i32 0, i32 6
    202   // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
    203   // CHECK:      store i32 -1040187392,
    204   // CHECK:      [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
    205   // CHECK-NEXT: store i8* [[T0]], i8**
    206   // CHECK:      call void @test6_helper(
    207   // CHECK:      [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
    208   // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
    209   // CHECK-NEXT: call void @objc_destroyWeak(i8** [[SLOT]])
    210   // CHECK: ret void
    211 
    212   // CHECK-LABEL:    define internal void @__Block_byref_object_copy_
    213   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
    214   // CHECK-NEXT: load i8**
    215   // CHECK-NEXT: bitcast i8* {{%.*}} to [[BYREF_T]]*
    216   // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
    217   // CHECK-NEXT: call void @objc_moveWeak(i8** [[T0]], i8** [[T1]])
    218 
    219   // CHECK-LABEL:    define internal void @__Block_byref_object_dispose_
    220   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
    221   // CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]])
    222 
    223   // CHECK-LABEL:    define internal void @__test6_block_invoke
    224   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds {{.*}}, i32 0, i32 6
    225   // CHECK-NEXT: call i8* @objc_storeWeak(i8** [[SLOT]], i8* null)
    226   // CHECK-NEXT: ret void
    227 
    228   // CHECK-LABEL:    define internal void @__copy_helper_block_
    229   // 0x8 - FIELD_IS_BYREF (no FIELD_IS_WEAK because clang in control)
    230   // CHECK:      call void @_Block_object_assign(i8* {{%.*}}, i8* {{%.*}}, i32 8)
    231 
    232   // CHECK-LABEL:    define internal void @__destroy_helper_block_
    233   // 0x8 - FIELD_IS_BYREF (no FIELD_IS_WEAK because clang in control)
    234   // CHECK:      call void @_Block_object_dispose(i8* {{%.*}}, i32 8)
    235 }
    236 
    237 void test7(void) {
    238   id test7_source(void);
    239   void test7_helper(void (^)(void));
    240   void test7_consume(id);
    241   __weak id var = test7_source();
    242   test7_helper(^{ test7_consume(var); });
    243 
    244   // CHECK-LABEL:    define void @test7()
    245   // CHECK:      [[VAR:%.*]] = alloca i8*,
    246   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
    247   // CHECK:      [[T0:%.*]] = call i8* @test7_source()
    248   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
    249   // CHECK-NEXT: call i8* @objc_initWeak(i8** [[VAR]], i8* [[T1]])
    250   // CHECK-NEXT: call void @objc_release(i8* [[T1]])
    251   // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
    252   // CHECK:      store i32 -1040187392,
    253   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
    254   // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[VAR]])
    255   // CHECK-NEXT: call i8* @objc_initWeak(i8** [[SLOT]], i8* [[T0]])
    256   // CHECK:      call void @test7_helper(
    257   // CHECK-NEXT: call void @objc_destroyWeak(i8** {{%.*}})
    258   // CHECK-NEXT: call void @objc_destroyWeak(i8** [[VAR]])
    259   // CHECK: ret void
    260 
    261   // CHECK-LABEL:    define internal void @__test7_block_invoke
    262   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* {{%.*}}, i32 0, i32 5
    263   // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[SLOT]])
    264   // CHECK-NEXT: call void @test7_consume(i8* [[T0]])
    265   // CHECK-NEXT: call void @objc_release(i8* [[T0]])
    266   // CHECK: ret void
    267 
    268   // CHECK-LABEL:    define internal void @__copy_helper_block_
    269   // CHECK:      getelementptr
    270   // CHECK-NEXT: getelementptr
    271   // CHECK-NEXT: call void @objc_copyWeak(
    272 
    273   // CHECK-LABEL:    define internal void @__destroy_helper_block_
    274   // CHECK:      getelementptr
    275   // CHECK-NEXT: call void @objc_destroyWeak(
    276 }
    277 
    278 @interface Test8 @end
    279 @implementation Test8
    280 - (void) test {
    281 // CHECK:    define internal void @"\01-[Test8 test]"
    282 // CHECK:      [[SELF:%.*]] = alloca [[TEST8:%.*]]*,
    283 // CHECK-NEXT: alloca i8*
    284 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
    285 // CHECK: store
    286 // CHECK-NEXT: store
    287 // CHECK:      [[D0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
    288 // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
    289 // CHECK-NEXT: [[T1:%.*]] = load [[TEST8]]** [[SELF]],
    290 // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST8]]* [[T1]] to i8*
    291 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]])
    292 // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[TEST8]]*
    293 // CHECK-NEXT: store [[TEST8]]* [[T4]], [[TEST8]]** [[T0]]
    294 // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to
    295 // CHECK: call void @test8_helper(
    296 // CHECK-NEXT: [[T1:%.*]] = load [[TEST8]]** [[D0]]
    297 // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST8]]* [[T1]] to i8*
    298 // CHECK-NEXT: call void @objc_release(i8* [[T2]])
    299 // CHECK: ret void
    300 
    301   extern void test8_helper(void (^)(void));
    302   test8_helper(^{ (void) self; });
    303 }
    304 @end
    305 
    306 id test9(void) {
    307   typedef id __attribute__((ns_returns_retained)) blocktype(void);
    308   extern void test9_consume_block(blocktype^);
    309   return ^blocktype {
    310       extern id test9_produce(void);
    311       return test9_produce();
    312   }();
    313 
    314 // CHECK-LABEL:    define i8* @test9(
    315 // CHECK:      load i8** getelementptr
    316 // CHECK-NEXT: bitcast i8*
    317 // CHECK-NEXT: call i8* 
    318 // CHECK-NEXT: tail call i8* @objc_autoreleaseReturnValue
    319 // CHECK-NEXT: ret i8*
    320 
    321 // CHECK:      call i8* @test9_produce()
    322 // CHECK-NEXT: call i8* @objc_retain
    323 // CHECK-NEXT: ret i8*
    324 }
    325 
    326 // rdar://problem/9814099
    327 // Test that we correctly initialize __block variables
    328 // when the initialization captures the variable.
    329 void test10a(void) {
    330   __block void (^block)(void) = ^{ block(); };
    331   // CHECK-LABEL:    define void @test10a()
    332   // CHECK:      [[BYREF:%.*]] = alloca [[BYREF_T:%.*]],
    333 
    334   // Zero-initialization before running the initializer.
    335   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* [[BYREF]], i32 0, i32 6
    336   // CHECK-NEXT: store void ()* null, void ()** [[T0]], align 8
    337 
    338   // Run the initializer as an assignment.
    339   // CHECK:      [[T0:%.*]] = bitcast void ()* {{%.*}} to i8*
    340   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainBlock(i8* [[T0]])
    341   // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to void ()*
    342   // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[BYREF_T]]* [[BYREF]], i32 0, i32 1
    343   // CHECK-NEXT: [[T4:%.*]] = load [[BYREF_T]]** [[T3]]
    344   // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[BYREF_T]]* [[T4]], i32 0, i32 6
    345   // CHECK-NEXT: [[T6:%.*]] = load void ()** [[T5]], align 8
    346   // CHECK-NEXT: store void ()* {{%.*}}, void ()** [[T5]], align 8
    347   // CHECK-NEXT: [[T7:%.*]] = bitcast void ()* [[T6]] to i8*
    348   // CHECK-NEXT: call void @objc_release(i8* [[T7]])
    349 
    350   // Destroy at end of function.
    351   // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]]* [[BYREF]], i32 0, i32 6
    352   // CHECK-NEXT: [[T0:%.*]] = bitcast [[BYREF_T]]* [[BYREF]] to i8*
    353   // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
    354   // CHECK-NEXT: [[T1:%.*]] = load void ()** [[SLOT]]
    355   // CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8*
    356   // CHECK-NEXT: call void @objc_release(i8* [[T2]])
    357   // CHECK: ret void
    358 }
    359 
    360 // <rdar://problem/10402698>: do this copy and dispose with
    361 // objc_retainBlock/release instead of _Block_object_assign/destroy.
    362 // We can also use _Block_object_assign/destroy with
    363 // BLOCK_FIELD_IS_BLOCK as long as we don't pass BLOCK_BYREF_CALLER.
    364 
    365 // CHECK-LABEL: define internal void @__Block_byref_object_copy
    366 // CHECK:      [[D0:%.*]] = load i8** {{%.*}}
    367 // CHECK-NEXT: [[D1:%.*]] = bitcast i8* [[D0]] to [[BYREF_T]]*
    368 // CHECK-NEXT: [[D2:%.*]] = getelementptr inbounds [[BYREF_T]]* [[D1]], i32 0, i32 6
    369 // CHECK-NEXT: [[S0:%.*]] = load i8** {{%.*}}
    370 // CHECK-NEXT: [[S1:%.*]] = bitcast i8* [[S0]] to [[BYREF_T]]*
    371 // CHECK-NEXT: [[S2:%.*]] = getelementptr inbounds [[BYREF_T]]* [[S1]], i32 0, i32 6
    372 // CHECK-NEXT: [[T0:%.*]] = load void ()** [[S2]], align 8
    373 // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
    374 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]])
    375 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
    376 // CHECK-NEXT: store void ()* [[T3]], void ()** [[D2]], align 8
    377 // CHECK: ret void
    378 
    379 // CHECK-LABEL: define internal void @__Block_byref_object_dispose
    380 // CHECK:      [[T0:%.*]] = load i8** {{%.*}}
    381 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[BYREF_T]]*
    382 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BYREF_T]]* [[T1]], i32 0, i32 6
    383 // CHECK-NEXT: [[T3:%.*]] = load void ()** [[T2]]
    384 // CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8*
    385 // CHECK-NEXT: call void @objc_release(i8* [[T4]])
    386 // CHECK-NEXT: ret void
    387 
    388 // Test that we correctly assign to __block variables when the
    389 // assignment captures the variable.
    390 void test10b(void) {
    391   __block void (^block)(void);
    392   block = ^{ block(); };
    393 
    394   // CHECK-LABEL:    define void @test10b()
    395   // CHECK:      [[BYREF:%.*]] = alloca [[BYREF_T:%.*]],
    396 
    397   // Zero-initialize.
    398   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* [[BYREF]], i32 0, i32 6
    399   // CHECK-NEXT: store void ()* null, void ()** [[T0]], align 8
    400 
    401   // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]]* [[BYREF]], i32 0, i32 6
    402 
    403   // The assignment.
    404   // CHECK:      [[T0:%.*]] = bitcast void ()* {{%.*}} to i8*
    405   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainBlock(i8* [[T0]])
    406   // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to void ()*
    407   // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[BYREF_T]]* [[BYREF]], i32 0, i32 1
    408   // CHECK-NEXT: [[T4:%.*]] = load [[BYREF_T]]** [[T3]]
    409   // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[BYREF_T]]* [[T4]], i32 0, i32 6
    410   // CHECK-NEXT: [[T6:%.*]] = load void ()** [[T5]], align 8
    411   // CHECK-NEXT: store void ()* {{%.*}}, void ()** [[T5]], align 8
    412   // CHECK-NEXT: [[T7:%.*]] = bitcast void ()* [[T6]] to i8*
    413   // CHECK-NEXT: call void @objc_release(i8* [[T7]])
    414 
    415   // Destroy at end of function.
    416   // CHECK-NEXT: [[T0:%.*]] = bitcast [[BYREF_T]]* [[BYREF]] to i8*
    417   // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
    418   // CHECK-NEXT: [[T1:%.*]] = load void ()** [[SLOT]]
    419   // CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8*
    420   // CHECK-NEXT: call void @objc_release(i8* [[T2]])
    421   // CHECK: ret void
    422 }
    423 
    424 // rdar://problem/10088932
    425 void test11_helper(id);
    426 void test11a(void) {
    427   int x;
    428   test11_helper(^{ (void) x; });
    429 
    430   // CHECK-LABEL:    define void @test11a()
    431   // CHECK:      [[X:%.*]] = alloca i32, align 4
    432   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], align 8
    433   // CHECK:      [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
    434   // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
    435   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]])
    436   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
    437   // CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8*
    438   // CHECK-NEXT: call void @test11_helper(i8* [[T4]])
    439   // CHECK-NEXT: [[T5:%.*]] = bitcast void ()* [[T3]] to i8*
    440   // CHECK-NEXT: call void @objc_release(i8* [[T5]])
    441   // CHECK: ret void
    442 }
    443 void test11b(void) {
    444   int x;
    445   id b = ^{ (void) x; };
    446 
    447   // CHECK-LABEL:    define void @test11b()
    448   // CHECK:      [[X:%.*]] = alloca i32, align 4
    449   // CHECK-NEXT: [[B:%.*]] = alloca i8*, align 8
    450   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], align 8
    451   // CHECK:      [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
    452   // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
    453   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]])
    454   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
    455   // CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8*
    456   // CHECK-NEXT: store i8* [[T4]], i8** [[B]], align 8
    457   // CHECK-NEXT: [[T5:%.*]] = load i8** [[B]]
    458   // CHECK-NEXT: call void @objc_release(i8* [[T5]])
    459   // CHECK: ret void
    460 }
    461 
    462 // rdar://problem/9979150
    463 @interface Test12
    464 @property (strong) void(^ablock)(void);
    465 @property (nonatomic, strong) void(^nblock)(void);
    466 @end
    467 @implementation Test12
    468 @synthesize ablock, nblock;
    469 // CHECK:    define internal void ()* @"\01-[Test12 ablock]"(
    470 // CHECK:    call i8* @objc_getProperty(i8* {{%.*}}, i8* {{%.*}}, i64 {{%.*}}, i1 zeroext true)
    471 
    472 // CHECK:    define internal void @"\01-[Test12 setAblock:]"(
    473 // CHECK:    call void @objc_setProperty(i8* {{%.*}}, i8* {{%.*}}, i64 {{%.*}}, i8* {{%.*}}, i1 zeroext true, i1 zeroext true)
    474 
    475 // CHECK:    define internal void ()* @"\01-[Test12 nblock]"(
    476 // CHECK:    call i8* @objc_getProperty(i8* {{%.*}}, i8* {{%.*}}, i64 {{%.*}}, i1 zeroext false)
    477 
    478 // CHECK:    define internal void @"\01-[Test12 setNblock:]"(
    479 // CHECK:    call void @objc_setProperty(i8* {{%.*}}, i8* {{%.*}}, i64 {{%.*}}, i8* {{%.*}}, i1 zeroext false, i1 zeroext true)
    480 @end
    481 
    482 // rdar://problem/10131784
    483 void test13(id x) {
    484   extern void test13_helper(id);
    485   extern void test13_use(void(^)(void));
    486 
    487   void (^b)(void) = (x ? ^{test13_helper(x);} : 0);
    488   test13_use(b);
    489 
    490   // CHECK-LABEL:    define void @test13(
    491   // CHECK:      [[X:%.*]] = alloca i8*, align 8
    492   // CHECK-NEXT: [[B:%.*]] = alloca void ()*, align 8
    493   // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:.*]], align 8
    494   // CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1
    495   // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}})
    496   // CHECK-NEXT: store i8* [[T0]], i8** [[X]], align 8
    497   // CHECK-NEXT: [[CLEANUP_ADDR:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
    498   // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]], align 8
    499   // CHECK-NEXT: [[T1:%.*]] = icmp ne i8* [[T0]], null
    500   // CHECK-NEXT: store i1 false, i1* [[CLEANUP_ACTIVE]]
    501   // CHECK-NEXT: br i1 [[T1]],
    502 
    503   // CHECK-NOT:  br
    504   // CHECK:      [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
    505   // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]], align 8
    506   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
    507   // CHECK-NEXT: store i8* [[T1]], i8** [[CAPTURE]], align 8
    508   // CHECK-NEXT: store i1 true, i1* [[CLEANUP_ACTIVE]]
    509   // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
    510   // CHECK-NEXT: br label
    511   // CHECK:      br label
    512   // CHECK:      [[T0:%.*]] = phi void ()*
    513   // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
    514   // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]])
    515   // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
    516   // CHECK-NEXT: store void ()* [[T3]], void ()** [[B]], align 8
    517   // CHECK-NEXT: [[T0:%.*]] = load void ()** [[B]], align 8
    518   // CHECK-NEXT: call void @test13_use(void ()* [[T0]])
    519   // CHECK-NEXT: [[T0:%.*]] = load void ()** [[B]]
    520   // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
    521   // CHECK-NEXT: call void @objc_release(i8* [[T1]])
    522 
    523   // CHECK-NEXT: [[T0:%.*]] = load i1* [[CLEANUP_ACTIVE]]
    524   // CHECK-NEXT: br i1 [[T0]]
    525   // CHECK:      [[T0:%.*]] = load i8** [[CLEANUP_ADDR]]
    526   // CHECK-NEXT: call void @objc_release(i8* [[T0]])
    527   // CHECK-NEXT: br label
    528 
    529   // CHECK:      [[T0:%.*]] = load i8** [[X]]
    530   // CHECK-NEXT: call void @objc_release(i8* [[T0]])
    531   // CHECK-NEXT: ret void
    532 }
    533 
    534 // <rdar://problem/10907510>
    535 void test14() {
    536   void (^const x[1])(void) = { ^{} };
    537 }
    538 
    539 // rdar://11149025
    540 // Don't make invalid ASTs and crash.
    541 void test15_helper(void (^block)(void), int x);
    542 void test15(int a) {
    543   test15_helper(^{ (void) a; }, ({ a; }));
    544 }
    545 
    546 // rdar://11016025
    547 void test16() {
    548   void (^BLKVAR)(void) = ^{ BLKVAR(); };
    549 
    550   // CHECK-LABEL: define void @test16(
    551   // CHECK: [[BLKVAR:%.*]]  = alloca void ()*, align 8
    552   // CHECK-NEXT:  [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
    553   // CHECK-NEXT:  [[SLOTREL:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
    554   // CHECK-NEXT:  store void ()* null, void ()** [[BLKVAR]], align 8
    555 }
    556 
    557 // rdar://12151005
    558 //
    559 // This is an intentional exception to our conservative jump-scope
    560 // checking for full-expressions containing block literals with
    561 // non-trivial cleanups: if the block literal appears in the operand
    562 // of a return statement, there's no need to extend its lifetime.
    563 id (^test17(id self, int which))(void) {
    564   switch (which) {
    565   case 1: return ^{ return self; };
    566   case 0: return ^{ return self; };
    567   }
    568   return (void*) 0;
    569 }
    570 // CHECK-LABEL:    define i8* ()* @test17(
    571 // CHECK:      [[RET:%.*]] = alloca i8* ()*, align
    572 // CHECK-NEXT: [[SELF:%.*]] = alloca i8*,
    573 // CHECK:      [[B0:%.*]] = alloca [[BLOCK:<.*>]], align
    574 // CHECK:      [[B1:%.*]] = alloca [[BLOCK]], align
    575 // CHECK:      [[T0:%.*]] = call i8* @objc_retain(i8*
    576 // CHECK-NEXT: store i8* [[T0]], i8** [[SELF]], align
    577 // CHECK-NOT:  objc_retain
    578 // CHECK-NOT:  objc_release
    579 // CHECK:      [[DESTROY:%.*]] = getelementptr inbounds [[BLOCK]]* [[B0]], i32 0, i32 5
    580 // CHECK-NOT:  objc_retain
    581 // CHECK-NOT:  objc_release
    582 // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BLOCK]]* [[B0]], i32 0, i32 5
    583 // CHECK-NEXT: [[T1:%.*]] = load i8** [[SELF]], align
    584 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
    585 // CHECK-NEXT: store i8* [[T2]], i8** [[T0]],
    586 // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK]]* [[B0]] to i8* ()*
    587 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* ()* [[T0]] to i8*
    588 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]])
    589 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8* ()*
    590 // CHECK-NEXT: store i8* ()* [[T3]], i8* ()** [[RET]]
    591 // CHECK-NEXT: [[T0:%.*]] = load i8** [[DESTROY]]
    592 // CHECK-NEXT: call void @objc_release(i8* [[T0]])
    593 // CHECK-NEXT: store i32
    594 // CHECK-NEXT: br label
    595 // CHECK-NOT:  objc_retain
    596 // CHECK-NOT:  objc_release
    597 // CHECK:      [[DESTROY:%.*]] = getelementptr inbounds [[BLOCK]]* [[B1]], i32 0, i32 5
    598 // CHECK-NOT:  objc_retain
    599 // CHECK-NOT:  objc_release
    600 // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BLOCK]]* [[B1]], i32 0, i32 5
    601 // CHECK-NEXT: [[T1:%.*]] = load i8** [[SELF]], align
    602 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
    603 // CHECK-NEXT: store i8* [[T2]], i8** [[T0]],
    604 // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK]]* [[B1]] to i8* ()*
    605 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* ()* [[T0]] to i8*
    606 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]])
    607 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8* ()*
    608 // CHECK-NEXT: store i8* ()* [[T3]], i8* ()** [[RET]]
    609 // CHECK-NEXT: [[T0:%.*]] = load i8** [[DESTROY]]
    610 // CHECK-NEXT: call void @objc_release(i8* [[T0]])
    611 // CHECK-NEXT: store i32
    612 // CHECK-NEXT: br label
    613 
    614 void test18(id x) {
    615 // CHECK-UNOPT-LABEL:    define void @test18(
    616 // CHECK-UNOPT:      [[X:%.*]] = alloca i8*,
    617 // CHECK-UNOPT-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
    618 // CHECK-UNOPT-NEXT: store i8* null, i8** [[X]]
    619 // CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X]], 
    620 // CHECK-UNOPT-NEXT: [[SLOTREL:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
    621 // CHECK-UNOPT:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
    622 // CHECK-UNOPT-NEXT: [[T0:%.*]] = load i8** [[X]],
    623 // CHECK-UNOPT-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
    624 // CHECK-UNOPT-NEXT: store i8* [[T1]], i8** [[SLOT]],
    625 // CHECK-UNOPT-NEXT: bitcast
    626 // CHECK-UNOPT-NEXT: call void @test18_helper(
    627 // CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[SLOTREL]], i8* null) [[NUW:#[0-9]+]]
    628 // CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) [[NUW]]
    629 // CHECK-UNOPT-NEXT: ret void
    630   extern void test18_helper(id (^)(void));
    631   test18_helper(^{ return x; });
    632 
    633 // CHECK-UNOPT-LABEL:    define internal void @__copy_helper_block_
    634 // CHECK-UNOPT:      [[T0:%.*]] = load i8**
    635 // CHECK-UNOPT-NEXT: [[SRC:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
    636 // CHECK-UNOPT-NEXT: [[T0:%.*]] = load i8**
    637 // CHECK-UNOPT-NEXT: [[DST:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
    638 // CHECK-UNOPT-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[SRC]], i32 0, i32 5
    639 // CHECK-UNOPT-NEXT: [[T1:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[DST]], i32 0, i32 5
    640 // CHECK-UNOPT-NEXT: [[T2:%.*]] = load i8** [[T0]]
    641 // CHECK-UNOPT-NEXT: store i8* null, i8** [[T1]]
    642 // CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[T1]], i8* [[T2]]) [[NUW]]
    643 // CHECK-UNOPT-NEXT: ret void
    644 
    645 // CHECK-UNOPT-LABEL:    define internal void @__destroy_helper_block_
    646 // CHECK-UNOPT:      [[T0:%.*]] = load i8**
    647 // CHECK-UNOPT-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
    648 // CHECK-UNOPT-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[T1]], i32 0, i32 5
    649 // CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null)
    650 // CHECK-UNOPT-NEXT: ret void
    651 }
    652 
    653 // rdar://13588325
    654 void test19_sink(void (^)(int));
    655 void test19(void (^b)(void)) {
    656 // CHECK-LABEL:    define void @test19(
    657 //   Prologue.
    658 // CHECK:      [[B:%.*]] = alloca void ()*,
    659 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
    660 // CHECK-NEXT: [[T0:%.*]] = bitcast void ()* {{%.*}} to i8*
    661 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
    662 // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to void ()*
    663 // CHECK-NEXT: store void ()* [[T2]], void ()** [[B]]
    664 
    665 //   Block setup.  We skip most of this.  Note the bare retain.
    666 // CHECK-NEXT: [[SLOTREL:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
    667 // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
    668 // CHECK-NEXT: [[T0:%.*]] = load void ()** [[B]],
    669 // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
    670 // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
    671 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
    672 // CHECK-NEXT: store void ()* [[T3]], void ()** [[SLOT]],
    673 //   Call.
    674 // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void (i32)*
    675 // CHECK-NEXT: call void @test19_sink(void (i32)* [[T0]])
    676 
    677   test19_sink(^(int x) { b(); });
    678 
    679 //   Block teardown.
    680 // CHECK-NEXT: [[T0:%.*]] = load void ()** [[SLOTREL]]
    681 // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
    682 // CHECK-NEXT: call void @objc_release(i8* [[T1]])
    683 
    684 //   Local cleanup.
    685 // CHECK-NEXT: [[T0:%.*]] = load void ()** [[B]]
    686 // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
    687 // CHECK-NEXT: call void @objc_release(i8* [[T1]])
    688 
    689 // CHECK-NEXT: ret void
    690 }
    691 
    692 // CHECK: attributes [[NUW]] = { nounwind }
    693 // CHECK-UNOPT: attributes [[NUW]] = { nounwind }
    694