1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -objc-arc < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; rdar://9503416 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker; Detect loop boundaries and don't move retains and releases 5*9880d681SAndroid Build Coastguard Worker; across them. 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Workerdeclare void @use_pointer(i8*) 8*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retain(i8*) 9*9880d681SAndroid Build Coastguard Workerdeclare void @objc_release(i8*) 10*9880d681SAndroid Build Coastguard Workerdeclare void @callee() 11*9880d681SAndroid Build Coastguard Workerdeclare void @block_callee(void ()*) 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test0( 14*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain( 15*9880d681SAndroid Build Coastguard Worker; CHECK: for.body: 16*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc 17*9880d681SAndroid Build Coastguard Worker; CHECK: for.end: 18*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release( 19*9880d681SAndroid Build Coastguard Worker; CHECK: } 20*9880d681SAndroid Build Coastguard Workerdefine void @test0(i8* %digits) { 21*9880d681SAndroid Build Coastguard Workerentry: 22*9880d681SAndroid Build Coastguard Worker %tmp1 = call i8* @objc_retain(i8* %digits) nounwind 23*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %digits) 24*9880d681SAndroid Build Coastguard Worker br label %for.body 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 27*9880d681SAndroid Build Coastguard Worker %upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ] 28*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %digits) 29*9880d681SAndroid Build Coastguard Worker %inc = add i64 %upcDigitIndex.01, 1 30*9880d681SAndroid Build Coastguard Worker %cmp = icmp ult i64 %inc, 12 31*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.end 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 34*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %digits) nounwind, !clang.imprecise_release !0 35*9880d681SAndroid Build Coastguard Worker ret void 36*9880d681SAndroid Build Coastguard Worker} 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test1( 39*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain( 40*9880d681SAndroid Build Coastguard Worker; CHECK: for.body: 41*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc 42*9880d681SAndroid Build Coastguard Worker; CHECK: for.end: 43*9880d681SAndroid Build Coastguard Worker; CHECK: void @objc_release( 44*9880d681SAndroid Build Coastguard Worker; CHECK: } 45*9880d681SAndroid Build Coastguard Workerdefine void @test1(i8* %digits) { 46*9880d681SAndroid Build Coastguard Workerentry: 47*9880d681SAndroid Build Coastguard Worker %tmp1 = call i8* @objc_retain(i8* %digits) nounwind 48*9880d681SAndroid Build Coastguard Worker br label %for.body 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 51*9880d681SAndroid Build Coastguard Worker %upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ] 52*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %digits) 53*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %digits) 54*9880d681SAndroid Build Coastguard Worker %inc = add i64 %upcDigitIndex.01, 1 55*9880d681SAndroid Build Coastguard Worker %cmp = icmp ult i64 %inc, 12 56*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.end 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 59*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %digits) nounwind, !clang.imprecise_release !0 60*9880d681SAndroid Build Coastguard Worker ret void 61*9880d681SAndroid Build Coastguard Worker} 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test2( 64*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain( 65*9880d681SAndroid Build Coastguard Worker; CHECK: for.body: 66*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc 67*9880d681SAndroid Build Coastguard Worker; CHECK: for.end: 68*9880d681SAndroid Build Coastguard Worker; CHECK: void @objc_release( 69*9880d681SAndroid Build Coastguard Worker; CHECK: } 70*9880d681SAndroid Build Coastguard Workerdefine void @test2(i8* %digits) { 71*9880d681SAndroid Build Coastguard Workerentry: 72*9880d681SAndroid Build Coastguard Worker %tmp1 = call i8* @objc_retain(i8* %digits) nounwind 73*9880d681SAndroid Build Coastguard Worker br label %for.body 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 76*9880d681SAndroid Build Coastguard Worker %upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ] 77*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %digits) 78*9880d681SAndroid Build Coastguard Worker %inc = add i64 %upcDigitIndex.01, 1 79*9880d681SAndroid Build Coastguard Worker %cmp = icmp ult i64 %inc, 12 80*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.end 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 83*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %digits) 84*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %digits) nounwind, !clang.imprecise_release !0 85*9880d681SAndroid Build Coastguard Worker ret void 86*9880d681SAndroid Build Coastguard Worker} 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker; Delete nested retain+release pairs around loops. 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test3(i8* %a) #0 { 91*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 92*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) [[NUW:#[0-9]+]] 93*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop 94*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 95*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 96*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %a) 97*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 98*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 99*9880d681SAndroid Build Coastguard Workerdefine void @test3(i8* %a) nounwind { 100*9880d681SAndroid Build Coastguard Workerentry: 101*9880d681SAndroid Build Coastguard Worker %outer = call i8* @objc_retain(i8* %a) nounwind 102*9880d681SAndroid Build Coastguard Worker %inner = call i8* @objc_retain(i8* %a) nounwind 103*9880d681SAndroid Build Coastguard Worker br label %loop 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Workerloop: 106*9880d681SAndroid Build Coastguard Worker call void @callee() 107*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %a 108*9880d681SAndroid Build Coastguard Worker br i1 undef, label %loop, label %exit 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Workerexit: 111*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind 112*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 113*9880d681SAndroid Build Coastguard Worker ret void 114*9880d681SAndroid Build Coastguard Worker} 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test4(i8* %a) #0 { 117*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 118*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) [[NUW]] 119*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop 120*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 121*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 122*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %a) 123*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 124*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 125*9880d681SAndroid Build Coastguard Workerdefine void @test4(i8* %a) nounwind { 126*9880d681SAndroid Build Coastguard Workerentry: 127*9880d681SAndroid Build Coastguard Worker %outer = call i8* @objc_retain(i8* %a) nounwind 128*9880d681SAndroid Build Coastguard Worker %inner = call i8* @objc_retain(i8* %a) nounwind 129*9880d681SAndroid Build Coastguard Worker br label %loop 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard Workerloop: 132*9880d681SAndroid Build Coastguard Worker br label %more 133*9880d681SAndroid Build Coastguard Worker 134*9880d681SAndroid Build Coastguard Workermore: 135*9880d681SAndroid Build Coastguard Worker call void @callee() 136*9880d681SAndroid Build Coastguard Worker call void @callee() 137*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %a 138*9880d681SAndroid Build Coastguard Worker br i1 undef, label %loop, label %exit 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Workerexit: 141*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind 142*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 143*9880d681SAndroid Build Coastguard Worker ret void 144*9880d681SAndroid Build Coastguard Worker} 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test5(i8* %a) #0 { 147*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 148*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) [[NUW]] 149*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @callee() 150*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop 151*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 152*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 153*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %a) 154*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %a) 155*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 156*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 157*9880d681SAndroid Build Coastguard Workerdefine void @test5(i8* %a) nounwind { 158*9880d681SAndroid Build Coastguard Workerentry: 159*9880d681SAndroid Build Coastguard Worker %outer = tail call i8* @objc_retain(i8* %a) nounwind 160*9880d681SAndroid Build Coastguard Worker %inner = tail call i8* @objc_retain(i8* %a) nounwind 161*9880d681SAndroid Build Coastguard Worker call void @callee() 162*9880d681SAndroid Build Coastguard Worker br label %loop 163*9880d681SAndroid Build Coastguard Worker 164*9880d681SAndroid Build Coastguard Workerloop: 165*9880d681SAndroid Build Coastguard Worker br i1 undef, label %true, label %more 166*9880d681SAndroid Build Coastguard Worker 167*9880d681SAndroid Build Coastguard Workertrue: 168*9880d681SAndroid Build Coastguard Worker br label %more 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Workermore: 171*9880d681SAndroid Build Coastguard Worker br i1 undef, label %exit, label %loop 172*9880d681SAndroid Build Coastguard Worker 173*9880d681SAndroid Build Coastguard Workerexit: 174*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %a) 175*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind 176*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 177*9880d681SAndroid Build Coastguard Worker ret void 178*9880d681SAndroid Build Coastguard Worker} 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test6(i8* %a) #0 { 181*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 182*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) [[NUW]] 183*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop 184*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 185*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 186*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %a) 187*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %a) 188*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 189*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 190*9880d681SAndroid Build Coastguard Workerdefine void @test6(i8* %a) nounwind { 191*9880d681SAndroid Build Coastguard Workerentry: 192*9880d681SAndroid Build Coastguard Worker %outer = tail call i8* @objc_retain(i8* %a) nounwind 193*9880d681SAndroid Build Coastguard Worker %inner = tail call i8* @objc_retain(i8* %a) nounwind 194*9880d681SAndroid Build Coastguard Worker br label %loop 195*9880d681SAndroid Build Coastguard Worker 196*9880d681SAndroid Build Coastguard Workerloop: 197*9880d681SAndroid Build Coastguard Worker br i1 undef, label %true, label %more 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Workertrue: 200*9880d681SAndroid Build Coastguard Worker call void @callee() 201*9880d681SAndroid Build Coastguard Worker br label %more 202*9880d681SAndroid Build Coastguard Worker 203*9880d681SAndroid Build Coastguard Workermore: 204*9880d681SAndroid Build Coastguard Worker br i1 undef, label %exit, label %loop 205*9880d681SAndroid Build Coastguard Worker 206*9880d681SAndroid Build Coastguard Workerexit: 207*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %a) 208*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind 209*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 210*9880d681SAndroid Build Coastguard Worker ret void 211*9880d681SAndroid Build Coastguard Worker} 212*9880d681SAndroid Build Coastguard Worker 213*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test7(i8* %a) #0 { 214*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 215*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) [[NUW]] 216*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @callee() 217*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop 218*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 219*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 220*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %a) 221*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 222*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 223*9880d681SAndroid Build Coastguard Workerdefine void @test7(i8* %a) nounwind { 224*9880d681SAndroid Build Coastguard Workerentry: 225*9880d681SAndroid Build Coastguard Worker %outer = tail call i8* @objc_retain(i8* %a) nounwind 226*9880d681SAndroid Build Coastguard Worker %inner = tail call i8* @objc_retain(i8* %a) nounwind 227*9880d681SAndroid Build Coastguard Worker call void @callee() 228*9880d681SAndroid Build Coastguard Worker br label %loop 229*9880d681SAndroid Build Coastguard Worker 230*9880d681SAndroid Build Coastguard Workerloop: 231*9880d681SAndroid Build Coastguard Worker br i1 undef, label %true, label %more 232*9880d681SAndroid Build Coastguard Worker 233*9880d681SAndroid Build Coastguard Workertrue: 234*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %a) 235*9880d681SAndroid Build Coastguard Worker br label %more 236*9880d681SAndroid Build Coastguard Worker 237*9880d681SAndroid Build Coastguard Workermore: 238*9880d681SAndroid Build Coastguard Worker br i1 undef, label %exit, label %loop 239*9880d681SAndroid Build Coastguard Worker 240*9880d681SAndroid Build Coastguard Workerexit: 241*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind 242*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 243*9880d681SAndroid Build Coastguard Worker ret void 244*9880d681SAndroid Build Coastguard Worker} 245*9880d681SAndroid Build Coastguard Worker 246*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test8(i8* %a) #0 { 247*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 248*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) [[NUW]] 249*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop 250*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 251*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 252*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %a) 253*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 254*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 255*9880d681SAndroid Build Coastguard Workerdefine void @test8(i8* %a) nounwind { 256*9880d681SAndroid Build Coastguard Workerentry: 257*9880d681SAndroid Build Coastguard Worker %outer = tail call i8* @objc_retain(i8* %a) nounwind 258*9880d681SAndroid Build Coastguard Worker %inner = tail call i8* @objc_retain(i8* %a) nounwind 259*9880d681SAndroid Build Coastguard Worker br label %loop 260*9880d681SAndroid Build Coastguard Worker 261*9880d681SAndroid Build Coastguard Workerloop: 262*9880d681SAndroid Build Coastguard Worker br i1 undef, label %true, label %more 263*9880d681SAndroid Build Coastguard Worker 264*9880d681SAndroid Build Coastguard Workertrue: 265*9880d681SAndroid Build Coastguard Worker call void @callee() 266*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %a) 267*9880d681SAndroid Build Coastguard Worker br label %more 268*9880d681SAndroid Build Coastguard Worker 269*9880d681SAndroid Build Coastguard Workermore: 270*9880d681SAndroid Build Coastguard Worker br i1 undef, label %exit, label %loop 271*9880d681SAndroid Build Coastguard Worker 272*9880d681SAndroid Build Coastguard Workerexit: 273*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind 274*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 275*9880d681SAndroid Build Coastguard Worker ret void 276*9880d681SAndroid Build Coastguard Worker} 277*9880d681SAndroid Build Coastguard Worker 278*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test9(i8* %a) #0 { 279*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 280*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop 281*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 282*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 283*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 284*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 285*9880d681SAndroid Build Coastguard Workerdefine void @test9(i8* %a) nounwind { 286*9880d681SAndroid Build Coastguard Workerentry: 287*9880d681SAndroid Build Coastguard Worker %outer = tail call i8* @objc_retain(i8* %a) nounwind 288*9880d681SAndroid Build Coastguard Worker %inner = tail call i8* @objc_retain(i8* %a) nounwind 289*9880d681SAndroid Build Coastguard Worker br label %loop 290*9880d681SAndroid Build Coastguard Worker 291*9880d681SAndroid Build Coastguard Workerloop: 292*9880d681SAndroid Build Coastguard Worker br i1 undef, label %true, label %more 293*9880d681SAndroid Build Coastguard Worker 294*9880d681SAndroid Build Coastguard Workertrue: 295*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %a) 296*9880d681SAndroid Build Coastguard Worker br label %more 297*9880d681SAndroid Build Coastguard Worker 298*9880d681SAndroid Build Coastguard Workermore: 299*9880d681SAndroid Build Coastguard Worker br i1 undef, label %exit, label %loop 300*9880d681SAndroid Build Coastguard Worker 301*9880d681SAndroid Build Coastguard Workerexit: 302*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind 303*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 304*9880d681SAndroid Build Coastguard Worker ret void 305*9880d681SAndroid Build Coastguard Worker} 306*9880d681SAndroid Build Coastguard Worker 307*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test10(i8* %a) #0 { 308*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 309*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop 310*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 311*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 312*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 313*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 314*9880d681SAndroid Build Coastguard Workerdefine void @test10(i8* %a) nounwind { 315*9880d681SAndroid Build Coastguard Workerentry: 316*9880d681SAndroid Build Coastguard Worker %outer = tail call i8* @objc_retain(i8* %a) nounwind 317*9880d681SAndroid Build Coastguard Worker %inner = tail call i8* @objc_retain(i8* %a) nounwind 318*9880d681SAndroid Build Coastguard Worker br label %loop 319*9880d681SAndroid Build Coastguard Worker 320*9880d681SAndroid Build Coastguard Workerloop: 321*9880d681SAndroid Build Coastguard Worker br i1 undef, label %true, label %more 322*9880d681SAndroid Build Coastguard Worker 323*9880d681SAndroid Build Coastguard Workertrue: 324*9880d681SAndroid Build Coastguard Worker call void @callee() 325*9880d681SAndroid Build Coastguard Worker br label %more 326*9880d681SAndroid Build Coastguard Worker 327*9880d681SAndroid Build Coastguard Workermore: 328*9880d681SAndroid Build Coastguard Worker br i1 undef, label %exit, label %loop 329*9880d681SAndroid Build Coastguard Worker 330*9880d681SAndroid Build Coastguard Workerexit: 331*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind 332*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 333*9880d681SAndroid Build Coastguard Worker ret void 334*9880d681SAndroid Build Coastguard Worker} 335*9880d681SAndroid Build Coastguard Worker 336*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test11(i8* %a) #0 { 337*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 338*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop 339*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 340*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 341*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 342*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 343*9880d681SAndroid Build Coastguard Workerdefine void @test11(i8* %a) nounwind { 344*9880d681SAndroid Build Coastguard Workerentry: 345*9880d681SAndroid Build Coastguard Worker %outer = tail call i8* @objc_retain(i8* %a) nounwind 346*9880d681SAndroid Build Coastguard Worker %inner = tail call i8* @objc_retain(i8* %a) nounwind 347*9880d681SAndroid Build Coastguard Worker br label %loop 348*9880d681SAndroid Build Coastguard Worker 349*9880d681SAndroid Build Coastguard Workerloop: 350*9880d681SAndroid Build Coastguard Worker br i1 undef, label %true, label %more 351*9880d681SAndroid Build Coastguard Worker 352*9880d681SAndroid Build Coastguard Workertrue: 353*9880d681SAndroid Build Coastguard Worker br label %more 354*9880d681SAndroid Build Coastguard Worker 355*9880d681SAndroid Build Coastguard Workermore: 356*9880d681SAndroid Build Coastguard Worker br i1 undef, label %exit, label %loop 357*9880d681SAndroid Build Coastguard Worker 358*9880d681SAndroid Build Coastguard Workerexit: 359*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind 360*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 361*9880d681SAndroid Build Coastguard Worker ret void 362*9880d681SAndroid Build Coastguard Worker} 363*9880d681SAndroid Build Coastguard Worker 364*9880d681SAndroid Build Coastguard Worker; Don't delete anything if they're not balanced. 365*9880d681SAndroid Build Coastguard Worker 366*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test12(i8* %a) #0 { 367*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 368*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %outer = tail call i8* @objc_retain(i8* %a) [[NUW]] 369*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %inner = tail call i8* @objc_retain(i8* %a) [[NUW]] 370*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop 371*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 372*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 373*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %a) [[NUW]] 374*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %a) [[NUW]], !clang.imprecise_release !0 375*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 376*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 377*9880d681SAndroid Build Coastguard Workerdefine void @test12(i8* %a) nounwind { 378*9880d681SAndroid Build Coastguard Workerentry: 379*9880d681SAndroid Build Coastguard Worker %outer = tail call i8* @objc_retain(i8* %a) nounwind 380*9880d681SAndroid Build Coastguard Worker %inner = tail call i8* @objc_retain(i8* %a) nounwind 381*9880d681SAndroid Build Coastguard Worker br label %loop 382*9880d681SAndroid Build Coastguard Worker 383*9880d681SAndroid Build Coastguard Workerloop: 384*9880d681SAndroid Build Coastguard Worker br i1 undef, label %true, label %more 385*9880d681SAndroid Build Coastguard Worker 386*9880d681SAndroid Build Coastguard Workertrue: 387*9880d681SAndroid Build Coastguard Worker ret void 388*9880d681SAndroid Build Coastguard Worker 389*9880d681SAndroid Build Coastguard Workermore: 390*9880d681SAndroid Build Coastguard Worker br i1 undef, label %exit, label %loop 391*9880d681SAndroid Build Coastguard Worker 392*9880d681SAndroid Build Coastguard Workerexit: 393*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind 394*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 395*9880d681SAndroid Build Coastguard Worker ret void 396*9880d681SAndroid Build Coastguard Worker} 397*9880d681SAndroid Build Coastguard Worker 398*9880d681SAndroid Build Coastguard Worker; Do not improperly pair retains in a for loop with releases outside of a for 399*9880d681SAndroid Build Coastguard Worker; loop when the proper pairing is disguised by a separate provenance represented 400*9880d681SAndroid Build Coastguard Worker; by an alloca. 401*9880d681SAndroid Build Coastguard Worker; rdar://12969722 402*9880d681SAndroid Build Coastguard Worker 403*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test13(i8* %a) [[NUW]] { 404*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 405*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %a) [[NUW]] 406*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 407*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %a) [[NUW]] 408*9880d681SAndroid Build Coastguard Worker; CHECK: call void @block_callee 409*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %reloaded_a) [[NUW]] 410*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 411*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %a) [[NUW]] 412*9880d681SAndroid Build Coastguard Worker; CHECK: } 413*9880d681SAndroid Build Coastguard Workerdefine void @test13(i8* %a) nounwind { 414*9880d681SAndroid Build Coastguard Workerentry: 415*9880d681SAndroid Build Coastguard Worker %block = alloca i8* 416*9880d681SAndroid Build Coastguard Worker %a1 = tail call i8* @objc_retain(i8* %a) nounwind 417*9880d681SAndroid Build Coastguard Worker br label %loop 418*9880d681SAndroid Build Coastguard Worker 419*9880d681SAndroid Build Coastguard Workerloop: 420*9880d681SAndroid Build Coastguard Worker %a2 = tail call i8* @objc_retain(i8* %a) nounwind 421*9880d681SAndroid Build Coastguard Worker store i8* %a, i8** %block, align 8 422*9880d681SAndroid Build Coastguard Worker %casted_block = bitcast i8** %block to void ()* 423*9880d681SAndroid Build Coastguard Worker call void @block_callee(void ()* %casted_block) 424*9880d681SAndroid Build Coastguard Worker %reloaded_a = load i8*, i8** %block, align 8 425*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %reloaded_a) nounwind, !clang.imprecise_release !0 426*9880d681SAndroid Build Coastguard Worker br i1 undef, label %loop, label %exit 427*9880d681SAndroid Build Coastguard Worker 428*9880d681SAndroid Build Coastguard Workerexit: 429*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 430*9880d681SAndroid Build Coastguard Worker ret void 431*9880d681SAndroid Build Coastguard Worker} 432*9880d681SAndroid Build Coastguard Worker 433*9880d681SAndroid Build Coastguard Worker; CHECK: attributes [[NUW]] = { nounwind } 434*9880d681SAndroid Build Coastguard Worker 435*9880d681SAndroid Build Coastguard Worker!0 = !{} 436