brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.1 KiB · d43f713 Raw
583 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=objc-arc < %s | FileCheck %s3; rdar://95034164 5; Detect loop boundaries and don't move retains and releases6; across them.7 8declare void @use_pointer(ptr)9declare ptr @llvm.objc.retain(ptr)10declare void @llvm.objc.release(ptr)11declare void @callee()12declare void @block_callee(ptr)13 14define void @test0(ptr %digits) {15; CHECK-LABEL: @test0(16; CHECK-NEXT:  entry:17; CHECK-NEXT:    [[TMP1:%.*]] = tail call ptr @llvm.objc.retain(ptr [[DIGITS:%.*]]) #[[ATTR0:[0-9]+]]18; CHECK-NEXT:    call void @use_pointer(ptr [[DIGITS]])19; CHECK-NEXT:    br label [[FOR_BODY:%.*]]20; CHECK:       for.body:21; CHECK-NEXT:    [[UPCDIGITINDEX_01:%.*]] = phi i64 [ 2, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]22; CHECK-NEXT:    call void @use_pointer(ptr [[DIGITS]])23; CHECK-NEXT:    [[INC]] = add i64 [[UPCDIGITINDEX_01]], 124; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[INC]], 1225; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]26; CHECK:       for.end:27; CHECK-NEXT:    call void @llvm.objc.release(ptr [[DIGITS]]) #[[ATTR0]], !clang.imprecise_release !028; CHECK-NEXT:    ret void29;30entry:31  %tmp1 = call ptr @llvm.objc.retain(ptr %digits) nounwind32  call void @use_pointer(ptr %digits)33  br label %for.body34 35for.body:                                         ; preds = %for.body, %entry36  %upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ]37  call void @use_pointer(ptr %digits)38  %inc = add i64 %upcDigitIndex.01, 139  %cmp = icmp ult i64 %inc, 1240  br i1 %cmp, label %for.body, label %for.end41 42for.end:                                          ; preds = %for.body43  call void @llvm.objc.release(ptr %digits) nounwind, !clang.imprecise_release !044  ret void45}46 47define void @test1(ptr %digits) {48; CHECK-LABEL: @test1(49; CHECK-NEXT:  entry:50; CHECK-NEXT:    [[TMP1:%.*]] = tail call ptr @llvm.objc.retain(ptr [[DIGITS:%.*]]) #[[ATTR0]]51; CHECK-NEXT:    br label [[FOR_BODY:%.*]]52; CHECK:       for.body:53; CHECK-NEXT:    [[UPCDIGITINDEX_01:%.*]] = phi i64 [ 2, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]54; CHECK-NEXT:    call void @use_pointer(ptr [[DIGITS]])55; CHECK-NEXT:    call void @use_pointer(ptr [[DIGITS]])56; CHECK-NEXT:    [[INC]] = add i64 [[UPCDIGITINDEX_01]], 157; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[INC]], 1258; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]59; CHECK:       for.end:60; CHECK-NEXT:    call void @llvm.objc.release(ptr [[DIGITS]]) #[[ATTR0]], !clang.imprecise_release !061; CHECK-NEXT:    ret void62;63entry:64  %tmp1 = call ptr @llvm.objc.retain(ptr %digits) nounwind65  br label %for.body66 67for.body:                                         ; preds = %for.body, %entry68  %upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ]69  call void @use_pointer(ptr %digits)70  call void @use_pointer(ptr %digits)71  %inc = add i64 %upcDigitIndex.01, 172  %cmp = icmp ult i64 %inc, 1273  br i1 %cmp, label %for.body, label %for.end74 75for.end:                                          ; preds = %for.body76  call void @llvm.objc.release(ptr %digits) nounwind, !clang.imprecise_release !077  ret void78}79 80define void @test2(ptr %digits) {81; CHECK-LABEL: @test2(82; CHECK-NEXT:  entry:83; CHECK-NEXT:    [[TMP1:%.*]] = tail call ptr @llvm.objc.retain(ptr [[DIGITS:%.*]]) #[[ATTR0]]84; CHECK-NEXT:    br label [[FOR_BODY:%.*]]85; CHECK:       for.body:86; CHECK-NEXT:    [[UPCDIGITINDEX_01:%.*]] = phi i64 [ 2, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]87; CHECK-NEXT:    call void @use_pointer(ptr [[DIGITS]])88; CHECK-NEXT:    [[INC]] = add i64 [[UPCDIGITINDEX_01]], 189; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[INC]], 1290; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]91; CHECK:       for.end:92; CHECK-NEXT:    call void @use_pointer(ptr [[DIGITS]])93; CHECK-NEXT:    call void @llvm.objc.release(ptr [[DIGITS]]) #[[ATTR0]], !clang.imprecise_release !094; CHECK-NEXT:    ret void95;96entry:97  %tmp1 = call ptr @llvm.objc.retain(ptr %digits) nounwind98  br label %for.body99 100for.body:                                         ; preds = %for.body, %entry101  %upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ]102  call void @use_pointer(ptr %digits)103  %inc = add i64 %upcDigitIndex.01, 1104  %cmp = icmp ult i64 %inc, 12105  br i1 %cmp, label %for.body, label %for.end106 107for.end:                                          ; preds = %for.body108  call void @use_pointer(ptr %digits)109  call void @llvm.objc.release(ptr %digits) nounwind, !clang.imprecise_release !0110  ret void111}112 113; Delete nested retain+release pairs around loops.114define void @test3(ptr %a, i1 %arg) nounwind {115; CHECK-LABEL: @test3(116; CHECK-NEXT:  entry:117; CHECK-NEXT:    [[OUTER:%.*]] = tail call ptr @llvm.objc.retain(ptr [[A:%.*]]) #[[ATTR0]]118; CHECK-NEXT:    br label [[LOOP:%.*]]119; CHECK:       loop:120; CHECK-NEXT:    call void @callee()121; CHECK-NEXT:    store i8 0, ptr [[A]], align 1122; CHECK-NEXT:    br i1 %arg, label [[LOOP]], label [[EXIT:%.*]]123; CHECK:       exit:124; CHECK-NEXT:    call void @llvm.objc.release(ptr [[A]]) #[[ATTR0]], !clang.imprecise_release !0125; CHECK-NEXT:    ret void126;127entry:128  %outer = call ptr @llvm.objc.retain(ptr %a) nounwind129  %inner = call ptr @llvm.objc.retain(ptr %a) nounwind130  br label %loop131 132loop:133  call void @callee()134  store i8 0, ptr %a135  br i1 %arg, label %loop, label %exit136 137exit:138  call void @llvm.objc.release(ptr %a) nounwind139  call void @llvm.objc.release(ptr %a) nounwind, !clang.imprecise_release !0140  ret void141}142 143define void @test4(ptr %a, i1 %arg) nounwind {144; CHECK-LABEL: @test4(145; CHECK-NEXT:  entry:146; CHECK-NEXT:    [[OUTER:%.*]] = tail call ptr @llvm.objc.retain(ptr [[A:%.*]]) #[[ATTR0]]147; CHECK-NEXT:    br label [[LOOP:%.*]]148; CHECK:       loop:149; CHECK-NEXT:    br label [[MORE:%.*]]150; CHECK:       more:151; CHECK-NEXT:    call void @callee()152; CHECK-NEXT:    call void @callee()153; CHECK-NEXT:    store i8 0, ptr [[A]], align 1154; CHECK-NEXT:    br i1 %arg, label [[LOOP]], label [[EXIT:%.*]]155; CHECK:       exit:156; CHECK-NEXT:    call void @llvm.objc.release(ptr [[A]]) #[[ATTR0]], !clang.imprecise_release !0157; CHECK-NEXT:    ret void158;159entry:160  %outer = call ptr @llvm.objc.retain(ptr %a) nounwind161  %inner = call ptr @llvm.objc.retain(ptr %a) nounwind162  br label %loop163 164loop:165  br label %more166 167more:168  call void @callee()169  call void @callee()170  store i8 0, ptr %a171  br i1 %arg, label %loop, label %exit172 173exit:174  call void @llvm.objc.release(ptr %a) nounwind175  call void @llvm.objc.release(ptr %a) nounwind, !clang.imprecise_release !0176  ret void177}178 179define void @test5(ptr %a, i1 %arg) nounwind {180; CHECK-LABEL: @test5(181; CHECK-NEXT:  entry:182; CHECK-NEXT:    [[OUTER:%.*]] = tail call ptr @llvm.objc.retain(ptr [[A:%.*]]) #[[ATTR0]]183; CHECK-NEXT:    call void @callee()184; CHECK-NEXT:    br label [[LOOP:%.*]]185; CHECK:       loop:186; CHECK-NEXT:    br i1 %arg, label [[TRUE:%.*]], label [[MORE:%.*]]187; CHECK:       true:188; CHECK-NEXT:    br label [[MORE]]189; CHECK:       more:190; CHECK-NEXT:    br i1 %arg, label [[EXIT:%.*]], label [[LOOP]]191; CHECK:       exit:192; CHECK-NEXT:    call void @use_pointer(ptr [[A]])193; CHECK-NEXT:    call void @llvm.objc.release(ptr [[A]]) #[[ATTR0]], !clang.imprecise_release !0194; CHECK-NEXT:    ret void195;196entry:197  %outer = tail call ptr @llvm.objc.retain(ptr %a) nounwind198  %inner = tail call ptr @llvm.objc.retain(ptr %a) nounwind199  call void @callee()200  br label %loop201 202loop:203  br i1 %arg, label %true, label %more204 205true:206  br label %more207 208more:209  br i1 %arg, label %exit, label %loop210 211exit:212  call void @use_pointer(ptr %a)213  call void @llvm.objc.release(ptr %a) nounwind214  call void @llvm.objc.release(ptr %a) nounwind, !clang.imprecise_release !0215  ret void216}217 218define void @test6(ptr %a, i1 %arg) nounwind {219; CHECK-LABEL: @test6(220; CHECK-NEXT:  entry:221; CHECK-NEXT:    [[OUTER:%.*]] = tail call ptr @llvm.objc.retain(ptr [[A:%.*]]) #[[ATTR0]]222; CHECK-NEXT:    br label [[LOOP:%.*]]223; CHECK:       loop:224; CHECK-NEXT:    br i1 %arg, label [[TRUE:%.*]], label [[MORE:%.*]]225; CHECK:       true:226; CHECK-NEXT:    call void @callee()227; CHECK-NEXT:    br label [[MORE]]228; CHECK:       more:229; CHECK-NEXT:    br i1 %arg, label [[EXIT:%.*]], label [[LOOP]]230; CHECK:       exit:231; CHECK-NEXT:    call void @use_pointer(ptr [[A]])232; CHECK-NEXT:    call void @llvm.objc.release(ptr [[A]]) #[[ATTR0]], !clang.imprecise_release !0233; CHECK-NEXT:    ret void234;235entry:236  %outer = tail call ptr @llvm.objc.retain(ptr %a) nounwind237  %inner = tail call ptr @llvm.objc.retain(ptr %a) nounwind238  br label %loop239 240loop:241  br i1 %arg, label %true, label %more242 243true:244  call void @callee()245  br label %more246 247more:248  br i1 %arg, label %exit, label %loop249 250exit:251  call void @use_pointer(ptr %a)252  call void @llvm.objc.release(ptr %a) nounwind253  call void @llvm.objc.release(ptr %a) nounwind, !clang.imprecise_release !0254  ret void255}256 257define void @test7(ptr %a, i1 %arg) nounwind {258; CHECK-LABEL: @test7(259; CHECK-NEXT:  entry:260; CHECK-NEXT:    [[OUTER:%.*]] = tail call ptr @llvm.objc.retain(ptr [[A:%.*]]) #[[ATTR0]]261; CHECK-NEXT:    call void @callee()262; CHECK-NEXT:    br label [[LOOP:%.*]]263; CHECK:       loop:264; CHECK-NEXT:    br i1 %arg, label [[TRUE:%.*]], label [[MORE:%.*]]265; CHECK:       true:266; CHECK-NEXT:    call void @use_pointer(ptr [[A]])267; CHECK-NEXT:    br label [[MORE]]268; CHECK:       more:269; CHECK-NEXT:    br i1 %arg, label [[EXIT:%.*]], label [[LOOP]]270; CHECK:       exit:271; CHECK-NEXT:    call void @llvm.objc.release(ptr [[A]]) #[[ATTR0]], !clang.imprecise_release !0272; CHECK-NEXT:    ret void273;274entry:275  %outer = tail call ptr @llvm.objc.retain(ptr %a) nounwind276  %inner = tail call ptr @llvm.objc.retain(ptr %a) nounwind277  call void @callee()278  br label %loop279 280loop:281  br i1 %arg, label %true, label %more282 283true:284  call void @use_pointer(ptr %a)285  br label %more286 287more:288  br i1 %arg, label %exit, label %loop289 290exit:291  call void @llvm.objc.release(ptr %a) nounwind292  call void @llvm.objc.release(ptr %a) nounwind, !clang.imprecise_release !0293  ret void294}295 296define void @test8(ptr %a, i1 %arg) nounwind {297; CHECK-LABEL: @test8(298; CHECK-NEXT:  entry:299; CHECK-NEXT:    [[OUTER:%.*]] = tail call ptr @llvm.objc.retain(ptr [[A:%.*]]) #[[ATTR0]]300; CHECK-NEXT:    br label [[LOOP:%.*]]301; CHECK:       loop:302; CHECK-NEXT:    br i1 %arg, label [[TRUE:%.*]], label [[MORE:%.*]]303; CHECK:       true:304; CHECK-NEXT:    call void @callee()305; CHECK-NEXT:    call void @use_pointer(ptr [[A]])306; CHECK-NEXT:    br label [[MORE]]307; CHECK:       more:308; CHECK-NEXT:    br i1 %arg, label [[EXIT:%.*]], label [[LOOP]]309; CHECK:       exit:310; CHECK-NEXT:    call void @llvm.objc.release(ptr [[A]]) #[[ATTR0]], !clang.imprecise_release !0311; CHECK-NEXT:    ret void312;313entry:314  %outer = tail call ptr @llvm.objc.retain(ptr %a) nounwind315  %inner = tail call ptr @llvm.objc.retain(ptr %a) nounwind316  br label %loop317 318loop:319  br i1 %arg, label %true, label %more320 321true:322  call void @callee()323  call void @use_pointer(ptr %a)324  br label %more325 326more:327  br i1 %arg, label %exit, label %loop328 329exit:330  call void @llvm.objc.release(ptr %a) nounwind331  call void @llvm.objc.release(ptr %a) nounwind, !clang.imprecise_release !0332  ret void333}334 335define void @test9(ptr %a, i1 %arg) nounwind {336; CHECK-LABEL: @test9(337; CHECK-NEXT:  entry:338; CHECK-NEXT:    br label [[LOOP:%.*]]339; CHECK:       loop:340; CHECK-NEXT:    br i1 %arg, label [[TRUE:%.*]], label [[MORE:%.*]]341; CHECK:       true:342; CHECK-NEXT:    call void @use_pointer(ptr [[A:%.*]])343; CHECK-NEXT:    br label [[MORE]]344; CHECK:       more:345; CHECK-NEXT:    br i1 %arg, label [[EXIT:%.*]], label [[LOOP]]346; CHECK:       exit:347; CHECK-NEXT:    ret void348;349entry:350  %outer = tail call ptr @llvm.objc.retain(ptr %a) nounwind351  %inner = tail call ptr @llvm.objc.retain(ptr %a) nounwind352  br label %loop353 354loop:355  br i1 %arg, label %true, label %more356 357true:358  call void @use_pointer(ptr %a)359  br label %more360 361more:362  br i1 %arg, label %exit, label %loop363 364exit:365  call void @llvm.objc.release(ptr %a) nounwind366  call void @llvm.objc.release(ptr %a) nounwind, !clang.imprecise_release !0367  ret void368}369 370define void @test10(ptr %a, i1 %arg) nounwind {371; CHECK-LABEL: @test10(372; CHECK-NEXT:  entry:373; CHECK-NEXT:    br label [[LOOP:%.*]]374; CHECK:       loop:375; CHECK-NEXT:    br i1 %arg, label [[TRUE:%.*]], label [[MORE:%.*]]376; CHECK:       true:377; CHECK-NEXT:    call void @callee()378; CHECK-NEXT:    br label [[MORE]]379; CHECK:       more:380; CHECK-NEXT:    br i1 %arg, label [[EXIT:%.*]], label [[LOOP]]381; CHECK:       exit:382; CHECK-NEXT:    ret void383;384entry:385  %outer = tail call ptr @llvm.objc.retain(ptr %a) nounwind386  %inner = tail call ptr @llvm.objc.retain(ptr %a) nounwind387  br label %loop388 389loop:390  br i1 %arg, label %true, label %more391 392true:393  call void @callee()394  br label %more395 396more:397  br i1 %arg, label %exit, label %loop398 399exit:400  call void @llvm.objc.release(ptr %a) nounwind401  call void @llvm.objc.release(ptr %a) nounwind, !clang.imprecise_release !0402  ret void403}404 405define void @test11(ptr %a, i1 %arg) nounwind {406; CHECK-LABEL: @test11(407; CHECK-NEXT:  entry:408; CHECK-NEXT:    br label [[LOOP:%.*]]409; CHECK:       loop:410; CHECK-NEXT:    br i1 %arg, label [[TRUE:%.*]], label [[MORE:%.*]]411; CHECK:       true:412; CHECK-NEXT:    br label [[MORE]]413; CHECK:       more:414; CHECK-NEXT:    br i1 %arg, label [[EXIT:%.*]], label [[LOOP]]415; CHECK:       exit:416; CHECK-NEXT:    ret void417;418entry:419  %outer = tail call ptr @llvm.objc.retain(ptr %a) nounwind420  %inner = tail call ptr @llvm.objc.retain(ptr %a) nounwind421  br label %loop422 423loop:424  br i1 %arg, label %true, label %more425 426true:427  br label %more428 429more:430  br i1 %arg, label %exit, label %loop431 432exit:433  call void @llvm.objc.release(ptr %a) nounwind434  call void @llvm.objc.release(ptr %a) nounwind, !clang.imprecise_release !0435  ret void436}437 438; Don't delete anything if they're not balanced.439 440define void @test12(ptr %a, i1 %arg) nounwind {441; CHECK-LABEL: @test12(442; CHECK-NEXT:  entry:443; CHECK-NEXT:    [[OUTER:%.*]] = tail call ptr @llvm.objc.retain(ptr [[A:%.*]]) #[[ATTR0]]444; CHECK-NEXT:    [[INNER:%.*]] = tail call ptr @llvm.objc.retain(ptr [[A]]) #[[ATTR0]]445; CHECK-NEXT:    br label [[LOOP:%.*]]446; CHECK:       loop:447; CHECK-NEXT:    br i1 %arg, label [[TRUE:%.*]], label [[MORE:%.*]]448; CHECK:       true:449; CHECK-NEXT:    ret void450; CHECK:       more:451; CHECK-NEXT:    br i1 %arg, label [[EXIT:%.*]], label [[LOOP]]452; CHECK:       exit:453; CHECK-NEXT:    call void @llvm.objc.release(ptr [[A]]) #[[ATTR0]]454; CHECK-NEXT:    call void @llvm.objc.release(ptr [[A]]) #[[ATTR0]], !clang.imprecise_release !0455; CHECK-NEXT:    ret void456;457entry:458  %outer = tail call ptr @llvm.objc.retain(ptr %a) nounwind459  %inner = tail call ptr @llvm.objc.retain(ptr %a) nounwind460  br label %loop461 462loop:463  br i1 %arg, label %true, label %more464 465true:466  ret void467 468more:469  br i1 %arg, label %exit, label %loop470 471exit:472  call void @llvm.objc.release(ptr %a) nounwind473  call void @llvm.objc.release(ptr %a) nounwind, !clang.imprecise_release !0474  ret void475}476 477; Do not improperly pair retains in a for loop with releases outside of a for478; loop when the proper pairing is disguised by a separate provenance represented479; by an alloca.480; rdar://12969722481 482define void @test13(ptr %a, i1 %arg) nounwind {483; CHECK-LABEL: @test13(484; CHECK-NEXT:  entry:485; CHECK-NEXT:    [[BLOCK:%.*]] = alloca ptr, align 8486; CHECK-NEXT:    [[A1:%.*]] = tail call ptr @llvm.objc.retain(ptr [[A:%.*]]) #[[ATTR0]]487; CHECK-NEXT:    br label [[LOOP:%.*]]488; CHECK:       loop:489; CHECK-NEXT:    [[A2:%.*]] = tail call ptr @llvm.objc.retain(ptr [[A]]) #[[ATTR0]]490; CHECK-NEXT:    store ptr [[A]], ptr [[BLOCK]], align 8491; CHECK-NEXT:    call void @block_callee(ptr [[BLOCK]])492; CHECK-NEXT:    [[RELOADED_A:%.*]] = load ptr, ptr [[BLOCK]], align 8493; CHECK-NEXT:    call void @llvm.objc.release(ptr [[RELOADED_A]]) #[[ATTR0]], !clang.imprecise_release !0494; CHECK-NEXT:    br i1 %arg, label [[LOOP]], label [[EXIT:%.*]]495; CHECK:       exit:496; CHECK-NEXT:    call void @llvm.objc.release(ptr [[A]]) #[[ATTR0]], !clang.imprecise_release !0497; CHECK-NEXT:    ret void498;499entry:500  %block = alloca ptr501  %a1 = tail call ptr @llvm.objc.retain(ptr %a) nounwind502  br label %loop503 504loop:505  %a2 = tail call ptr @llvm.objc.retain(ptr %a) nounwind506  store ptr %a, ptr %block, align 8507  call void @block_callee(ptr %block)508  %reloaded_a = load ptr, ptr %block, align 8509  call void @llvm.objc.release(ptr %reloaded_a) nounwind, !clang.imprecise_release !0510  br i1 %arg, label %loop, label %exit511 512exit:513  call void @llvm.objc.release(ptr %a) nounwind, !clang.imprecise_release !0514  ret void515}516 517; The retain call in the entry block shouldn't be moved to the loop body.518 519define void @test14(ptr %val0, i8 %val1) {520; CHECK-LABEL: @test14(521; CHECK-NEXT:  entry:522; CHECK-NEXT:    [[V1:%.*]] = tail call ptr @llvm.objc.retain(ptr [[VAL0:%.*]]) #[[ATTR0]]523; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[VAL0]], null524; CHECK-NEXT:    br i1 [[CMP]], label [[IF_END27:%.*]], label [[IF_THEN:%.*]]525; CHECK:       if.then:526; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[VAL1:%.*]], 1527; CHECK-NEXT:    br label [[FOR_BODY:%.*]]528; CHECK:       for.cond:529; CHECK-NEXT:    [[CMP6:%.*]] = icmp eq i8 [[VAL1]], 2530; CHECK-NEXT:    br i1 [[CMP6]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]531; CHECK:       for.body:532; CHECK-NEXT:    call void @callee()533; CHECK-NEXT:    [[TOBOOL9:%.*]] = icmp eq i8 [[VAL1]], 0534; CHECK-NEXT:    br i1 [[TOBOOL9]], label [[FOR_COND:%.*]], label [[IF_THEN10:%.*]]535; CHECK:       if.then10:536; CHECK-NEXT:    br label [[FOR_END:%.*]]537; CHECK:       for.end.loopexit:538; CHECK-NEXT:    br label [[FOR_END]]539; CHECK:       for.end:540; CHECK-NEXT:    call void @callee()541; CHECK-NEXT:    call void @use_pointer(ptr [[V1]])542; CHECK-NEXT:    br label [[IF_END27]]543; CHECK:       if.end27:544; CHECK-NEXT:    call void @llvm.objc.release(ptr [[V1]]) #[[ATTR0]], !clang.imprecise_release !0545; CHECK-NEXT:    ret void546;547entry:548  %v1 = tail call ptr @llvm.objc.retain(ptr %val0)549  %cmp = icmp eq ptr %val0, null550  br i1 %cmp, label %if.end27, label %if.then551 552if.then:553  %tobool = icmp eq i8 %val1, 1554  br label %for.body555 556for.cond:557  %cmp6 = icmp eq i8 %val1, 2558  br i1 %cmp6, label %for.body, label %for.end.loopexit559 560for.body:561  call void @callee()562  %tobool9 = icmp eq i8 %val1, 0563  br i1 %tobool9, label %for.cond, label %if.then10564 565if.then10:566  br label %for.end567 568for.end.loopexit:569  br label %for.end570 571for.end:572  call void @callee()573  call void @use_pointer(ptr %v1)574  br label %if.end27575 576if.end27:577  call void @llvm.objc.release(ptr %v1) #0, !clang.imprecise_release !0578  ret void579}580 581 582!0 = !{}583