Home | History | Annotate | Download | only in ObjCARC
      1 ; RUN: opt -objc-arc -S < %s | FileCheck %s
      2 
      3 %struct.__objcFastEnumerationState = type { i64, i8**, i64*, [5 x i64] }
      4 
      5 @"\01L_OBJC_METH_VAR_NAME_" = internal global [43 x i8] c"countByEnumeratingWithState:objects:count:\00", section "__TEXT,__objc_methname,cstring_literals", align 1
      6 @"\01L_OBJC_SELECTOR_REFERENCES_" = internal global i8* getelementptr inbounds ([43 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i64 0, i64 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
      7 @g = common global i8* null, align 8
      8 @"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"
      9 
     10 declare void @callee()
     11 declare i8* @returner()
     12 declare i8* @objc_retainAutoreleasedReturnValue(i8*)
     13 declare i8* @objc_retain(i8*)
     14 declare void @objc_enumerationMutation(i8*)
     15 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
     16 declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind
     17 declare void @use(i8*)
     18 declare void @objc_release(i8*)
     19 
     20 !0 = metadata !{}
     21 
     22 ; Delete a nested retain+release pair.
     23 
     24 ; CHECK: define void @test0(
     25 ; CHECK: call i8* @objc_retain
     26 ; CHECK-NOT: @objc_retain
     27 ; CHECK: }
     28 define void @test0(i8* %a) nounwind {
     29 entry:
     30   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
     31   %items.ptr = alloca [16 x i8*], align 8
     32   %0 = call i8* @objc_retain(i8* %a) nounwind
     33   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
     34   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
     35   %1 = call i8* @objc_retain(i8* %0) nounwind
     36   %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
     37   %call = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
     38   %iszero = icmp eq i64 %call, 0
     39   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
     40 
     41 forcoll.loopinit:
     42   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
     43   %mutationsptr = load i64** %mutationsptr.ptr, align 8
     44   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
     45   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
     46   br label %forcoll.loopbody.outer
     47 
     48 forcoll.loopbody.outer:
     49   %forcoll.count.ph = phi i64 [ %call, %forcoll.loopinit ], [ %call6, %forcoll.refetch ]
     50   %tmp7 = icmp ugt i64 %forcoll.count.ph, 1
     51   %umax = select i1 %tmp7, i64 %forcoll.count.ph, i64 1
     52   br label %forcoll.loopbody
     53 
     54 forcoll.loopbody:
     55   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
     56   %mutationsptr3 = load i64** %mutationsptr.ptr, align 8
     57   %statemutations = load i64* %mutationsptr3, align 8
     58   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
     59   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
     60 
     61 forcoll.mutated:
     62   call void @objc_enumerationMutation(i8* %1)
     63   br label %forcoll.notmutated
     64 
     65 forcoll.notmutated:
     66   %stateitems = load i8*** %stateitems.ptr, align 8
     67   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
     68   %3 = load i8** %currentitem.ptr, align 8
     69   call void @use(i8* %3)
     70   %4 = add i64 %forcoll.index, 1
     71   %exitcond = icmp eq i64 %4, %umax
     72   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
     73 
     74 forcoll.refetch:
     75   %tmp5 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
     76   %call6 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp5, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
     77   %5 = icmp eq i64 %call6, 0
     78   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
     79 
     80 forcoll.empty:
     81   call void @objc_release(i8* %1) nounwind
     82   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
     83   ret void
     84 }
     85 
     86 ; Delete a nested retain+release pair.
     87 
     88 ; CHECK: define void @test2(
     89 ; CHECK: call i8* @objc_retain
     90 ; CHECK-NOT: @objc_retain
     91 ; CHECK: }
     92 define void @test2() nounwind {
     93 entry:
     94   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
     95   %items.ptr = alloca [16 x i8*], align 8
     96   %call = call i8* @returner()
     97   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
     98   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
     99   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
    100   %1 = call i8* @objc_retain(i8* %0) nounwind
    101   %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    102   %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    103   %iszero = icmp eq i64 %call3, 0
    104   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
    105 
    106 forcoll.loopinit:
    107   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
    108   %mutationsptr = load i64** %mutationsptr.ptr, align 8
    109   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
    110   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
    111   br label %forcoll.loopbody.outer
    112 
    113 forcoll.loopbody.outer:
    114   %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
    115   %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
    116   %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
    117   br label %forcoll.loopbody
    118 
    119 forcoll.loopbody:
    120   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
    121   %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
    122   %statemutations = load i64* %mutationsptr4, align 8
    123   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
    124   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
    125 
    126 forcoll.mutated:
    127   call void @objc_enumerationMutation(i8* %1)
    128   br label %forcoll.notmutated
    129 
    130 forcoll.notmutated:
    131   %stateitems = load i8*** %stateitems.ptr, align 8
    132   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
    133   %3 = load i8** %currentitem.ptr, align 8
    134   call void @use(i8* %3)
    135   %4 = add i64 %forcoll.index, 1
    136   %exitcond = icmp eq i64 %4, %umax
    137   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
    138 
    139 forcoll.refetch:
    140   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    141   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    142   %5 = icmp eq i64 %call7, 0
    143   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
    144 
    145 forcoll.empty:
    146   call void @objc_release(i8* %1) nounwind
    147   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
    148   ret void
    149 }
    150 
    151 ; Delete a nested retain+release pair.
    152 
    153 ; CHECK: define void @test4(
    154 ; CHECK: call i8* @objc_retain
    155 ; CHECK-NOT: @objc_retain
    156 ; CHECK: }
    157 define void @test4() nounwind {
    158 entry:
    159   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
    160   %items.ptr = alloca [16 x i8*], align 8
    161   %tmp = load i8** @g, align 8
    162   %0 = call i8* @objc_retain(i8* %tmp) nounwind
    163   %tmp2 = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
    164   call void @llvm.memset.p0i8.i64(i8* %tmp2, i8 0, i64 64, i32 8, i1 false)
    165   %1 = call i8* @objc_retain(i8* %0) nounwind
    166   %tmp4 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    167   %call = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp4, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    168   %iszero = icmp eq i64 %call, 0
    169   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
    170 
    171 forcoll.loopinit:
    172   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
    173   %mutationsptr = load i64** %mutationsptr.ptr, align 8
    174   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
    175   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
    176   br label %forcoll.loopbody.outer
    177 
    178 forcoll.loopbody.outer:
    179   %forcoll.count.ph = phi i64 [ %call, %forcoll.loopinit ], [ %call8, %forcoll.refetch ]
    180   %tmp9 = icmp ugt i64 %forcoll.count.ph, 1
    181   %umax = select i1 %tmp9, i64 %forcoll.count.ph, i64 1
    182   br label %forcoll.loopbody
    183 
    184 forcoll.loopbody:
    185   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
    186   %mutationsptr5 = load i64** %mutationsptr.ptr, align 8
    187   %statemutations = load i64* %mutationsptr5, align 8
    188   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
    189   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
    190 
    191 forcoll.mutated:
    192   call void @objc_enumerationMutation(i8* %1)
    193   br label %forcoll.notmutated
    194 
    195 forcoll.notmutated:
    196   %stateitems = load i8*** %stateitems.ptr, align 8
    197   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
    198   %3 = load i8** %currentitem.ptr, align 8
    199   call void @use(i8* %3)
    200   %4 = add i64 %forcoll.index, 1
    201   %exitcond = icmp eq i64 %4, %umax
    202   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
    203 
    204 forcoll.refetch:
    205   %tmp7 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    206   %call8 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp7, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    207   %5 = icmp eq i64 %call8, 0
    208   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
    209 
    210 forcoll.empty:
    211   call void @objc_release(i8* %1) nounwind
    212   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
    213   ret void
    214 }
    215 
    216 ; Delete a nested retain+release pair.
    217 
    218 ; CHECK: define void @test5(
    219 ; CHECK: call i8* @objc_retain
    220 ; CHECK-NOT: @objc_retain
    221 ; CHECK: }
    222 define void @test5() nounwind {
    223 entry:
    224   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
    225   %items.ptr = alloca [16 x i8*], align 8
    226   %call = call i8* @returner()
    227   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
    228   call void @callee()
    229   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
    230   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
    231   %1 = call i8* @objc_retain(i8* %0) nounwind
    232   %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    233   %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    234   %iszero = icmp eq i64 %call3, 0
    235   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
    236 
    237 forcoll.loopinit:
    238   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
    239   %mutationsptr = load i64** %mutationsptr.ptr, align 8
    240   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
    241   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
    242   br label %forcoll.loopbody.outer
    243 
    244 forcoll.loopbody.outer:
    245   %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
    246   %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
    247   %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
    248   br label %forcoll.loopbody
    249 
    250 forcoll.loopbody:
    251   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
    252   %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
    253   %statemutations = load i64* %mutationsptr4, align 8
    254   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
    255   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
    256 
    257 forcoll.mutated:
    258   call void @objc_enumerationMutation(i8* %1)
    259   br label %forcoll.notmutated
    260 
    261 forcoll.notmutated:
    262   %stateitems = load i8*** %stateitems.ptr, align 8
    263   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
    264   %3 = load i8** %currentitem.ptr, align 8
    265   call void @use(i8* %3)
    266   %4 = add i64 %forcoll.index, 1
    267   %exitcond = icmp eq i64 %4, %umax
    268   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
    269 
    270 forcoll.refetch:
    271   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    272   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    273   %5 = icmp eq i64 %call7, 0
    274   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
    275 
    276 forcoll.empty:
    277   call void @objc_release(i8* %1) nounwind
    278   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
    279   ret void
    280 }
    281 
    282 ; Delete a nested retain+release pair.
    283 
    284 ; CHECK: define void @test6(
    285 ; CHECK: call i8* @objc_retain
    286 ; CHECK-NOT: @objc_retain
    287 ; CHECK: }
    288 define void @test6() nounwind {
    289 entry:
    290   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
    291   %items.ptr = alloca [16 x i8*], align 8
    292   %call = call i8* @returner()
    293   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
    294   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
    295   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
    296   %1 = call i8* @objc_retain(i8* %0) nounwind
    297   %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    298   %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    299   %iszero = icmp eq i64 %call3, 0
    300   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
    301 
    302 forcoll.loopinit:
    303   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
    304   %mutationsptr = load i64** %mutationsptr.ptr, align 8
    305   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
    306   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
    307   br label %forcoll.loopbody.outer
    308 
    309 forcoll.loopbody.outer:
    310   %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
    311   %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
    312   %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
    313   br label %forcoll.loopbody
    314 
    315 forcoll.loopbody:
    316   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
    317   %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
    318   %statemutations = load i64* %mutationsptr4, align 8
    319   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
    320   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
    321 
    322 forcoll.mutated:
    323   call void @objc_enumerationMutation(i8* %1)
    324   br label %forcoll.notmutated
    325 
    326 forcoll.notmutated:
    327   %stateitems = load i8*** %stateitems.ptr, align 8
    328   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
    329   %3 = load i8** %currentitem.ptr, align 8
    330   call void @use(i8* %3)
    331   %4 = add i64 %forcoll.index, 1
    332   %exitcond = icmp eq i64 %4, %umax
    333   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
    334 
    335 forcoll.refetch:
    336   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    337   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    338   %5 = icmp eq i64 %call7, 0
    339   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
    340 
    341 forcoll.empty:
    342   call void @objc_release(i8* %1) nounwind
    343   call void @callee()
    344   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
    345   ret void
    346 }
    347 
    348 ; Delete a nested retain+release pair.
    349 
    350 ; CHECK: define void @test7(
    351 ; CHECK: call i8* @objc_retain
    352 ; CHECK-NOT: @objc_retain
    353 ; CHECK: }
    354 define void @test7() nounwind {
    355 entry:
    356   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
    357   %items.ptr = alloca [16 x i8*], align 8
    358   %call = call i8* @returner()
    359   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
    360   call void @callee()
    361   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
    362   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
    363   %1 = call i8* @objc_retain(i8* %0) nounwind
    364   %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    365   %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    366   %iszero = icmp eq i64 %call3, 0
    367   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
    368 
    369 forcoll.loopinit:
    370   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
    371   %mutationsptr = load i64** %mutationsptr.ptr, align 8
    372   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
    373   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
    374   br label %forcoll.loopbody.outer
    375 
    376 forcoll.loopbody.outer:
    377   %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
    378   %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
    379   %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
    380   br label %forcoll.loopbody
    381 
    382 forcoll.loopbody:
    383   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
    384   %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
    385   %statemutations = load i64* %mutationsptr4, align 8
    386   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
    387   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
    388 
    389 forcoll.mutated:
    390   call void @objc_enumerationMutation(i8* %1)
    391   br label %forcoll.notmutated
    392 
    393 forcoll.notmutated:
    394   %stateitems = load i8*** %stateitems.ptr, align 8
    395   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
    396   %3 = load i8** %currentitem.ptr, align 8
    397   call void @use(i8* %3)
    398   %4 = add i64 %forcoll.index, 1
    399   %exitcond = icmp eq i64 %4, %umax
    400   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
    401 
    402 forcoll.refetch:
    403   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    404   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    405   %5 = icmp eq i64 %call7, 0
    406   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
    407 
    408 forcoll.empty:
    409   call void @objc_release(i8* %1) nounwind
    410   call void @callee()
    411   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
    412   ret void
    413 }
    414 
    415 ; Delete a nested retain+release pair.
    416 
    417 ; CHECK: define void @test8(
    418 ; CHECK: call i8* @objc_retain
    419 ; CHECK-NOT: @objc_retain
    420 ; CHECK: }
    421 define void @test8() nounwind {
    422 entry:
    423   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
    424   %items.ptr = alloca [16 x i8*], align 8
    425   %call = call i8* @returner()
    426   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
    427   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
    428   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
    429   %1 = call i8* @objc_retain(i8* %0) nounwind
    430   %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    431   %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    432   %iszero = icmp eq i64 %call3, 0
    433   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
    434 
    435 forcoll.loopinit:
    436   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
    437   %mutationsptr = load i64** %mutationsptr.ptr, align 8
    438   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
    439   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
    440   br label %forcoll.loopbody.outer
    441 
    442 forcoll.loopbody.outer:
    443   %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
    444   %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
    445   %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
    446   br label %forcoll.loopbody
    447 
    448 forcoll.loopbody:
    449   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.next ]
    450   %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
    451   %statemutations = load i64* %mutationsptr4, align 8
    452   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
    453   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
    454 
    455 forcoll.mutated:
    456   call void @objc_enumerationMutation(i8* %1)
    457   br label %forcoll.notmutated
    458 
    459 forcoll.notmutated:
    460   %stateitems = load i8*** %stateitems.ptr, align 8
    461   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
    462   %3 = load i8** %currentitem.ptr, align 8
    463   %tobool = icmp eq i8* %3, null
    464   br i1 %tobool, label %forcoll.next, label %if.then
    465 
    466 if.then:
    467   call void @callee()
    468   br label %forcoll.next
    469 
    470 forcoll.next:
    471   %4 = add i64 %forcoll.index, 1
    472   %exitcond = icmp eq i64 %4, %umax
    473   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
    474 
    475 forcoll.refetch:
    476   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    477   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    478   %5 = icmp eq i64 %call7, 0
    479   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
    480 
    481 forcoll.empty:
    482   call void @objc_release(i8* %1) nounwind
    483   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
    484   ret void
    485 }
    486 
    487 ; Delete a nested retain+release pair.
    488 
    489 ; CHECK: define void @test9(
    490 ; CHECK: call i8* @objc_retain
    491 ; CHECK: call i8* @objc_retain
    492 ; CHECK-NOT: @objc_retain
    493 ; CHECK: }
    494 define void @test9() nounwind {
    495 entry:
    496   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
    497   %items.ptr = alloca [16 x i8*], align 8
    498   %call = call i8* @returner()
    499   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
    500   %call1 = call i8* @returner()
    501   %1 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call1) nounwind
    502   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
    503   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
    504   %2 = call i8* @objc_retain(i8* %0) nounwind
    505   %tmp3 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    506   %call4 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %2, i8* %tmp3, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    507   %iszero = icmp eq i64 %call4, 0
    508   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
    509 
    510 forcoll.loopinit:
    511   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
    512   %mutationsptr = load i64** %mutationsptr.ptr, align 8
    513   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
    514   br label %forcoll.loopbody.outer
    515 
    516 forcoll.loopbody.outer:
    517   %forcoll.count.ph = phi i64 [ %call4, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
    518   %tmp9 = icmp ugt i64 %forcoll.count.ph, 1
    519   %umax = select i1 %tmp9, i64 %forcoll.count.ph, i64 1
    520   br label %forcoll.loopbody
    521 
    522 forcoll.loopbody:
    523   %forcoll.index = phi i64 [ %phitmp, %forcoll.notmutated.forcoll.loopbody_crit_edge ], [ 1, %forcoll.loopbody.outer ]
    524   %mutationsptr5 = load i64** %mutationsptr.ptr, align 8
    525   %statemutations = load i64* %mutationsptr5, align 8
    526   %3 = icmp eq i64 %statemutations, %forcoll.initial-mutations
    527   br i1 %3, label %forcoll.notmutated, label %forcoll.mutated
    528 
    529 forcoll.mutated:
    530   call void @objc_enumerationMutation(i8* %2)
    531   br label %forcoll.notmutated
    532 
    533 forcoll.notmutated:
    534   %exitcond = icmp eq i64 %forcoll.index, %umax
    535   br i1 %exitcond, label %forcoll.refetch, label %forcoll.notmutated.forcoll.loopbody_crit_edge
    536 
    537 forcoll.notmutated.forcoll.loopbody_crit_edge:
    538   %phitmp = add i64 %forcoll.index, 1
    539   br label %forcoll.loopbody
    540 
    541 forcoll.refetch:
    542   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    543   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %2, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    544   %4 = icmp eq i64 %call7, 0
    545   br i1 %4, label %forcoll.empty, label %forcoll.loopbody.outer
    546 
    547 forcoll.empty:
    548   call void @objc_release(i8* %2) nounwind
    549   call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
    550   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
    551   ret void
    552 }
    553 
    554 ; Delete a nested retain+release pair.
    555 
    556 ; CHECK: define void @test10(
    557 ; CHECK: call i8* @objc_retain
    558 ; CHECK: call i8* @objc_retain
    559 ; CHECK-NOT: @objc_retain
    560 ; CHECK: }
    561 define void @test10() nounwind {
    562 entry:
    563   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
    564   %items.ptr = alloca [16 x i8*], align 8
    565   %call = call i8* @returner()
    566   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
    567   %call1 = call i8* @returner()
    568   %1 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call1) nounwind
    569   call void @callee()
    570   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
    571   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
    572   %2 = call i8* @objc_retain(i8* %0) nounwind
    573   %tmp3 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    574   %call4 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %2, i8* %tmp3, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    575   %iszero = icmp eq i64 %call4, 0
    576   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
    577 
    578 forcoll.loopinit:
    579   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
    580   %mutationsptr = load i64** %mutationsptr.ptr, align 8
    581   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
    582   br label %forcoll.loopbody.outer
    583 
    584 forcoll.loopbody.outer:
    585   %forcoll.count.ph = phi i64 [ %call4, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
    586   %tmp9 = icmp ugt i64 %forcoll.count.ph, 1
    587   %umax = select i1 %tmp9, i64 %forcoll.count.ph, i64 1
    588   br label %forcoll.loopbody
    589 
    590 forcoll.loopbody:
    591   %forcoll.index = phi i64 [ %phitmp, %forcoll.notmutated.forcoll.loopbody_crit_edge ], [ 1, %forcoll.loopbody.outer ]
    592   %mutationsptr5 = load i64** %mutationsptr.ptr, align 8
    593   %statemutations = load i64* %mutationsptr5, align 8
    594   %3 = icmp eq i64 %statemutations, %forcoll.initial-mutations
    595   br i1 %3, label %forcoll.notmutated, label %forcoll.mutated
    596 
    597 forcoll.mutated:
    598   call void @objc_enumerationMutation(i8* %2)
    599   br label %forcoll.notmutated
    600 
    601 forcoll.notmutated:
    602   %exitcond = icmp eq i64 %forcoll.index, %umax
    603   br i1 %exitcond, label %forcoll.refetch, label %forcoll.notmutated.forcoll.loopbody_crit_edge
    604 
    605 forcoll.notmutated.forcoll.loopbody_crit_edge:
    606   %phitmp = add i64 %forcoll.index, 1
    607   br label %forcoll.loopbody
    608 
    609 forcoll.refetch:
    610   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
    611   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %2, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
    612   %4 = icmp eq i64 %call7, 0
    613   br i1 %4, label %forcoll.empty, label %forcoll.loopbody.outer
    614 
    615 forcoll.empty:
    616   call void @objc_release(i8* %2) nounwind
    617   call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
    618   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
    619   ret void
    620 }
    621