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