1*9880d681SAndroid Build Coastguard Worker; RUN: opt -basicaa -objc-arc -S < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-p:64:64:64" 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retain(i8*) 6*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainAutoreleasedReturnValue(i8*) 7*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_unsafeClaimAutoreleasedReturnValue(i8*) 8*9880d681SAndroid Build Coastguard Workerdeclare void @objc_release(i8*) 9*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_autorelease(i8*) 10*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_autoreleaseReturnValue(i8*) 11*9880d681SAndroid Build Coastguard Workerdeclare void @objc_autoreleasePoolPop(i8*) 12*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_autoreleasePoolPush() 13*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainBlock(i8*) 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainedObject(i8*) 16*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_unretainedObject(i8*) 17*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_unretainedPointer(i8*) 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Workerdeclare void @use_pointer(i8*) 20*9880d681SAndroid Build Coastguard Workerdeclare void @callee() 21*9880d681SAndroid Build Coastguard Workerdeclare void @callee_fnptr(void ()*) 22*9880d681SAndroid Build Coastguard Workerdeclare void @invokee() 23*9880d681SAndroid Build Coastguard Workerdeclare i8* @returner() 24*9880d681SAndroid Build Coastguard Workerdeclare void @bar(i32 ()*) 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.dbg.value(metadata, i64, metadata, metadata) 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_msgSend(i8*, i8*, ...) 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker; Simple retain+release pair deletion, with some intervening control 31*9880d681SAndroid Build Coastguard Worker; flow and harmless instructions. 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test0_precise(i32* %x, i1 %p) [[NUW:#[0-9]+]] { 34*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 35*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 36*9880d681SAndroid Build Coastguard Worker; CHECK: } 37*9880d681SAndroid Build Coastguard Workerdefine void @test0_precise(i32* %x, i1 %p) nounwind { 38*9880d681SAndroid Build Coastguard Workerentry: 39*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 40*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 41*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Workert: 44*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 45*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 46*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 47*9880d681SAndroid Build Coastguard Worker br label %return 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Workerf: 50*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 51*9880d681SAndroid Build Coastguard Worker br label %return 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Workerreturn: 54*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 55*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind 56*9880d681SAndroid Build Coastguard Worker ret void 57*9880d681SAndroid Build Coastguard Worker} 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test0_imprecise(i32* %x, i1 %p) [[NUW]] { 60*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 61*9880d681SAndroid Build Coastguard Worker; CHECK: } 62*9880d681SAndroid Build Coastguard Workerdefine void @test0_imprecise(i32* %x, i1 %p) nounwind { 63*9880d681SAndroid Build Coastguard Workerentry: 64*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 65*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 66*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Workert: 69*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 70*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 71*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 72*9880d681SAndroid Build Coastguard Worker br label %return 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Workerf: 75*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 76*9880d681SAndroid Build Coastguard Worker br label %return 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Workerreturn: 79*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 80*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0 81*9880d681SAndroid Build Coastguard Worker ret void 82*9880d681SAndroid Build Coastguard Worker} 83*9880d681SAndroid Build Coastguard Worker 84*9880d681SAndroid Build Coastguard Worker; Like test0 but the release isn't always executed when the retain is, 85*9880d681SAndroid Build Coastguard Worker; so the optimization is not safe. 86*9880d681SAndroid Build Coastguard Worker 87*9880d681SAndroid Build Coastguard Worker; TODO: Make the objc_release's argument be %0. 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1_precise(i32* %x, i1 %p, i1 %q) [[NUW]] { 90*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %a) 91*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 92*9880d681SAndroid Build Coastguard Worker; CHECK: } 93*9880d681SAndroid Build Coastguard Workerdefine void @test1_precise(i32* %x, i1 %p, i1 %q) nounwind { 94*9880d681SAndroid Build Coastguard Workerentry: 95*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 96*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 97*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 98*9880d681SAndroid Build Coastguard Worker 99*9880d681SAndroid Build Coastguard Workert: 100*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 101*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 102*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 103*9880d681SAndroid Build Coastguard Worker br label %return 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Workerf: 106*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 107*9880d681SAndroid Build Coastguard Worker call void @callee() 108*9880d681SAndroid Build Coastguard Worker br i1 %q, label %return, label %alt_return 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Workerreturn: 111*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 112*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind 113*9880d681SAndroid Build Coastguard Worker ret void 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Workeralt_return: 116*9880d681SAndroid Build Coastguard Worker ret void 117*9880d681SAndroid Build Coastguard Worker} 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1_imprecise(i32* %x, i1 %p, i1 %q) [[NUW]] { 120*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %a) 121*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 122*9880d681SAndroid Build Coastguard Worker; CHECK: } 123*9880d681SAndroid Build Coastguard Workerdefine void @test1_imprecise(i32* %x, i1 %p, i1 %q) nounwind { 124*9880d681SAndroid Build Coastguard Workerentry: 125*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 126*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 127*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Workert: 130*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 131*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 132*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 133*9880d681SAndroid Build Coastguard Worker br label %return 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Workerf: 136*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 137*9880d681SAndroid Build Coastguard Worker call void @callee() 138*9880d681SAndroid Build Coastguard Worker br i1 %q, label %return, label %alt_return 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Workerreturn: 141*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 142*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0 143*9880d681SAndroid Build Coastguard Worker ret void 144*9880d681SAndroid Build Coastguard Worker 145*9880d681SAndroid Build Coastguard Workeralt_return: 146*9880d681SAndroid Build Coastguard Worker ret void 147*9880d681SAndroid Build Coastguard Worker} 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Worker; Don't do partial elimination into two different CFG diamonds. 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1b_precise(i8* %x, i1 %p, i1 %q) { 153*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 154*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]] 155*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 156*9880d681SAndroid Build Coastguard Worker; CHECK: if.end5: 157*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @objc_release(i8* %x) [[NUW]] 158*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 159*9880d681SAndroid Build Coastguard Worker; CHECK: } 160*9880d681SAndroid Build Coastguard Workerdefine void @test1b_precise(i8* %x, i1 %p, i1 %q) { 161*9880d681SAndroid Build Coastguard Workerentry: 162*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) nounwind 163*9880d681SAndroid Build Coastguard Worker br i1 %p, label %if.then, label %if.end 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 166*9880d681SAndroid Build Coastguard Worker tail call void @callee() 167*9880d681SAndroid Build Coastguard Worker br label %if.end 168*9880d681SAndroid Build Coastguard Worker 169*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.then, %entry 170*9880d681SAndroid Build Coastguard Worker br i1 %q, label %if.then3, label %if.end5 171*9880d681SAndroid Build Coastguard Worker 172*9880d681SAndroid Build Coastguard Workerif.then3: ; preds = %if.end 173*9880d681SAndroid Build Coastguard Worker tail call void @use_pointer(i8* %x) 174*9880d681SAndroid Build Coastguard Worker br label %if.end5 175*9880d681SAndroid Build Coastguard Worker 176*9880d681SAndroid Build Coastguard Workerif.end5: ; preds = %if.then3, %if.end 177*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %x) nounwind 178*9880d681SAndroid Build Coastguard Worker ret void 179*9880d681SAndroid Build Coastguard Worker} 180*9880d681SAndroid Build Coastguard Worker 181*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test1b_imprecise( 182*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 183*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW:#[0-9]+]] 184*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 185*9880d681SAndroid Build Coastguard Worker; CHECK: if.end5: 186*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @objc_release(i8* %x) [[NUW]], !clang.imprecise_release ![[RELEASE:[0-9]+]] 187*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 188*9880d681SAndroid Build Coastguard Worker; CHECK: } 189*9880d681SAndroid Build Coastguard Workerdefine void @test1b_imprecise(i8* %x, i1 %p, i1 %q) { 190*9880d681SAndroid Build Coastguard Workerentry: 191*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) nounwind 192*9880d681SAndroid Build Coastguard Worker br i1 %p, label %if.then, label %if.end 193*9880d681SAndroid Build Coastguard Worker 194*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 195*9880d681SAndroid Build Coastguard Worker tail call void @callee() 196*9880d681SAndroid Build Coastguard Worker br label %if.end 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.then, %entry 199*9880d681SAndroid Build Coastguard Worker br i1 %q, label %if.then3, label %if.end5 200*9880d681SAndroid Build Coastguard Worker 201*9880d681SAndroid Build Coastguard Workerif.then3: ; preds = %if.end 202*9880d681SAndroid Build Coastguard Worker tail call void @use_pointer(i8* %x) 203*9880d681SAndroid Build Coastguard Worker br label %if.end5 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Workerif.end5: ; preds = %if.then3, %if.end 206*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 207*9880d681SAndroid Build Coastguard Worker ret void 208*9880d681SAndroid Build Coastguard Worker} 209*9880d681SAndroid Build Coastguard Worker 210*9880d681SAndroid Build Coastguard Worker 211*9880d681SAndroid Build Coastguard Worker; Like test0 but the pointer is passed to an intervening call, 212*9880d681SAndroid Build Coastguard Worker; so the optimization is not safe. 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test2_precise( 215*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %a) 216*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 217*9880d681SAndroid Build Coastguard Worker; CHECK: } 218*9880d681SAndroid Build Coastguard Workerdefine void @test2_precise(i32* %x, i1 %p) nounwind { 219*9880d681SAndroid Build Coastguard Workerentry: 220*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 221*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 222*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 223*9880d681SAndroid Build Coastguard Worker 224*9880d681SAndroid Build Coastguard Workert: 225*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 226*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 227*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 228*9880d681SAndroid Build Coastguard Worker br label %return 229*9880d681SAndroid Build Coastguard Worker 230*9880d681SAndroid Build Coastguard Workerf: 231*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 232*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %0) 233*9880d681SAndroid Build Coastguard Worker %d = bitcast i32* %x to float* 234*9880d681SAndroid Build Coastguard Worker store float 3.0, float* %d 235*9880d681SAndroid Build Coastguard Worker br label %return 236*9880d681SAndroid Build Coastguard Worker 237*9880d681SAndroid Build Coastguard Workerreturn: 238*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 239*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind 240*9880d681SAndroid Build Coastguard Worker ret void 241*9880d681SAndroid Build Coastguard Worker} 242*9880d681SAndroid Build Coastguard Worker 243*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test2_imprecise( 244*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %a) 245*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 246*9880d681SAndroid Build Coastguard Worker; CHECK: } 247*9880d681SAndroid Build Coastguard Workerdefine void @test2_imprecise(i32* %x, i1 %p) nounwind { 248*9880d681SAndroid Build Coastguard Workerentry: 249*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 250*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 251*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 252*9880d681SAndroid Build Coastguard Worker 253*9880d681SAndroid Build Coastguard Workert: 254*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 255*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 256*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 257*9880d681SAndroid Build Coastguard Worker br label %return 258*9880d681SAndroid Build Coastguard Worker 259*9880d681SAndroid Build Coastguard Workerf: 260*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 261*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %0) 262*9880d681SAndroid Build Coastguard Worker %d = bitcast i32* %x to float* 263*9880d681SAndroid Build Coastguard Worker store float 3.0, float* %d 264*9880d681SAndroid Build Coastguard Worker br label %return 265*9880d681SAndroid Build Coastguard Worker 266*9880d681SAndroid Build Coastguard Workerreturn: 267*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 268*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0 269*9880d681SAndroid Build Coastguard Worker ret void 270*9880d681SAndroid Build Coastguard Worker} 271*9880d681SAndroid Build Coastguard Worker 272*9880d681SAndroid Build Coastguard Worker; Like test0 but the release is in a loop, 273*9880d681SAndroid Build Coastguard Worker; so the optimization is not safe. 274*9880d681SAndroid Build Coastguard Worker 275*9880d681SAndroid Build Coastguard Worker; TODO: For now, assume this can't happen. 276*9880d681SAndroid Build Coastguard Worker 277*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test3_precise( 278*9880d681SAndroid Build Coastguard Worker; TODO: @objc_retain(i8* %a) 279*9880d681SAndroid Build Coastguard Worker; TODO: @objc_release 280*9880d681SAndroid Build Coastguard Worker; CHECK: } 281*9880d681SAndroid Build Coastguard Workerdefine void @test3_precise(i32* %x, i1* %q) nounwind { 282*9880d681SAndroid Build Coastguard Workerentry: 283*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 284*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 285*9880d681SAndroid Build Coastguard Worker br label %loop 286*9880d681SAndroid Build Coastguard Worker 287*9880d681SAndroid Build Coastguard Workerloop: 288*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 289*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind 290*9880d681SAndroid Build Coastguard Worker %j = load volatile i1, i1* %q 291*9880d681SAndroid Build Coastguard Worker br i1 %j, label %loop, label %return 292*9880d681SAndroid Build Coastguard Worker 293*9880d681SAndroid Build Coastguard Workerreturn: 294*9880d681SAndroid Build Coastguard Worker ret void 295*9880d681SAndroid Build Coastguard Worker} 296*9880d681SAndroid Build Coastguard Worker 297*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test3_imprecise( 298*9880d681SAndroid Build Coastguard Worker; TODO: @objc_retain(i8* %a) 299*9880d681SAndroid Build Coastguard Worker; TODO: @objc_release 300*9880d681SAndroid Build Coastguard Worker; CHECK: } 301*9880d681SAndroid Build Coastguard Workerdefine void @test3_imprecise(i32* %x, i1* %q) nounwind { 302*9880d681SAndroid Build Coastguard Workerentry: 303*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 304*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 305*9880d681SAndroid Build Coastguard Worker br label %loop 306*9880d681SAndroid Build Coastguard Worker 307*9880d681SAndroid Build Coastguard Workerloop: 308*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 309*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0 310*9880d681SAndroid Build Coastguard Worker %j = load volatile i1, i1* %q 311*9880d681SAndroid Build Coastguard Worker br i1 %j, label %loop, label %return 312*9880d681SAndroid Build Coastguard Worker 313*9880d681SAndroid Build Coastguard Workerreturn: 314*9880d681SAndroid Build Coastguard Worker ret void 315*9880d681SAndroid Build Coastguard Worker} 316*9880d681SAndroid Build Coastguard Worker 317*9880d681SAndroid Build Coastguard Worker 318*9880d681SAndroid Build Coastguard Worker; TODO: For now, assume this can't happen. 319*9880d681SAndroid Build Coastguard Worker 320*9880d681SAndroid Build Coastguard Worker; Like test0 but the retain is in a loop, 321*9880d681SAndroid Build Coastguard Worker; so the optimization is not safe. 322*9880d681SAndroid Build Coastguard Worker 323*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test4_precise( 324*9880d681SAndroid Build Coastguard Worker; TODO: @objc_retain(i8* %a) 325*9880d681SAndroid Build Coastguard Worker; TODO: @objc_release 326*9880d681SAndroid Build Coastguard Worker; CHECK: } 327*9880d681SAndroid Build Coastguard Workerdefine void @test4_precise(i32* %x, i1* %q) nounwind { 328*9880d681SAndroid Build Coastguard Workerentry: 329*9880d681SAndroid Build Coastguard Worker br label %loop 330*9880d681SAndroid Build Coastguard Worker 331*9880d681SAndroid Build Coastguard Workerloop: 332*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 333*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 334*9880d681SAndroid Build Coastguard Worker %j = load volatile i1, i1* %q 335*9880d681SAndroid Build Coastguard Worker br i1 %j, label %loop, label %return 336*9880d681SAndroid Build Coastguard Worker 337*9880d681SAndroid Build Coastguard Workerreturn: 338*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 339*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind 340*9880d681SAndroid Build Coastguard Worker ret void 341*9880d681SAndroid Build Coastguard Worker} 342*9880d681SAndroid Build Coastguard Worker 343*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test4_imprecise( 344*9880d681SAndroid Build Coastguard Worker; TODO: @objc_retain(i8* %a) 345*9880d681SAndroid Build Coastguard Worker; TODO: @objc_release 346*9880d681SAndroid Build Coastguard Worker; CHECK: } 347*9880d681SAndroid Build Coastguard Workerdefine void @test4_imprecise(i32* %x, i1* %q) nounwind { 348*9880d681SAndroid Build Coastguard Workerentry: 349*9880d681SAndroid Build Coastguard Worker br label %loop 350*9880d681SAndroid Build Coastguard Worker 351*9880d681SAndroid Build Coastguard Workerloop: 352*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 353*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 354*9880d681SAndroid Build Coastguard Worker %j = load volatile i1, i1* %q 355*9880d681SAndroid Build Coastguard Worker br i1 %j, label %loop, label %return 356*9880d681SAndroid Build Coastguard Worker 357*9880d681SAndroid Build Coastguard Workerreturn: 358*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 359*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0 360*9880d681SAndroid Build Coastguard Worker ret void 361*9880d681SAndroid Build Coastguard Worker} 362*9880d681SAndroid Build Coastguard Worker 363*9880d681SAndroid Build Coastguard Worker 364*9880d681SAndroid Build Coastguard Worker; Like test0 but the pointer is conditionally passed to an intervening call, 365*9880d681SAndroid Build Coastguard Worker; so the optimization is not safe. 366*9880d681SAndroid Build Coastguard Worker 367*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test5a( 368*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* 369*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 370*9880d681SAndroid Build Coastguard Worker; CHECK: } 371*9880d681SAndroid Build Coastguard Workerdefine void @test5a(i32* %x, i1 %q, i8* %y) nounwind { 372*9880d681SAndroid Build Coastguard Workerentry: 373*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 374*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 375*9880d681SAndroid Build Coastguard Worker %s = select i1 %q, i8* %y, i8* %0 376*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %s) 377*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 378*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 379*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind 380*9880d681SAndroid Build Coastguard Worker ret void 381*9880d681SAndroid Build Coastguard Worker} 382*9880d681SAndroid Build Coastguard Worker 383*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test5b( 384*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* 385*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 386*9880d681SAndroid Build Coastguard Worker; CHECK: } 387*9880d681SAndroid Build Coastguard Workerdefine void @test5b(i32* %x, i1 %q, i8* %y) nounwind { 388*9880d681SAndroid Build Coastguard Workerentry: 389*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 390*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 391*9880d681SAndroid Build Coastguard Worker %s = select i1 %q, i8* %y, i8* %0 392*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %s) 393*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 394*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 395*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0 396*9880d681SAndroid Build Coastguard Worker ret void 397*9880d681SAndroid Build Coastguard Worker} 398*9880d681SAndroid Build Coastguard Worker 399*9880d681SAndroid Build Coastguard Worker 400*9880d681SAndroid Build Coastguard Worker; retain+release pair deletion, where the release happens on two different 401*9880d681SAndroid Build Coastguard Worker; flow paths. 402*9880d681SAndroid Build Coastguard Worker 403*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test6a( 404*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 405*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain( 406*9880d681SAndroid Build Coastguard Worker; CHECK: t: 407*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release( 408*9880d681SAndroid Build Coastguard Worker; CHECK: f: 409*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release( 410*9880d681SAndroid Build Coastguard Worker; CHECK: return: 411*9880d681SAndroid Build Coastguard Worker; CHECK: } 412*9880d681SAndroid Build Coastguard Workerdefine void @test6a(i32* %x, i1 %p) nounwind { 413*9880d681SAndroid Build Coastguard Workerentry: 414*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 415*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 416*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 417*9880d681SAndroid Build Coastguard Worker 418*9880d681SAndroid Build Coastguard Workert: 419*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 420*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 421*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 422*9880d681SAndroid Build Coastguard Worker %ct = bitcast i32* %x to i8* 423*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %ct) nounwind 424*9880d681SAndroid Build Coastguard Worker br label %return 425*9880d681SAndroid Build Coastguard Worker 426*9880d681SAndroid Build Coastguard Workerf: 427*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 428*9880d681SAndroid Build Coastguard Worker call void @callee() 429*9880d681SAndroid Build Coastguard Worker %cf = bitcast i32* %x to i8* 430*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %cf) nounwind 431*9880d681SAndroid Build Coastguard Worker br label %return 432*9880d681SAndroid Build Coastguard Worker 433*9880d681SAndroid Build Coastguard Workerreturn: 434*9880d681SAndroid Build Coastguard Worker ret void 435*9880d681SAndroid Build Coastguard Worker} 436*9880d681SAndroid Build Coastguard Worker 437*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test6b( 438*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 439*9880d681SAndroid Build Coastguard Worker; CHECK: } 440*9880d681SAndroid Build Coastguard Workerdefine void @test6b(i32* %x, i1 %p) nounwind { 441*9880d681SAndroid Build Coastguard Workerentry: 442*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 443*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 444*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 445*9880d681SAndroid Build Coastguard Worker 446*9880d681SAndroid Build Coastguard Workert: 447*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 448*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 449*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 450*9880d681SAndroid Build Coastguard Worker %ct = bitcast i32* %x to i8* 451*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %ct) nounwind, !clang.imprecise_release !0 452*9880d681SAndroid Build Coastguard Worker br label %return 453*9880d681SAndroid Build Coastguard Worker 454*9880d681SAndroid Build Coastguard Workerf: 455*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 456*9880d681SAndroid Build Coastguard Worker call void @callee() 457*9880d681SAndroid Build Coastguard Worker %cf = bitcast i32* %x to i8* 458*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %cf) nounwind, !clang.imprecise_release !0 459*9880d681SAndroid Build Coastguard Worker br label %return 460*9880d681SAndroid Build Coastguard Worker 461*9880d681SAndroid Build Coastguard Workerreturn: 462*9880d681SAndroid Build Coastguard Worker ret void 463*9880d681SAndroid Build Coastguard Worker} 464*9880d681SAndroid Build Coastguard Worker 465*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test6c( 466*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 467*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain( 468*9880d681SAndroid Build Coastguard Worker; CHECK: t: 469*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release( 470*9880d681SAndroid Build Coastguard Worker; CHECK: f: 471*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release( 472*9880d681SAndroid Build Coastguard Worker; CHECK: return: 473*9880d681SAndroid Build Coastguard Worker; CHECK: } 474*9880d681SAndroid Build Coastguard Workerdefine void @test6c(i32* %x, i1 %p) nounwind { 475*9880d681SAndroid Build Coastguard Workerentry: 476*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 477*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 478*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 479*9880d681SAndroid Build Coastguard Worker 480*9880d681SAndroid Build Coastguard Workert: 481*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 482*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 483*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 484*9880d681SAndroid Build Coastguard Worker %ct = bitcast i32* %x to i8* 485*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %ct) nounwind 486*9880d681SAndroid Build Coastguard Worker br label %return 487*9880d681SAndroid Build Coastguard Worker 488*9880d681SAndroid Build Coastguard Workerf: 489*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 490*9880d681SAndroid Build Coastguard Worker call void @callee() 491*9880d681SAndroid Build Coastguard Worker %cf = bitcast i32* %x to i8* 492*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %cf) nounwind, !clang.imprecise_release !0 493*9880d681SAndroid Build Coastguard Worker br label %return 494*9880d681SAndroid Build Coastguard Worker 495*9880d681SAndroid Build Coastguard Workerreturn: 496*9880d681SAndroid Build Coastguard Worker ret void 497*9880d681SAndroid Build Coastguard Worker} 498*9880d681SAndroid Build Coastguard Worker 499*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test6d( 500*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 501*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain( 502*9880d681SAndroid Build Coastguard Worker; CHECK: t: 503*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release( 504*9880d681SAndroid Build Coastguard Worker; CHECK: f: 505*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release( 506*9880d681SAndroid Build Coastguard Worker; CHECK: return: 507*9880d681SAndroid Build Coastguard Worker; CHECK: } 508*9880d681SAndroid Build Coastguard Workerdefine void @test6d(i32* %x, i1 %p) nounwind { 509*9880d681SAndroid Build Coastguard Workerentry: 510*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 511*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 512*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 513*9880d681SAndroid Build Coastguard Worker 514*9880d681SAndroid Build Coastguard Workert: 515*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 516*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 517*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 518*9880d681SAndroid Build Coastguard Worker %ct = bitcast i32* %x to i8* 519*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %ct) nounwind, !clang.imprecise_release !0 520*9880d681SAndroid Build Coastguard Worker br label %return 521*9880d681SAndroid Build Coastguard Worker 522*9880d681SAndroid Build Coastguard Workerf: 523*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 524*9880d681SAndroid Build Coastguard Worker call void @callee() 525*9880d681SAndroid Build Coastguard Worker %cf = bitcast i32* %x to i8* 526*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %cf) nounwind 527*9880d681SAndroid Build Coastguard Worker br label %return 528*9880d681SAndroid Build Coastguard Worker 529*9880d681SAndroid Build Coastguard Workerreturn: 530*9880d681SAndroid Build Coastguard Worker ret void 531*9880d681SAndroid Build Coastguard Worker} 532*9880d681SAndroid Build Coastguard Worker 533*9880d681SAndroid Build Coastguard Worker 534*9880d681SAndroid Build Coastguard Worker; retain+release pair deletion, where the retain happens on two different 535*9880d681SAndroid Build Coastguard Worker; flow paths. 536*9880d681SAndroid Build Coastguard Worker 537*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test7( 538*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 539*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: objc_ 540*9880d681SAndroid Build Coastguard Worker; CHECK: t: 541*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain 542*9880d681SAndroid Build Coastguard Worker; CHECK: f: 543*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain 544*9880d681SAndroid Build Coastguard Worker; CHECK: return: 545*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 546*9880d681SAndroid Build Coastguard Worker; CHECK: } 547*9880d681SAndroid Build Coastguard Workerdefine void @test7(i32* %x, i1 %p) nounwind { 548*9880d681SAndroid Build Coastguard Workerentry: 549*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 550*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 551*9880d681SAndroid Build Coastguard Worker 552*9880d681SAndroid Build Coastguard Workert: 553*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 554*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 555*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 556*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 557*9880d681SAndroid Build Coastguard Worker br label %return 558*9880d681SAndroid Build Coastguard Worker 559*9880d681SAndroid Build Coastguard Workerf: 560*9880d681SAndroid Build Coastguard Worker %1 = call i8* @objc_retain(i8* %a) nounwind 561*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 562*9880d681SAndroid Build Coastguard Worker call void @callee() 563*9880d681SAndroid Build Coastguard Worker br label %return 564*9880d681SAndroid Build Coastguard Worker 565*9880d681SAndroid Build Coastguard Workerreturn: 566*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 567*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind 568*9880d681SAndroid Build Coastguard Worker ret void 569*9880d681SAndroid Build Coastguard Worker} 570*9880d681SAndroid Build Coastguard Worker 571*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test7b( 572*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 573*9880d681SAndroid Build Coastguard Worker; CHECK: } 574*9880d681SAndroid Build Coastguard Workerdefine void @test7b(i32* %x, i1 %p) nounwind { 575*9880d681SAndroid Build Coastguard Workerentry: 576*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 577*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 578*9880d681SAndroid Build Coastguard Worker 579*9880d681SAndroid Build Coastguard Workert: 580*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 581*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 582*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 583*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 584*9880d681SAndroid Build Coastguard Worker br label %return 585*9880d681SAndroid Build Coastguard Worker 586*9880d681SAndroid Build Coastguard Workerf: 587*9880d681SAndroid Build Coastguard Worker %1 = call i8* @objc_retain(i8* %a) nounwind 588*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 589*9880d681SAndroid Build Coastguard Worker call void @callee() 590*9880d681SAndroid Build Coastguard Worker br label %return 591*9880d681SAndroid Build Coastguard Worker 592*9880d681SAndroid Build Coastguard Workerreturn: 593*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 594*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0 595*9880d681SAndroid Build Coastguard Worker ret void 596*9880d681SAndroid Build Coastguard Worker} 597*9880d681SAndroid Build Coastguard Worker 598*9880d681SAndroid Build Coastguard Worker; Like test7, but there's a retain/retainBlock mismatch. Don't delete! 599*9880d681SAndroid Build Coastguard Worker 600*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test7c( 601*9880d681SAndroid Build Coastguard Worker; CHECK: t: 602*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retainBlock 603*9880d681SAndroid Build Coastguard Worker; CHECK: f: 604*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain 605*9880d681SAndroid Build Coastguard Worker; CHECK: return: 606*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 607*9880d681SAndroid Build Coastguard Worker; CHECK: } 608*9880d681SAndroid Build Coastguard Workerdefine void @test7c(i32* %x, i1 %p) nounwind { 609*9880d681SAndroid Build Coastguard Workerentry: 610*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 611*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 612*9880d681SAndroid Build Coastguard Worker 613*9880d681SAndroid Build Coastguard Workert: 614*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retainBlock(i8* %a) nounwind 615*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 616*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 617*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 618*9880d681SAndroid Build Coastguard Worker br label %return 619*9880d681SAndroid Build Coastguard Worker 620*9880d681SAndroid Build Coastguard Workerf: 621*9880d681SAndroid Build Coastguard Worker %1 = call i8* @objc_retain(i8* %a) nounwind 622*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 623*9880d681SAndroid Build Coastguard Worker call void @callee() 624*9880d681SAndroid Build Coastguard Worker br label %return 625*9880d681SAndroid Build Coastguard Worker 626*9880d681SAndroid Build Coastguard Workerreturn: 627*9880d681SAndroid Build Coastguard Worker %c = bitcast i32* %x to i8* 628*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) nounwind 629*9880d681SAndroid Build Coastguard Worker ret void 630*9880d681SAndroid Build Coastguard Worker} 631*9880d681SAndroid Build Coastguard Worker 632*9880d681SAndroid Build Coastguard Worker; retain+release pair deletion, where the retain and release both happen on 633*9880d681SAndroid Build Coastguard Worker; different flow paths. Wild! 634*9880d681SAndroid Build Coastguard Worker 635*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test8a( 636*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 637*9880d681SAndroid Build Coastguard Worker; CHECK: t: 638*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 639*9880d681SAndroid Build Coastguard Worker; CHECK: f: 640*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 641*9880d681SAndroid Build Coastguard Worker; CHECK: mid: 642*9880d681SAndroid Build Coastguard Worker; CHECK: u: 643*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 644*9880d681SAndroid Build Coastguard Worker; CHECK: g: 645*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 646*9880d681SAndroid Build Coastguard Worker; CHECK: return: 647*9880d681SAndroid Build Coastguard Worker; CHECK: } 648*9880d681SAndroid Build Coastguard Workerdefine void @test8a(i32* %x, i1 %p, i1 %q) nounwind { 649*9880d681SAndroid Build Coastguard Workerentry: 650*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 651*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 652*9880d681SAndroid Build Coastguard Worker 653*9880d681SAndroid Build Coastguard Workert: 654*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 655*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 656*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 657*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 658*9880d681SAndroid Build Coastguard Worker br label %mid 659*9880d681SAndroid Build Coastguard Worker 660*9880d681SAndroid Build Coastguard Workerf: 661*9880d681SAndroid Build Coastguard Worker %1 = call i8* @objc_retain(i8* %a) nounwind 662*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 663*9880d681SAndroid Build Coastguard Worker br label %mid 664*9880d681SAndroid Build Coastguard Worker 665*9880d681SAndroid Build Coastguard Workermid: 666*9880d681SAndroid Build Coastguard Worker br i1 %q, label %u, label %g 667*9880d681SAndroid Build Coastguard Worker 668*9880d681SAndroid Build Coastguard Workeru: 669*9880d681SAndroid Build Coastguard Worker call void @callee() 670*9880d681SAndroid Build Coastguard Worker %cu = bitcast i32* %x to i8* 671*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %cu) nounwind 672*9880d681SAndroid Build Coastguard Worker br label %return 673*9880d681SAndroid Build Coastguard Worker 674*9880d681SAndroid Build Coastguard Workerg: 675*9880d681SAndroid Build Coastguard Worker %cg = bitcast i32* %x to i8* 676*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %cg) nounwind 677*9880d681SAndroid Build Coastguard Worker br label %return 678*9880d681SAndroid Build Coastguard Worker 679*9880d681SAndroid Build Coastguard Workerreturn: 680*9880d681SAndroid Build Coastguard Worker ret void 681*9880d681SAndroid Build Coastguard Worker} 682*9880d681SAndroid Build Coastguard Worker 683*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test8b( 684*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 685*9880d681SAndroid Build Coastguard Worker; CHECK: } 686*9880d681SAndroid Build Coastguard Workerdefine void @test8b(i32* %x, i1 %p, i1 %q) nounwind { 687*9880d681SAndroid Build Coastguard Workerentry: 688*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 689*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 690*9880d681SAndroid Build Coastguard Worker 691*9880d681SAndroid Build Coastguard Workert: 692*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 693*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 694*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 695*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 696*9880d681SAndroid Build Coastguard Worker br label %mid 697*9880d681SAndroid Build Coastguard Worker 698*9880d681SAndroid Build Coastguard Workerf: 699*9880d681SAndroid Build Coastguard Worker %1 = call i8* @objc_retain(i8* %a) nounwind 700*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 701*9880d681SAndroid Build Coastguard Worker br label %mid 702*9880d681SAndroid Build Coastguard Worker 703*9880d681SAndroid Build Coastguard Workermid: 704*9880d681SAndroid Build Coastguard Worker br i1 %q, label %u, label %g 705*9880d681SAndroid Build Coastguard Worker 706*9880d681SAndroid Build Coastguard Workeru: 707*9880d681SAndroid Build Coastguard Worker call void @callee() 708*9880d681SAndroid Build Coastguard Worker %cu = bitcast i32* %x to i8* 709*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %cu) nounwind, !clang.imprecise_release !0 710*9880d681SAndroid Build Coastguard Worker br label %return 711*9880d681SAndroid Build Coastguard Worker 712*9880d681SAndroid Build Coastguard Workerg: 713*9880d681SAndroid Build Coastguard Worker %cg = bitcast i32* %x to i8* 714*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %cg) nounwind, !clang.imprecise_release !0 715*9880d681SAndroid Build Coastguard Worker br label %return 716*9880d681SAndroid Build Coastguard Worker 717*9880d681SAndroid Build Coastguard Workerreturn: 718*9880d681SAndroid Build Coastguard Worker ret void 719*9880d681SAndroid Build Coastguard Worker} 720*9880d681SAndroid Build Coastguard Worker 721*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test8c( 722*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 723*9880d681SAndroid Build Coastguard Worker; CHECK: t: 724*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 725*9880d681SAndroid Build Coastguard Worker; CHECK: f: 726*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 727*9880d681SAndroid Build Coastguard Worker; CHECK: mid: 728*9880d681SAndroid Build Coastguard Worker; CHECK: u: 729*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 730*9880d681SAndroid Build Coastguard Worker; CHECK: g: 731*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 732*9880d681SAndroid Build Coastguard Worker; CHECK: return: 733*9880d681SAndroid Build Coastguard Worker; CHECK: } 734*9880d681SAndroid Build Coastguard Workerdefine void @test8c(i32* %x, i1 %p, i1 %q) nounwind { 735*9880d681SAndroid Build Coastguard Workerentry: 736*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 737*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 738*9880d681SAndroid Build Coastguard Worker 739*9880d681SAndroid Build Coastguard Workert: 740*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 741*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 742*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 743*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 744*9880d681SAndroid Build Coastguard Worker br label %mid 745*9880d681SAndroid Build Coastguard Worker 746*9880d681SAndroid Build Coastguard Workerf: 747*9880d681SAndroid Build Coastguard Worker %1 = call i8* @objc_retain(i8* %a) nounwind 748*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 749*9880d681SAndroid Build Coastguard Worker br label %mid 750*9880d681SAndroid Build Coastguard Worker 751*9880d681SAndroid Build Coastguard Workermid: 752*9880d681SAndroid Build Coastguard Worker br i1 %q, label %u, label %g 753*9880d681SAndroid Build Coastguard Worker 754*9880d681SAndroid Build Coastguard Workeru: 755*9880d681SAndroid Build Coastguard Worker call void @callee() 756*9880d681SAndroid Build Coastguard Worker %cu = bitcast i32* %x to i8* 757*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %cu) nounwind 758*9880d681SAndroid Build Coastguard Worker br label %return 759*9880d681SAndroid Build Coastguard Worker 760*9880d681SAndroid Build Coastguard Workerg: 761*9880d681SAndroid Build Coastguard Worker %cg = bitcast i32* %x to i8* 762*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %cg) nounwind, !clang.imprecise_release !0 763*9880d681SAndroid Build Coastguard Worker br label %return 764*9880d681SAndroid Build Coastguard Worker 765*9880d681SAndroid Build Coastguard Workerreturn: 766*9880d681SAndroid Build Coastguard Worker ret void 767*9880d681SAndroid Build Coastguard Worker} 768*9880d681SAndroid Build Coastguard Worker 769*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test8d( 770*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 771*9880d681SAndroid Build Coastguard Worker; CHECK: t: 772*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 773*9880d681SAndroid Build Coastguard Worker; CHECK: f: 774*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 775*9880d681SAndroid Build Coastguard Worker; CHECK: mid: 776*9880d681SAndroid Build Coastguard Worker; CHECK: u: 777*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 778*9880d681SAndroid Build Coastguard Worker; CHECK: g: 779*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 780*9880d681SAndroid Build Coastguard Worker; CHECK: return: 781*9880d681SAndroid Build Coastguard Worker; CHECK: } 782*9880d681SAndroid Build Coastguard Workerdefine void @test8d(i32* %x, i1 %p, i1 %q) nounwind { 783*9880d681SAndroid Build Coastguard Workerentry: 784*9880d681SAndroid Build Coastguard Worker %a = bitcast i32* %x to i8* 785*9880d681SAndroid Build Coastguard Worker br i1 %p, label %t, label %f 786*9880d681SAndroid Build Coastguard Worker 787*9880d681SAndroid Build Coastguard Workert: 788*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %a) nounwind 789*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %a 790*9880d681SAndroid Build Coastguard Worker %b = bitcast i32* %x to float* 791*9880d681SAndroid Build Coastguard Worker store float 2.0, float* %b 792*9880d681SAndroid Build Coastguard Worker br label %mid 793*9880d681SAndroid Build Coastguard Worker 794*9880d681SAndroid Build Coastguard Workerf: 795*9880d681SAndroid Build Coastguard Worker %1 = call i8* @objc_retain(i8* %a) nounwind 796*9880d681SAndroid Build Coastguard Worker store i32 7, i32* %x 797*9880d681SAndroid Build Coastguard Worker br label %mid 798*9880d681SAndroid Build Coastguard Worker 799*9880d681SAndroid Build Coastguard Workermid: 800*9880d681SAndroid Build Coastguard Worker br i1 %q, label %u, label %g 801*9880d681SAndroid Build Coastguard Worker 802*9880d681SAndroid Build Coastguard Workeru: 803*9880d681SAndroid Build Coastguard Worker call void @callee() 804*9880d681SAndroid Build Coastguard Worker %cu = bitcast i32* %x to i8* 805*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %cu) nounwind, !clang.imprecise_release !0 806*9880d681SAndroid Build Coastguard Worker br label %return 807*9880d681SAndroid Build Coastguard Worker 808*9880d681SAndroid Build Coastguard Workerg: 809*9880d681SAndroid Build Coastguard Worker %cg = bitcast i32* %x to i8* 810*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %cg) nounwind 811*9880d681SAndroid Build Coastguard Worker br label %return 812*9880d681SAndroid Build Coastguard Worker 813*9880d681SAndroid Build Coastguard Workerreturn: 814*9880d681SAndroid Build Coastguard Worker ret void 815*9880d681SAndroid Build Coastguard Worker} 816*9880d681SAndroid Build Coastguard Worker 817*9880d681SAndroid Build Coastguard Worker; Trivial retain+release pair deletion. 818*9880d681SAndroid Build Coastguard Worker 819*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test9( 820*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 821*9880d681SAndroid Build Coastguard Worker; CHECK: } 822*9880d681SAndroid Build Coastguard Workerdefine void @test9(i8* %x) nounwind { 823*9880d681SAndroid Build Coastguard Workerentry: 824*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %x) nounwind 825*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %0) nounwind 826*9880d681SAndroid Build Coastguard Worker ret void 827*9880d681SAndroid Build Coastguard Worker} 828*9880d681SAndroid Build Coastguard Worker 829*9880d681SAndroid Build Coastguard Worker; Retain+release pair, but on an unknown pointer relationship. Don't delete! 830*9880d681SAndroid Build Coastguard Worker 831*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test9b( 832*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 833*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %s) 834*9880d681SAndroid Build Coastguard Worker; CHECK: } 835*9880d681SAndroid Build Coastguard Workerdefine void @test9b(i8* %x, i1 %j, i8* %p) nounwind { 836*9880d681SAndroid Build Coastguard Workerentry: 837*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %x) nounwind 838*9880d681SAndroid Build Coastguard Worker %s = select i1 %j, i8* %x, i8* %p 839*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %s) nounwind 840*9880d681SAndroid Build Coastguard Worker ret void 841*9880d681SAndroid Build Coastguard Worker} 842*9880d681SAndroid Build Coastguard Worker 843*9880d681SAndroid Build Coastguard Worker; Trivial retain+release pair with intervening calls - don't delete! 844*9880d681SAndroid Build Coastguard Worker 845*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test10( 846*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 847*9880d681SAndroid Build Coastguard Worker; CHECK: @callee 848*9880d681SAndroid Build Coastguard Worker; CHECK: @use_pointer 849*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 850*9880d681SAndroid Build Coastguard Worker; CHECK: } 851*9880d681SAndroid Build Coastguard Workerdefine void @test10(i8* %x) nounwind { 852*9880d681SAndroid Build Coastguard Workerentry: 853*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %x) nounwind 854*9880d681SAndroid Build Coastguard Worker call void @callee() 855*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 856*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %0) nounwind 857*9880d681SAndroid Build Coastguard Worker ret void 858*9880d681SAndroid Build Coastguard Worker} 859*9880d681SAndroid Build Coastguard Worker 860*9880d681SAndroid Build Coastguard Worker; Trivial retain+autoreleaserelease pair. Don't delete! 861*9880d681SAndroid Build Coastguard Worker; Also, add a tail keyword, since objc_retain can never be passed 862*9880d681SAndroid Build Coastguard Worker; a stack argument. 863*9880d681SAndroid Build Coastguard Worker 864*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test11( 865*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]] 866*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autorelease(i8* %0) [[NUW]] 867*9880d681SAndroid Build Coastguard Worker; CHECK: } 868*9880d681SAndroid Build Coastguard Workerdefine void @test11(i8* %x) nounwind { 869*9880d681SAndroid Build Coastguard Workerentry: 870*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %x) nounwind 871*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* %0) nounwind 872*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 873*9880d681SAndroid Build Coastguard Worker ret void 874*9880d681SAndroid Build Coastguard Worker} 875*9880d681SAndroid Build Coastguard Worker 876*9880d681SAndroid Build Coastguard Worker; Same as test11 but with no use_pointer call. Delete the pair! 877*9880d681SAndroid Build Coastguard Worker 878*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test11a( 879*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 880*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 881*9880d681SAndroid Build Coastguard Worker; CHECK: } 882*9880d681SAndroid Build Coastguard Workerdefine void @test11a(i8* %x) nounwind { 883*9880d681SAndroid Build Coastguard Workerentry: 884*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %x) nounwind 885*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* %0) nounwind 886*9880d681SAndroid Build Coastguard Worker ret void 887*9880d681SAndroid Build Coastguard Worker} 888*9880d681SAndroid Build Coastguard Worker 889*9880d681SAndroid Build Coastguard Worker; Same as test11 but the value is returned. Do not perform an RV optimization 890*9880d681SAndroid Build Coastguard Worker; since if the frontend emitted code for an __autoreleasing variable, we may 891*9880d681SAndroid Build Coastguard Worker; want it to be in the autorelease pool. 892*9880d681SAndroid Build Coastguard Worker 893*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test11b( 894*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]] 895*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autorelease(i8* %0) [[NUW]] 896*9880d681SAndroid Build Coastguard Worker; CHECK: } 897*9880d681SAndroid Build Coastguard Workerdefine i8* @test11b(i8* %x) nounwind { 898*9880d681SAndroid Build Coastguard Workerentry: 899*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %x) nounwind 900*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* %0) nounwind 901*9880d681SAndroid Build Coastguard Worker ret i8* %x 902*9880d681SAndroid Build Coastguard Worker} 903*9880d681SAndroid Build Coastguard Worker 904*9880d681SAndroid Build Coastguard Worker; We can not delete this retain, release since we do not have a post-dominating 905*9880d681SAndroid Build Coastguard Worker; use of the release. 906*9880d681SAndroid Build Coastguard Worker 907*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test12( 908*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 909*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_retain(i8* %x) 910*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_retain 911*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 912*9880d681SAndroid Build Coastguard Worker; CHECK: } 913*9880d681SAndroid Build Coastguard Workerdefine void @test12(i8* %x, i64 %n) { 914*9880d681SAndroid Build Coastguard Workerentry: 915*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 916*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 917*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 918*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 919*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 920*9880d681SAndroid Build Coastguard Worker ret void 921*9880d681SAndroid Build Coastguard Worker} 922*9880d681SAndroid Build Coastguard Worker 923*9880d681SAndroid Build Coastguard Worker; Trivial retain,autorelease pair. Don't delete! 924*9880d681SAndroid Build Coastguard Worker 925*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test13( 926*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]] 927*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]] 928*9880d681SAndroid Build Coastguard Worker; CHECK: @use_pointer(i8* %x) 929*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autorelease(i8* %x) [[NUW]] 930*9880d681SAndroid Build Coastguard Worker; CHECK: } 931*9880d681SAndroid Build Coastguard Workerdefine void @test13(i8* %x, i64 %n) { 932*9880d681SAndroid Build Coastguard Workerentry: 933*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 934*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 935*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 936*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* %x) nounwind 937*9880d681SAndroid Build Coastguard Worker ret void 938*9880d681SAndroid Build Coastguard Worker} 939*9880d681SAndroid Build Coastguard Worker 940*9880d681SAndroid Build Coastguard Worker; Delete the retain+release pair. 941*9880d681SAndroid Build Coastguard Worker 942*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test13b( 943*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 944*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_retain(i8* %x) 945*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @use_pointer 946*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @use_pointer 947*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @use_pointer 948*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_release 949*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 950*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 951*9880d681SAndroid Build Coastguard Workerdefine void @test13b(i8* %x, i64 %n) { 952*9880d681SAndroid Build Coastguard Workerentry: 953*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 954*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 955*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 956*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 957*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 958*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 959*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 960*9880d681SAndroid Build Coastguard Worker ret void 961*9880d681SAndroid Build Coastguard Worker} 962*9880d681SAndroid Build Coastguard Worker 963*9880d681SAndroid Build Coastguard Worker; Don't delete the retain+release pair because there's an 964*9880d681SAndroid Build Coastguard Worker; autoreleasePoolPop in the way. 965*9880d681SAndroid Build Coastguard Worker 966*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test13c( 967*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 968*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_autoreleasePoolPop 969*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 970*9880d681SAndroid Build Coastguard Worker; CHECK: @use_pointer 971*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 972*9880d681SAndroid Build Coastguard Worker; CHECK: } 973*9880d681SAndroid Build Coastguard Workerdefine void @test13c(i8* %x, i64 %n) { 974*9880d681SAndroid Build Coastguard Workerentry: 975*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 976*9880d681SAndroid Build Coastguard Worker call void @objc_autoreleasePoolPop(i8* undef) 977*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 978*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 979*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 980*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 981*9880d681SAndroid Build Coastguard Worker ret void 982*9880d681SAndroid Build Coastguard Worker} 983*9880d681SAndroid Build Coastguard Worker 984*9880d681SAndroid Build Coastguard Worker; Like test13c, but there's an autoreleasePoolPush in the way, but that 985*9880d681SAndroid Build Coastguard Worker; doesn't matter. 986*9880d681SAndroid Build Coastguard Worker 987*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test13d( 988*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 989*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_retain(i8* %x) 990*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_autoreleasePoolPush 991*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @use_pointer 992*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @use_pointer 993*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @use_pointer 994*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_release 995*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 996*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 997*9880d681SAndroid Build Coastguard Workerdefine void @test13d(i8* %x, i64 %n) { 998*9880d681SAndroid Build Coastguard Workerentry: 999*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1000*9880d681SAndroid Build Coastguard Worker call i8* @objc_autoreleasePoolPush() 1001*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1002*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1003*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1004*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 1005*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1006*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 1007*9880d681SAndroid Build Coastguard Worker ret void 1008*9880d681SAndroid Build Coastguard Worker} 1009*9880d681SAndroid Build Coastguard Worker 1010*9880d681SAndroid Build Coastguard Worker; Trivial retain,release pair with intervening call, and it's post-dominated by 1011*9880d681SAndroid Build Coastguard Worker; another release. But it is not known safe in the top down direction. We can 1012*9880d681SAndroid Build Coastguard Worker; not eliminate it. 1013*9880d681SAndroid Build Coastguard Worker 1014*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test14( 1015*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 1016*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_retain 1017*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @use_pointer 1018*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @use_pointer 1019*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_release 1020*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_release 1021*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 1022*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 1023*9880d681SAndroid Build Coastguard Workerdefine void @test14(i8* %x, i64 %n) { 1024*9880d681SAndroid Build Coastguard Workerentry: 1025*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1026*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1027*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1028*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 1029*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 1030*9880d681SAndroid Build Coastguard Worker ret void 1031*9880d681SAndroid Build Coastguard Worker} 1032*9880d681SAndroid Build Coastguard Worker 1033*9880d681SAndroid Build Coastguard Worker; Trivial retain,autorelease pair with intervening call, but it's post-dominated 1034*9880d681SAndroid Build Coastguard Worker; by another release. Don't delete anything. 1035*9880d681SAndroid Build Coastguard Worker 1036*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test15( 1037*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 1038*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_retain(i8* %x) 1039*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @use_pointer 1040*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_autorelease(i8* %x) 1041*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_release 1042*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 1043*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 1044*9880d681SAndroid Build Coastguard Workerdefine void @test15(i8* %x, i64 %n) { 1045*9880d681SAndroid Build Coastguard Workerentry: 1046*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1047*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1048*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* %x) nounwind 1049*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 1050*9880d681SAndroid Build Coastguard Worker ret void 1051*9880d681SAndroid Build Coastguard Worker} 1052*9880d681SAndroid Build Coastguard Worker 1053*9880d681SAndroid Build Coastguard Worker; Trivial retain,autorelease pair, post-dominated 1054*9880d681SAndroid Build Coastguard Worker; by another release. Delete the retain and release. 1055*9880d681SAndroid Build Coastguard Worker 1056*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test15b( 1057*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 1058*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_retain 1059*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_autorelease 1060*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_release 1061*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 1062*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 1063*9880d681SAndroid Build Coastguard Workerdefine void @test15b(i8* %x, i64 %n) { 1064*9880d681SAndroid Build Coastguard Workerentry: 1065*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1066*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* %x) nounwind 1067*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 1068*9880d681SAndroid Build Coastguard Worker ret void 1069*9880d681SAndroid Build Coastguard Worker} 1070*9880d681SAndroid Build Coastguard Worker 1071*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test15c( 1072*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 1073*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_autorelease 1074*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 1075*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 1076*9880d681SAndroid Build Coastguard Workerdefine void @test15c(i8* %x, i64 %n) { 1077*9880d681SAndroid Build Coastguard Workerentry: 1078*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1079*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* %x) nounwind 1080*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 1081*9880d681SAndroid Build Coastguard Worker ret void 1082*9880d681SAndroid Build Coastguard Worker} 1083*9880d681SAndroid Build Coastguard Worker 1084*9880d681SAndroid Build Coastguard Worker; Retain+release pairs in diamonds, all dominated by a retain. 1085*9880d681SAndroid Build Coastguard Worker 1086*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test16a( 1087*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 1088*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc 1089*9880d681SAndroid Build Coastguard Worker; CHECK: purple: 1090*9880d681SAndroid Build Coastguard Worker; CHECK: @use_pointer 1091*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 1092*9880d681SAndroid Build Coastguard Worker; CHECK: } 1093*9880d681SAndroid Build Coastguard Workerdefine void @test16a(i1 %a, i1 %b, i8* %x) { 1094*9880d681SAndroid Build Coastguard Workerentry: 1095*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1096*9880d681SAndroid Build Coastguard Worker br i1 %a, label %red, label %orange 1097*9880d681SAndroid Build Coastguard Worker 1098*9880d681SAndroid Build Coastguard Workerred: 1099*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1100*9880d681SAndroid Build Coastguard Worker br label %yellow 1101*9880d681SAndroid Build Coastguard Worker 1102*9880d681SAndroid Build Coastguard Workerorange: 1103*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1104*9880d681SAndroid Build Coastguard Worker br label %yellow 1105*9880d681SAndroid Build Coastguard Worker 1106*9880d681SAndroid Build Coastguard Workeryellow: 1107*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1108*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1109*9880d681SAndroid Build Coastguard Worker br i1 %b, label %green, label %blue 1110*9880d681SAndroid Build Coastguard Worker 1111*9880d681SAndroid Build Coastguard Workergreen: 1112*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 1113*9880d681SAndroid Build Coastguard Worker br label %purple 1114*9880d681SAndroid Build Coastguard Worker 1115*9880d681SAndroid Build Coastguard Workerblue: 1116*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 1117*9880d681SAndroid Build Coastguard Worker br label %purple 1118*9880d681SAndroid Build Coastguard Worker 1119*9880d681SAndroid Build Coastguard Workerpurple: 1120*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1121*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 1122*9880d681SAndroid Build Coastguard Worker ret void 1123*9880d681SAndroid Build Coastguard Worker} 1124*9880d681SAndroid Build Coastguard Worker 1125*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test16b( 1126*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 1127*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc 1128*9880d681SAndroid Build Coastguard Worker; CHECK: purple: 1129*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @use_pointer 1130*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @use_pointer 1131*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_release 1132*9880d681SAndroid Build Coastguard Worker; CHECK: } 1133*9880d681SAndroid Build Coastguard Workerdefine void @test16b(i1 %a, i1 %b, i8* %x) { 1134*9880d681SAndroid Build Coastguard Workerentry: 1135*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1136*9880d681SAndroid Build Coastguard Worker br i1 %a, label %red, label %orange 1137*9880d681SAndroid Build Coastguard Worker 1138*9880d681SAndroid Build Coastguard Workerred: 1139*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1140*9880d681SAndroid Build Coastguard Worker br label %yellow 1141*9880d681SAndroid Build Coastguard Worker 1142*9880d681SAndroid Build Coastguard Workerorange: 1143*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1144*9880d681SAndroid Build Coastguard Worker br label %yellow 1145*9880d681SAndroid Build Coastguard Worker 1146*9880d681SAndroid Build Coastguard Workeryellow: 1147*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1148*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1149*9880d681SAndroid Build Coastguard Worker br i1 %b, label %green, label %blue 1150*9880d681SAndroid Build Coastguard Worker 1151*9880d681SAndroid Build Coastguard Workergreen: 1152*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 1153*9880d681SAndroid Build Coastguard Worker br label %purple 1154*9880d681SAndroid Build Coastguard Worker 1155*9880d681SAndroid Build Coastguard Workerblue: 1156*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 1157*9880d681SAndroid Build Coastguard Worker br label %purple 1158*9880d681SAndroid Build Coastguard Worker 1159*9880d681SAndroid Build Coastguard Workerpurple: 1160*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1161*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1162*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 1163*9880d681SAndroid Build Coastguard Worker ret void 1164*9880d681SAndroid Build Coastguard Worker} 1165*9880d681SAndroid Build Coastguard Worker 1166*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test16c( 1167*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 1168*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc 1169*9880d681SAndroid Build Coastguard Worker; CHECK: purple: 1170*9880d681SAndroid Build Coastguard Worker; CHECK: @use_pointer 1171*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 1172*9880d681SAndroid Build Coastguard Worker; CHECK: } 1173*9880d681SAndroid Build Coastguard Workerdefine void @test16c(i1 %a, i1 %b, i8* %x) { 1174*9880d681SAndroid Build Coastguard Workerentry: 1175*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1176*9880d681SAndroid Build Coastguard Worker br i1 %a, label %red, label %orange 1177*9880d681SAndroid Build Coastguard Worker 1178*9880d681SAndroid Build Coastguard Workerred: 1179*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1180*9880d681SAndroid Build Coastguard Worker br label %yellow 1181*9880d681SAndroid Build Coastguard Worker 1182*9880d681SAndroid Build Coastguard Workerorange: 1183*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1184*9880d681SAndroid Build Coastguard Worker br label %yellow 1185*9880d681SAndroid Build Coastguard Worker 1186*9880d681SAndroid Build Coastguard Workeryellow: 1187*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1188*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1189*9880d681SAndroid Build Coastguard Worker br i1 %b, label %green, label %blue 1190*9880d681SAndroid Build Coastguard Worker 1191*9880d681SAndroid Build Coastguard Workergreen: 1192*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 1193*9880d681SAndroid Build Coastguard Worker br label %purple 1194*9880d681SAndroid Build Coastguard Worker 1195*9880d681SAndroid Build Coastguard Workerblue: 1196*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 1197*9880d681SAndroid Build Coastguard Worker br label %purple 1198*9880d681SAndroid Build Coastguard Worker 1199*9880d681SAndroid Build Coastguard Workerpurple: 1200*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1201*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 1202*9880d681SAndroid Build Coastguard Worker ret void 1203*9880d681SAndroid Build Coastguard Worker} 1204*9880d681SAndroid Build Coastguard Worker 1205*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test16d( 1206*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 1207*9880d681SAndroid Build Coastguard Worker; CHECK: @objc 1208*9880d681SAndroid Build Coastguard Worker; CHECK: } 1209*9880d681SAndroid Build Coastguard Workerdefine void @test16d(i1 %a, i1 %b, i8* %x) { 1210*9880d681SAndroid Build Coastguard Workerentry: 1211*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1212*9880d681SAndroid Build Coastguard Worker br i1 %a, label %red, label %orange 1213*9880d681SAndroid Build Coastguard Worker 1214*9880d681SAndroid Build Coastguard Workerred: 1215*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1216*9880d681SAndroid Build Coastguard Worker br label %yellow 1217*9880d681SAndroid Build Coastguard Worker 1218*9880d681SAndroid Build Coastguard Workerorange: 1219*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 1220*9880d681SAndroid Build Coastguard Worker br label %yellow 1221*9880d681SAndroid Build Coastguard Worker 1222*9880d681SAndroid Build Coastguard Workeryellow: 1223*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1224*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 1225*9880d681SAndroid Build Coastguard Worker br i1 %b, label %green, label %blue 1226*9880d681SAndroid Build Coastguard Worker 1227*9880d681SAndroid Build Coastguard Workergreen: 1228*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 1229*9880d681SAndroid Build Coastguard Worker br label %purple 1230*9880d681SAndroid Build Coastguard Worker 1231*9880d681SAndroid Build Coastguard Workerblue: 1232*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 1233*9880d681SAndroid Build Coastguard Worker br label %purple 1234*9880d681SAndroid Build Coastguard Worker 1235*9880d681SAndroid Build Coastguard Workerpurple: 1236*9880d681SAndroid Build Coastguard Worker ret void 1237*9880d681SAndroid Build Coastguard Worker} 1238*9880d681SAndroid Build Coastguard Worker 1239*9880d681SAndroid Build Coastguard Worker; Delete no-ops. 1240*9880d681SAndroid Build Coastguard Worker 1241*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test18( 1242*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1243*9880d681SAndroid Build Coastguard Worker; CHECK: } 1244*9880d681SAndroid Build Coastguard Workerdefine void @test18() { 1245*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* null) 1246*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* null) 1247*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* null) 1248*9880d681SAndroid Build Coastguard Worker ret void 1249*9880d681SAndroid Build Coastguard Worker} 1250*9880d681SAndroid Build Coastguard Worker 1251*9880d681SAndroid Build Coastguard Worker; Delete no-ops where undef can be assumed to be null. 1252*9880d681SAndroid Build Coastguard Worker 1253*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test18b( 1254*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1255*9880d681SAndroid Build Coastguard Worker; CHECK: } 1256*9880d681SAndroid Build Coastguard Workerdefine void @test18b() { 1257*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* undef) 1258*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* undef) 1259*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* undef) 1260*9880d681SAndroid Build Coastguard Worker ret void 1261*9880d681SAndroid Build Coastguard Worker} 1262*9880d681SAndroid Build Coastguard Worker 1263*9880d681SAndroid Build Coastguard Worker; Replace uses of arguments with uses of return values, to reduce 1264*9880d681SAndroid Build Coastguard Worker; register pressure. 1265*9880d681SAndroid Build Coastguard Worker 1266*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test19(i32* %y) { 1267*9880d681SAndroid Build Coastguard Worker; CHECK: %z = bitcast i32* %y to i8* 1268*9880d681SAndroid Build Coastguard Worker; CHECK: %0 = bitcast i32* %y to i8* 1269*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = tail call i8* @objc_retain(i8* %0) 1270*9880d681SAndroid Build Coastguard Worker; CHECK: call void @use_pointer(i8* %z) 1271*9880d681SAndroid Build Coastguard Worker; CHECK: call void @use_pointer(i8* %z) 1272*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = bitcast i32* %y to i8* 1273*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %2) 1274*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 1275*9880d681SAndroid Build Coastguard Worker; CHECK: } 1276*9880d681SAndroid Build Coastguard Workerdefine void @test19(i32* %y) { 1277*9880d681SAndroid Build Coastguard Workerentry: 1278*9880d681SAndroid Build Coastguard Worker %x = bitcast i32* %y to i8* 1279*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %x) nounwind 1280*9880d681SAndroid Build Coastguard Worker %z = bitcast i32* %y to i8* 1281*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %z) 1282*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %z) 1283*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) 1284*9880d681SAndroid Build Coastguard Worker ret void 1285*9880d681SAndroid Build Coastguard Worker} 1286*9880d681SAndroid Build Coastguard Worker 1287*9880d681SAndroid Build Coastguard Worker; Bitcast insertion 1288*9880d681SAndroid Build Coastguard Worker 1289*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test20( 1290*9880d681SAndroid Build Coastguard Worker; CHECK: %tmp1 = tail call i8* @objc_retain(i8* %tmp) [[NUW]] 1291*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: invoke 1292*9880d681SAndroid Build Coastguard Worker; CHECK: } 1293*9880d681SAndroid Build Coastguard Workerdefine void @test20(double* %self) personality i32 (...)* @__gxx_personality_v0 { 1294*9880d681SAndroid Build Coastguard Workerif.then12: 1295*9880d681SAndroid Build Coastguard Worker %tmp = bitcast double* %self to i8* 1296*9880d681SAndroid Build Coastguard Worker %tmp1 = call i8* @objc_retain(i8* %tmp) nounwind 1297*9880d681SAndroid Build Coastguard Worker invoke void @invokee() 1298*9880d681SAndroid Build Coastguard Worker to label %invoke.cont23 unwind label %lpad20 1299*9880d681SAndroid Build Coastguard Worker 1300*9880d681SAndroid Build Coastguard Workerinvoke.cont23: ; preds = %if.then12 1301*9880d681SAndroid Build Coastguard Worker invoke void @invokee() 1302*9880d681SAndroid Build Coastguard Worker to label %if.end unwind label %lpad20 1303*9880d681SAndroid Build Coastguard Worker 1304*9880d681SAndroid Build Coastguard Workerlpad20: ; preds = %invoke.cont23, %if.then12 1305*9880d681SAndroid Build Coastguard Worker %tmp502 = phi double* [ undef, %invoke.cont23 ], [ %self, %if.then12 ] 1306*9880d681SAndroid Build Coastguard Worker %exn = landingpad {i8*, i32} 1307*9880d681SAndroid Build Coastguard Worker cleanup 1308*9880d681SAndroid Build Coastguard Worker unreachable 1309*9880d681SAndroid Build Coastguard Worker 1310*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %invoke.cont23 1311*9880d681SAndroid Build Coastguard Worker ret void 1312*9880d681SAndroid Build Coastguard Worker} 1313*9880d681SAndroid Build Coastguard Worker 1314*9880d681SAndroid Build Coastguard Worker; Delete a redundant retain,autorelease when forwaring a call result 1315*9880d681SAndroid Build Coastguard Worker; directly to a return value. 1316*9880d681SAndroid Build Coastguard Worker 1317*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test21( 1318*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @returner() 1319*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i8* %call 1320*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 1321*9880d681SAndroid Build Coastguard Workerdefine i8* @test21() { 1322*9880d681SAndroid Build Coastguard Workerentry: 1323*9880d681SAndroid Build Coastguard Worker %call = call i8* @returner() 1324*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %call) nounwind 1325*9880d681SAndroid Build Coastguard Worker %1 = call i8* @objc_autorelease(i8* %0) nounwind 1326*9880d681SAndroid Build Coastguard Worker ret i8* %1 1327*9880d681SAndroid Build Coastguard Worker} 1328*9880d681SAndroid Build Coastguard Worker 1329*9880d681SAndroid Build Coastguard Worker; Move an objc call up through a phi that has null operands. 1330*9880d681SAndroid Build Coastguard Worker 1331*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test22( 1332*9880d681SAndroid Build Coastguard Worker; CHECK: B: 1333*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = bitcast double* %p to i8* 1334*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %1) 1335*9880d681SAndroid Build Coastguard Worker; CHECK: br label %C 1336*9880d681SAndroid Build Coastguard Worker; CHECK: C: ; preds = %B, %A 1337*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 1338*9880d681SAndroid Build Coastguard Worker; CHECK: } 1339*9880d681SAndroid Build Coastguard Workerdefine void @test22(double* %p, i1 %a) { 1340*9880d681SAndroid Build Coastguard Worker br i1 %a, label %A, label %B 1341*9880d681SAndroid Build Coastguard WorkerA: 1342*9880d681SAndroid Build Coastguard Worker br label %C 1343*9880d681SAndroid Build Coastguard WorkerB: 1344*9880d681SAndroid Build Coastguard Worker br label %C 1345*9880d681SAndroid Build Coastguard WorkerC: 1346*9880d681SAndroid Build Coastguard Worker %h = phi double* [ null, %A ], [ %p, %B ] 1347*9880d681SAndroid Build Coastguard Worker %c = bitcast double* %h to i8* 1348*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %c) 1349*9880d681SAndroid Build Coastguard Worker ret void 1350*9880d681SAndroid Build Coastguard Worker} 1351*9880d681SAndroid Build Coastguard Worker 1352*9880d681SAndroid Build Coastguard Worker; Any call can decrement a retain count. 1353*9880d681SAndroid Build Coastguard Worker 1354*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test24( 1355*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %a) 1356*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 1357*9880d681SAndroid Build Coastguard Worker; CHECK: } 1358*9880d681SAndroid Build Coastguard Workerdefine void @test24(i8* %r, i8* %a) { 1359*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %a) 1360*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %r) 1361*9880d681SAndroid Build Coastguard Worker %q = load i8, i8* %a 1362*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %a) 1363*9880d681SAndroid Build Coastguard Worker ret void 1364*9880d681SAndroid Build Coastguard Worker} 1365*9880d681SAndroid Build Coastguard Worker 1366*9880d681SAndroid Build Coastguard Worker; Don't move a retain/release pair if the release can be moved 1367*9880d681SAndroid Build Coastguard Worker; but the retain can't be moved to balance it. 1368*9880d681SAndroid Build Coastguard Worker 1369*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test25( 1370*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 1371*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain(i8* %p) 1372*9880d681SAndroid Build Coastguard Worker; CHECK: true: 1373*9880d681SAndroid Build Coastguard Worker; CHECK: done: 1374*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %p) 1375*9880d681SAndroid Build Coastguard Worker; CHECK: } 1376*9880d681SAndroid Build Coastguard Workerdefine void @test25(i8* %p, i1 %x) { 1377*9880d681SAndroid Build Coastguard Workerentry: 1378*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1379*9880d681SAndroid Build Coastguard Worker call void @callee() 1380*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %done 1381*9880d681SAndroid Build Coastguard Worker 1382*9880d681SAndroid Build Coastguard Workertrue: 1383*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %p 1384*9880d681SAndroid Build Coastguard Worker br label %done 1385*9880d681SAndroid Build Coastguard Worker 1386*9880d681SAndroid Build Coastguard Workerdone: 1387*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1388*9880d681SAndroid Build Coastguard Worker ret void 1389*9880d681SAndroid Build Coastguard Worker} 1390*9880d681SAndroid Build Coastguard Worker 1391*9880d681SAndroid Build Coastguard Worker; Don't move a retain/release pair if the retain can be moved 1392*9880d681SAndroid Build Coastguard Worker; but the release can't be moved to balance it. 1393*9880d681SAndroid Build Coastguard Worker 1394*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test26( 1395*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 1396*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain(i8* %p) 1397*9880d681SAndroid Build Coastguard Worker; CHECK: true: 1398*9880d681SAndroid Build Coastguard Worker; CHECK: done: 1399*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %p) 1400*9880d681SAndroid Build Coastguard Worker; CHECK: } 1401*9880d681SAndroid Build Coastguard Workerdefine void @test26(i8* %p, i1 %x) { 1402*9880d681SAndroid Build Coastguard Workerentry: 1403*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1404*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %done 1405*9880d681SAndroid Build Coastguard Worker 1406*9880d681SAndroid Build Coastguard Workertrue: 1407*9880d681SAndroid Build Coastguard Worker call void @callee() 1408*9880d681SAndroid Build Coastguard Worker br label %done 1409*9880d681SAndroid Build Coastguard Worker 1410*9880d681SAndroid Build Coastguard Workerdone: 1411*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %p 1412*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1413*9880d681SAndroid Build Coastguard Worker ret void 1414*9880d681SAndroid Build Coastguard Worker} 1415*9880d681SAndroid Build Coastguard Worker 1416*9880d681SAndroid Build Coastguard Worker; Don't sink the retain,release into the loop. 1417*9880d681SAndroid Build Coastguard Worker 1418*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test27( 1419*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 1420*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain(i8* %p) 1421*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 1422*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1423*9880d681SAndroid Build Coastguard Worker; CHECK: done: 1424*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 1425*9880d681SAndroid Build Coastguard Worker; CHECK: } 1426*9880d681SAndroid Build Coastguard Workerdefine void @test27(i8* %p, i1 %x, i1 %y) { 1427*9880d681SAndroid Build Coastguard Workerentry: 1428*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1429*9880d681SAndroid Build Coastguard Worker br i1 %x, label %loop, label %done 1430*9880d681SAndroid Build Coastguard Worker 1431*9880d681SAndroid Build Coastguard Workerloop: 1432*9880d681SAndroid Build Coastguard Worker call void @callee() 1433*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %p 1434*9880d681SAndroid Build Coastguard Worker br i1 %y, label %done, label %loop 1435*9880d681SAndroid Build Coastguard Worker 1436*9880d681SAndroid Build Coastguard Workerdone: 1437*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1438*9880d681SAndroid Build Coastguard Worker ret void 1439*9880d681SAndroid Build Coastguard Worker} 1440*9880d681SAndroid Build Coastguard Worker 1441*9880d681SAndroid Build Coastguard Worker; Trivial code motion case: Triangle. 1442*9880d681SAndroid Build Coastguard Worker 1443*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test28( 1444*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1445*9880d681SAndroid Build Coastguard Worker; CHECK: true: 1446*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain( 1447*9880d681SAndroid Build Coastguard Worker; CHECK: call void @callee() 1448*9880d681SAndroid Build Coastguard Worker; CHECK: store 1449*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 1450*9880d681SAndroid Build Coastguard Worker; CHECK: done: 1451*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1452*9880d681SAndroid Build Coastguard Worker; CHECK: } 1453*9880d681SAndroid Build Coastguard Workerdefine void @test28(i8* %p, i1 %x) { 1454*9880d681SAndroid Build Coastguard Workerentry: 1455*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1456*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %done 1457*9880d681SAndroid Build Coastguard Worker 1458*9880d681SAndroid Build Coastguard Workertrue: 1459*9880d681SAndroid Build Coastguard Worker call void @callee() 1460*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %p 1461*9880d681SAndroid Build Coastguard Worker br label %done 1462*9880d681SAndroid Build Coastguard Worker 1463*9880d681SAndroid Build Coastguard Workerdone: 1464*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p), !clang.imprecise_release !0 1465*9880d681SAndroid Build Coastguard Worker ret void 1466*9880d681SAndroid Build Coastguard Worker} 1467*9880d681SAndroid Build Coastguard Worker 1468*9880d681SAndroid Build Coastguard Worker; Trivial code motion case: Triangle, but no metadata. Don't move past 1469*9880d681SAndroid Build Coastguard Worker; unrelated memory references! 1470*9880d681SAndroid Build Coastguard Worker 1471*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test28b( 1472*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain( 1473*9880d681SAndroid Build Coastguard Worker; CHECK: true: 1474*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1475*9880d681SAndroid Build Coastguard Worker; CHECK: call void @callee() 1476*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1477*9880d681SAndroid Build Coastguard Worker; CHECK: store 1478*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1479*9880d681SAndroid Build Coastguard Worker; CHECK: done: 1480*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 1481*9880d681SAndroid Build Coastguard Worker; CHECK: } 1482*9880d681SAndroid Build Coastguard Workerdefine void @test28b(i8* %p, i1 %x, i8* noalias %t) { 1483*9880d681SAndroid Build Coastguard Workerentry: 1484*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1485*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %done 1486*9880d681SAndroid Build Coastguard Worker 1487*9880d681SAndroid Build Coastguard Workertrue: 1488*9880d681SAndroid Build Coastguard Worker call void @callee() 1489*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %p 1490*9880d681SAndroid Build Coastguard Worker br label %done 1491*9880d681SAndroid Build Coastguard Worker 1492*9880d681SAndroid Build Coastguard Workerdone: 1493*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %t 1494*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1495*9880d681SAndroid Build Coastguard Worker ret void 1496*9880d681SAndroid Build Coastguard Worker} 1497*9880d681SAndroid Build Coastguard Worker 1498*9880d681SAndroid Build Coastguard Worker; Trivial code motion case: Triangle, with metadata. Do move past 1499*9880d681SAndroid Build Coastguard Worker; unrelated memory references! And preserve the metadata. 1500*9880d681SAndroid Build Coastguard Worker 1501*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test28c( 1502*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1503*9880d681SAndroid Build Coastguard Worker; CHECK: true: 1504*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain( 1505*9880d681SAndroid Build Coastguard Worker; CHECK: call void @callee() 1506*9880d681SAndroid Build Coastguard Worker; CHECK: store 1507*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %p) [[NUW]], !clang.imprecise_release 1508*9880d681SAndroid Build Coastguard Worker; CHECK: done: 1509*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1510*9880d681SAndroid Build Coastguard Worker; CHECK: } 1511*9880d681SAndroid Build Coastguard Workerdefine void @test28c(i8* %p, i1 %x, i8* noalias %t) { 1512*9880d681SAndroid Build Coastguard Workerentry: 1513*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1514*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %done 1515*9880d681SAndroid Build Coastguard Worker 1516*9880d681SAndroid Build Coastguard Workertrue: 1517*9880d681SAndroid Build Coastguard Worker call void @callee() 1518*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %p 1519*9880d681SAndroid Build Coastguard Worker br label %done 1520*9880d681SAndroid Build Coastguard Worker 1521*9880d681SAndroid Build Coastguard Workerdone: 1522*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %t 1523*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p), !clang.imprecise_release !0 1524*9880d681SAndroid Build Coastguard Worker ret void 1525*9880d681SAndroid Build Coastguard Worker} 1526*9880d681SAndroid Build Coastguard Worker 1527*9880d681SAndroid Build Coastguard Worker; Like test28. but with two releases. 1528*9880d681SAndroid Build Coastguard Worker 1529*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test29( 1530*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1531*9880d681SAndroid Build Coastguard Worker; CHECK: true: 1532*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain( 1533*9880d681SAndroid Build Coastguard Worker; CHECK: call void @callee() 1534*9880d681SAndroid Build Coastguard Worker; CHECK: store 1535*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 1536*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 1537*9880d681SAndroid Build Coastguard Worker; CHECK: done: 1538*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1539*9880d681SAndroid Build Coastguard Worker; CHECK: ohno: 1540*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1541*9880d681SAndroid Build Coastguard Worker; CHECK: } 1542*9880d681SAndroid Build Coastguard Workerdefine void @test29(i8* %p, i1 %x, i1 %y) { 1543*9880d681SAndroid Build Coastguard Workerentry: 1544*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1545*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %done 1546*9880d681SAndroid Build Coastguard Worker 1547*9880d681SAndroid Build Coastguard Workertrue: 1548*9880d681SAndroid Build Coastguard Worker call void @callee() 1549*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %p 1550*9880d681SAndroid Build Coastguard Worker br i1 %y, label %done, label %ohno 1551*9880d681SAndroid Build Coastguard Worker 1552*9880d681SAndroid Build Coastguard Workerdone: 1553*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1554*9880d681SAndroid Build Coastguard Worker ret void 1555*9880d681SAndroid Build Coastguard Worker 1556*9880d681SAndroid Build Coastguard Workerohno: 1557*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1558*9880d681SAndroid Build Coastguard Worker ret void 1559*9880d681SAndroid Build Coastguard Worker} 1560*9880d681SAndroid Build Coastguard Worker 1561*9880d681SAndroid Build Coastguard Worker; Basic case with the use and call in a diamond 1562*9880d681SAndroid Build Coastguard Worker; with an extra release. 1563*9880d681SAndroid Build Coastguard Worker 1564*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test30( 1565*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1566*9880d681SAndroid Build Coastguard Worker; CHECK: true: 1567*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain( 1568*9880d681SAndroid Build Coastguard Worker; CHECK: call void @callee() 1569*9880d681SAndroid Build Coastguard Worker; CHECK: store 1570*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 1571*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 1572*9880d681SAndroid Build Coastguard Worker; CHECK: false: 1573*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1574*9880d681SAndroid Build Coastguard Worker; CHECK: done: 1575*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1576*9880d681SAndroid Build Coastguard Worker; CHECK: ohno: 1577*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1578*9880d681SAndroid Build Coastguard Worker; CHECK: } 1579*9880d681SAndroid Build Coastguard Workerdefine void @test30(i8* %p, i1 %x, i1 %y, i1 %z) { 1580*9880d681SAndroid Build Coastguard Workerentry: 1581*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1582*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %false 1583*9880d681SAndroid Build Coastguard Worker 1584*9880d681SAndroid Build Coastguard Workertrue: 1585*9880d681SAndroid Build Coastguard Worker call void @callee() 1586*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %p 1587*9880d681SAndroid Build Coastguard Worker br i1 %y, label %done, label %ohno 1588*9880d681SAndroid Build Coastguard Worker 1589*9880d681SAndroid Build Coastguard Workerfalse: 1590*9880d681SAndroid Build Coastguard Worker br i1 %z, label %done, label %ohno 1591*9880d681SAndroid Build Coastguard Worker 1592*9880d681SAndroid Build Coastguard Workerdone: 1593*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1594*9880d681SAndroid Build Coastguard Worker ret void 1595*9880d681SAndroid Build Coastguard Worker 1596*9880d681SAndroid Build Coastguard Workerohno: 1597*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1598*9880d681SAndroid Build Coastguard Worker ret void 1599*9880d681SAndroid Build Coastguard Worker} 1600*9880d681SAndroid Build Coastguard Worker 1601*9880d681SAndroid Build Coastguard Worker; Basic case with a mergeable release. 1602*9880d681SAndroid Build Coastguard Worker 1603*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test31( 1604*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain(i8* %p) 1605*9880d681SAndroid Build Coastguard Worker; CHECK: call void @callee() 1606*9880d681SAndroid Build Coastguard Worker; CHECK: store 1607*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 1608*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 1609*9880d681SAndroid Build Coastguard Worker; CHECK: true: 1610*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 1611*9880d681SAndroid Build Coastguard Worker; CHECK: false: 1612*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 1613*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 1614*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 1615*9880d681SAndroid Build Coastguard Worker; CHECK: } 1616*9880d681SAndroid Build Coastguard Workerdefine void @test31(i8* %p, i1 %x) { 1617*9880d681SAndroid Build Coastguard Workerentry: 1618*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1619*9880d681SAndroid Build Coastguard Worker call void @callee() 1620*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %p 1621*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %false 1622*9880d681SAndroid Build Coastguard Workertrue: 1623*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1624*9880d681SAndroid Build Coastguard Worker ret void 1625*9880d681SAndroid Build Coastguard Workerfalse: 1626*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1627*9880d681SAndroid Build Coastguard Worker ret void 1628*9880d681SAndroid Build Coastguard Worker} 1629*9880d681SAndroid Build Coastguard Worker 1630*9880d681SAndroid Build Coastguard Worker; Don't consider bitcasts or getelementptrs direct uses. 1631*9880d681SAndroid Build Coastguard Worker 1632*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test32( 1633*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1634*9880d681SAndroid Build Coastguard Worker; CHECK: true: 1635*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain( 1636*9880d681SAndroid Build Coastguard Worker; CHECK: call void @callee() 1637*9880d681SAndroid Build Coastguard Worker; CHECK: store 1638*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 1639*9880d681SAndroid Build Coastguard Worker; CHECK: done: 1640*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1641*9880d681SAndroid Build Coastguard Worker; CHECK: } 1642*9880d681SAndroid Build Coastguard Workerdefine void @test32(i8* %p, i1 %x) { 1643*9880d681SAndroid Build Coastguard Workerentry: 1644*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1645*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %done 1646*9880d681SAndroid Build Coastguard Worker 1647*9880d681SAndroid Build Coastguard Workertrue: 1648*9880d681SAndroid Build Coastguard Worker call void @callee() 1649*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %p 1650*9880d681SAndroid Build Coastguard Worker br label %done 1651*9880d681SAndroid Build Coastguard Worker 1652*9880d681SAndroid Build Coastguard Workerdone: 1653*9880d681SAndroid Build Coastguard Worker %g = bitcast i8* %p to i8* 1654*9880d681SAndroid Build Coastguard Worker %h = getelementptr i8, i8* %g, i64 0 1655*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %g) 1656*9880d681SAndroid Build Coastguard Worker ret void 1657*9880d681SAndroid Build Coastguard Worker} 1658*9880d681SAndroid Build Coastguard Worker 1659*9880d681SAndroid Build Coastguard Worker; Do consider icmps to be direct uses. 1660*9880d681SAndroid Build Coastguard Worker 1661*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test33( 1662*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1663*9880d681SAndroid Build Coastguard Worker; CHECK: true: 1664*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain( 1665*9880d681SAndroid Build Coastguard Worker; CHECK: call void @callee() 1666*9880d681SAndroid Build Coastguard Worker; CHECK: icmp 1667*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 1668*9880d681SAndroid Build Coastguard Worker; CHECK: done: 1669*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1670*9880d681SAndroid Build Coastguard Worker; CHECK: } 1671*9880d681SAndroid Build Coastguard Workerdefine void @test33(i8* %p, i1 %x, i8* %y) { 1672*9880d681SAndroid Build Coastguard Workerentry: 1673*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1674*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %done 1675*9880d681SAndroid Build Coastguard Worker 1676*9880d681SAndroid Build Coastguard Workertrue: 1677*9880d681SAndroid Build Coastguard Worker call void @callee() 1678*9880d681SAndroid Build Coastguard Worker %v = icmp eq i8* %p, %y 1679*9880d681SAndroid Build Coastguard Worker br label %done 1680*9880d681SAndroid Build Coastguard Worker 1681*9880d681SAndroid Build Coastguard Workerdone: 1682*9880d681SAndroid Build Coastguard Worker %g = bitcast i8* %p to i8* 1683*9880d681SAndroid Build Coastguard Worker %h = getelementptr i8, i8* %g, i64 0 1684*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %g) 1685*9880d681SAndroid Build Coastguard Worker ret void 1686*9880d681SAndroid Build Coastguard Worker} 1687*9880d681SAndroid Build Coastguard Worker 1688*9880d681SAndroid Build Coastguard Worker; Delete retain,release if there's just a possible dec and we have imprecise 1689*9880d681SAndroid Build Coastguard Worker; releases. 1690*9880d681SAndroid Build Coastguard Worker 1691*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test34a( 1692*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain 1693*9880d681SAndroid Build Coastguard Worker; CHECK: true: 1694*9880d681SAndroid Build Coastguard Worker; CHECK: done: 1695*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 1696*9880d681SAndroid Build Coastguard Worker; CHECK: } 1697*9880d681SAndroid Build Coastguard Workerdefine void @test34a(i8* %p, i1 %x, i8* %y) { 1698*9880d681SAndroid Build Coastguard Workerentry: 1699*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1700*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %done 1701*9880d681SAndroid Build Coastguard Worker 1702*9880d681SAndroid Build Coastguard Workertrue: 1703*9880d681SAndroid Build Coastguard Worker call void @callee() 1704*9880d681SAndroid Build Coastguard Worker br label %done 1705*9880d681SAndroid Build Coastguard Worker 1706*9880d681SAndroid Build Coastguard Workerdone: 1707*9880d681SAndroid Build Coastguard Worker %g = bitcast i8* %p to i8* 1708*9880d681SAndroid Build Coastguard Worker %h = getelementptr i8, i8* %g, i64 0 1709*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %g) 1710*9880d681SAndroid Build Coastguard Worker ret void 1711*9880d681SAndroid Build Coastguard Worker} 1712*9880d681SAndroid Build Coastguard Worker 1713*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test34b( 1714*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1715*9880d681SAndroid Build Coastguard Worker; CHECK: } 1716*9880d681SAndroid Build Coastguard Workerdefine void @test34b(i8* %p, i1 %x, i8* %y) { 1717*9880d681SAndroid Build Coastguard Workerentry: 1718*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1719*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %done 1720*9880d681SAndroid Build Coastguard Worker 1721*9880d681SAndroid Build Coastguard Workertrue: 1722*9880d681SAndroid Build Coastguard Worker call void @callee() 1723*9880d681SAndroid Build Coastguard Worker br label %done 1724*9880d681SAndroid Build Coastguard Worker 1725*9880d681SAndroid Build Coastguard Workerdone: 1726*9880d681SAndroid Build Coastguard Worker %g = bitcast i8* %p to i8* 1727*9880d681SAndroid Build Coastguard Worker %h = getelementptr i8, i8* %g, i64 0 1728*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %g), !clang.imprecise_release !0 1729*9880d681SAndroid Build Coastguard Worker ret void 1730*9880d681SAndroid Build Coastguard Worker} 1731*9880d681SAndroid Build Coastguard Worker 1732*9880d681SAndroid Build Coastguard Worker 1733*9880d681SAndroid Build Coastguard Worker; Delete retain,release if there's just a use and we do not have a precise 1734*9880d681SAndroid Build Coastguard Worker; release. 1735*9880d681SAndroid Build Coastguard Worker 1736*9880d681SAndroid Build Coastguard Worker; Precise. 1737*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test35a( 1738*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 1739*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain 1740*9880d681SAndroid Build Coastguard Worker; CHECK: true: 1741*9880d681SAndroid Build Coastguard Worker; CHECK: done: 1742*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 1743*9880d681SAndroid Build Coastguard Worker; CHECK: } 1744*9880d681SAndroid Build Coastguard Workerdefine void @test35a(i8* %p, i1 %x, i8* %y) { 1745*9880d681SAndroid Build Coastguard Workerentry: 1746*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1747*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %done 1748*9880d681SAndroid Build Coastguard Worker 1749*9880d681SAndroid Build Coastguard Workertrue: 1750*9880d681SAndroid Build Coastguard Worker %v = icmp eq i8* %p, %y 1751*9880d681SAndroid Build Coastguard Worker br label %done 1752*9880d681SAndroid Build Coastguard Worker 1753*9880d681SAndroid Build Coastguard Workerdone: 1754*9880d681SAndroid Build Coastguard Worker %g = bitcast i8* %p to i8* 1755*9880d681SAndroid Build Coastguard Worker %h = getelementptr i8, i8* %g, i64 0 1756*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %g) 1757*9880d681SAndroid Build Coastguard Worker ret void 1758*9880d681SAndroid Build Coastguard Worker} 1759*9880d681SAndroid Build Coastguard Worker 1760*9880d681SAndroid Build Coastguard Worker; Imprecise. 1761*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test35b( 1762*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1763*9880d681SAndroid Build Coastguard Worker; CHECK: } 1764*9880d681SAndroid Build Coastguard Workerdefine void @test35b(i8* %p, i1 %x, i8* %y) { 1765*9880d681SAndroid Build Coastguard Workerentry: 1766*9880d681SAndroid Build Coastguard Worker %f0 = call i8* @objc_retain(i8* %p) 1767*9880d681SAndroid Build Coastguard Worker br i1 %x, label %true, label %done 1768*9880d681SAndroid Build Coastguard Worker 1769*9880d681SAndroid Build Coastguard Workertrue: 1770*9880d681SAndroid Build Coastguard Worker %v = icmp eq i8* %p, %y 1771*9880d681SAndroid Build Coastguard Worker br label %done 1772*9880d681SAndroid Build Coastguard Worker 1773*9880d681SAndroid Build Coastguard Workerdone: 1774*9880d681SAndroid Build Coastguard Worker %g = bitcast i8* %p to i8* 1775*9880d681SAndroid Build Coastguard Worker %h = getelementptr i8, i8* %g, i64 0 1776*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %g), !clang.imprecise_release !0 1777*9880d681SAndroid Build Coastguard Worker ret void 1778*9880d681SAndroid Build Coastguard Worker} 1779*9880d681SAndroid Build Coastguard Worker 1780*9880d681SAndroid Build Coastguard Worker; Delete a retain,release if there's no actual use and we have precise release. 1781*9880d681SAndroid Build Coastguard Worker 1782*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test36a( 1783*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 1784*9880d681SAndroid Build Coastguard Worker; CHECK: call void @callee() 1785*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1786*9880d681SAndroid Build Coastguard Worker; CHECK: call void @callee() 1787*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 1788*9880d681SAndroid Build Coastguard Worker; CHECK: } 1789*9880d681SAndroid Build Coastguard Workerdefine void @test36a(i8* %p) { 1790*9880d681SAndroid Build Coastguard Workerentry: 1791*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 1792*9880d681SAndroid Build Coastguard Worker call void @callee() 1793*9880d681SAndroid Build Coastguard Worker call void @callee() 1794*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1795*9880d681SAndroid Build Coastguard Worker ret void 1796*9880d681SAndroid Build Coastguard Worker} 1797*9880d681SAndroid Build Coastguard Worker 1798*9880d681SAndroid Build Coastguard Worker; Like test36, but with metadata. 1799*9880d681SAndroid Build Coastguard Worker 1800*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test36b( 1801*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1802*9880d681SAndroid Build Coastguard Worker; CHECK: } 1803*9880d681SAndroid Build Coastguard Workerdefine void @test36b(i8* %p) { 1804*9880d681SAndroid Build Coastguard Workerentry: 1805*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 1806*9880d681SAndroid Build Coastguard Worker call void @callee() 1807*9880d681SAndroid Build Coastguard Worker call void @callee() 1808*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p), !clang.imprecise_release !0 1809*9880d681SAndroid Build Coastguard Worker ret void 1810*9880d681SAndroid Build Coastguard Worker} 1811*9880d681SAndroid Build Coastguard Worker 1812*9880d681SAndroid Build Coastguard Worker; Be aggressive about analyzing phis to eliminate possible uses. 1813*9880d681SAndroid Build Coastguard Worker 1814*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test38( 1815*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1816*9880d681SAndroid Build Coastguard Worker; CHECK: } 1817*9880d681SAndroid Build Coastguard Workerdefine void @test38(i8* %p, i1 %u, i1 %m, i8* %z, i8* %y, i8* %x, i8* %w) { 1818*9880d681SAndroid Build Coastguard Workerentry: 1819*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 1820*9880d681SAndroid Build Coastguard Worker br i1 %u, label %true, label %false 1821*9880d681SAndroid Build Coastguard Workertrue: 1822*9880d681SAndroid Build Coastguard Worker br i1 %m, label %a, label %b 1823*9880d681SAndroid Build Coastguard Workerfalse: 1824*9880d681SAndroid Build Coastguard Worker br i1 %m, label %c, label %d 1825*9880d681SAndroid Build Coastguard Workera: 1826*9880d681SAndroid Build Coastguard Worker br label %e 1827*9880d681SAndroid Build Coastguard Workerb: 1828*9880d681SAndroid Build Coastguard Worker br label %e 1829*9880d681SAndroid Build Coastguard Workerc: 1830*9880d681SAndroid Build Coastguard Worker br label %f 1831*9880d681SAndroid Build Coastguard Workerd: 1832*9880d681SAndroid Build Coastguard Worker br label %f 1833*9880d681SAndroid Build Coastguard Workere: 1834*9880d681SAndroid Build Coastguard Worker %j = phi i8* [ %z, %a ], [ %y, %b ] 1835*9880d681SAndroid Build Coastguard Worker br label %g 1836*9880d681SAndroid Build Coastguard Workerf: 1837*9880d681SAndroid Build Coastguard Worker %k = phi i8* [ %w, %c ], [ %x, %d ] 1838*9880d681SAndroid Build Coastguard Worker br label %g 1839*9880d681SAndroid Build Coastguard Workerg: 1840*9880d681SAndroid Build Coastguard Worker %h = phi i8* [ %j, %e ], [ %k, %f ] 1841*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %h) 1842*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p), !clang.imprecise_release !0 1843*9880d681SAndroid Build Coastguard Worker ret void 1844*9880d681SAndroid Build Coastguard Worker} 1845*9880d681SAndroid Build Coastguard Worker 1846*9880d681SAndroid Build Coastguard Worker; Delete retain,release pairs around loops. 1847*9880d681SAndroid Build Coastguard Worker 1848*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test39( 1849*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1850*9880d681SAndroid Build Coastguard Worker; CHECK: } 1851*9880d681SAndroid Build Coastguard Workerdefine void @test39(i8* %p) { 1852*9880d681SAndroid Build Coastguard Workerentry: 1853*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %p) 1854*9880d681SAndroid Build Coastguard Worker br label %loop 1855*9880d681SAndroid Build Coastguard Worker 1856*9880d681SAndroid Build Coastguard Workerloop: ; preds = %loop, %entry 1857*9880d681SAndroid Build Coastguard Worker br i1 undef, label %loop, label %exit 1858*9880d681SAndroid Build Coastguard Worker 1859*9880d681SAndroid Build Coastguard Workerexit: ; preds = %loop 1860*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %0), !clang.imprecise_release !0 1861*9880d681SAndroid Build Coastguard Worker ret void 1862*9880d681SAndroid Build Coastguard Worker} 1863*9880d681SAndroid Build Coastguard Worker 1864*9880d681SAndroid Build Coastguard Worker; Delete retain,release pairs around loops containing uses. 1865*9880d681SAndroid Build Coastguard Worker 1866*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test39b( 1867*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1868*9880d681SAndroid Build Coastguard Worker; CHECK: } 1869*9880d681SAndroid Build Coastguard Workerdefine void @test39b(i8* %p) { 1870*9880d681SAndroid Build Coastguard Workerentry: 1871*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %p) 1872*9880d681SAndroid Build Coastguard Worker br label %loop 1873*9880d681SAndroid Build Coastguard Worker 1874*9880d681SAndroid Build Coastguard Workerloop: ; preds = %loop, %entry 1875*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %0 1876*9880d681SAndroid Build Coastguard Worker br i1 undef, label %loop, label %exit 1877*9880d681SAndroid Build Coastguard Worker 1878*9880d681SAndroid Build Coastguard Workerexit: ; preds = %loop 1879*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %0), !clang.imprecise_release !0 1880*9880d681SAndroid Build Coastguard Worker ret void 1881*9880d681SAndroid Build Coastguard Worker} 1882*9880d681SAndroid Build Coastguard Worker 1883*9880d681SAndroid Build Coastguard Worker; Delete retain,release pairs around loops containing potential decrements. 1884*9880d681SAndroid Build Coastguard Worker 1885*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test39c( 1886*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1887*9880d681SAndroid Build Coastguard Worker; CHECK: } 1888*9880d681SAndroid Build Coastguard Workerdefine void @test39c(i8* %p) { 1889*9880d681SAndroid Build Coastguard Workerentry: 1890*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %p) 1891*9880d681SAndroid Build Coastguard Worker br label %loop 1892*9880d681SAndroid Build Coastguard Worker 1893*9880d681SAndroid Build Coastguard Workerloop: ; preds = %loop, %entry 1894*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %0) 1895*9880d681SAndroid Build Coastguard Worker br i1 undef, label %loop, label %exit 1896*9880d681SAndroid Build Coastguard Worker 1897*9880d681SAndroid Build Coastguard Workerexit: ; preds = %loop 1898*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %0), !clang.imprecise_release !0 1899*9880d681SAndroid Build Coastguard Worker ret void 1900*9880d681SAndroid Build Coastguard Worker} 1901*9880d681SAndroid Build Coastguard Worker 1902*9880d681SAndroid Build Coastguard Worker; Delete retain,release pairs around loops even if 1903*9880d681SAndroid Build Coastguard Worker; the successors are in a different order. 1904*9880d681SAndroid Build Coastguard Worker 1905*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test40( 1906*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 1907*9880d681SAndroid Build Coastguard Worker; CHECK: } 1908*9880d681SAndroid Build Coastguard Workerdefine void @test40(i8* %p) { 1909*9880d681SAndroid Build Coastguard Workerentry: 1910*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %p) 1911*9880d681SAndroid Build Coastguard Worker br label %loop 1912*9880d681SAndroid Build Coastguard Worker 1913*9880d681SAndroid Build Coastguard Workerloop: ; preds = %loop, %entry 1914*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %0) 1915*9880d681SAndroid Build Coastguard Worker br i1 undef, label %exit, label %loop 1916*9880d681SAndroid Build Coastguard Worker 1917*9880d681SAndroid Build Coastguard Workerexit: ; preds = %loop 1918*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %0), !clang.imprecise_release !0 1919*9880d681SAndroid Build Coastguard Worker ret void 1920*9880d681SAndroid Build Coastguard Worker} 1921*9880d681SAndroid Build Coastguard Worker 1922*9880d681SAndroid Build Coastguard Worker; Do the known-incremented retain+release elimination even if the pointer 1923*9880d681SAndroid Build Coastguard Worker; is also autoreleased. 1924*9880d681SAndroid Build Coastguard Worker 1925*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test42( 1926*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 1927*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_retain(i8* %p) 1928*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_autorelease(i8* %p) 1929*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %p) 1930*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %p) 1931*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %p) 1932*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %p) 1933*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %p) 1934*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 1935*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 1936*9880d681SAndroid Build Coastguard Workerdefine void @test42(i8* %p) { 1937*9880d681SAndroid Build Coastguard Workerentry: 1938*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 1939*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* %p) 1940*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 1941*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %p) 1942*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %p) 1943*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1944*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %p) 1945*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %p) 1946*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1947*9880d681SAndroid Build Coastguard Worker ret void 1948*9880d681SAndroid Build Coastguard Worker} 1949*9880d681SAndroid Build Coastguard Worker 1950*9880d681SAndroid Build Coastguard Worker; Don't the known-incremented retain+release elimination if the pointer is 1951*9880d681SAndroid Build Coastguard Worker; autoreleased and there's an autoreleasePoolPop. 1952*9880d681SAndroid Build Coastguard Worker 1953*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test43( 1954*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 1955*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_retain(i8* %p) 1956*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_autorelease(i8* %p) 1957*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_retain 1958*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %p) 1959*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %p) 1960*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_autoreleasePoolPop(i8* undef) 1961*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release 1962*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 1963*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 1964*9880d681SAndroid Build Coastguard Workerdefine void @test43(i8* %p) { 1965*9880d681SAndroid Build Coastguard Workerentry: 1966*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 1967*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* %p) 1968*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 1969*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %p) 1970*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %p) 1971*9880d681SAndroid Build Coastguard Worker call void @objc_autoreleasePoolPop(i8* undef) 1972*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1973*9880d681SAndroid Build Coastguard Worker ret void 1974*9880d681SAndroid Build Coastguard Worker} 1975*9880d681SAndroid Build Coastguard Worker 1976*9880d681SAndroid Build Coastguard Worker; Do the known-incremented retain+release elimination if the pointer is 1977*9880d681SAndroid Build Coastguard Worker; autoreleased and there's an autoreleasePoolPush. 1978*9880d681SAndroid Build Coastguard Worker 1979*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test43b( 1980*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 1981*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_retain(i8* %p) 1982*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_autorelease(i8* %p) 1983*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %p) 1984*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %p) 1985*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_autoreleasePoolPush() 1986*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %p) 1987*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release 1988*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 1989*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 1990*9880d681SAndroid Build Coastguard Workerdefine void @test43b(i8* %p) { 1991*9880d681SAndroid Build Coastguard Workerentry: 1992*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 1993*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* %p) 1994*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 1995*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %p) 1996*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %p) 1997*9880d681SAndroid Build Coastguard Worker call i8* @objc_autoreleasePoolPush() 1998*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 1999*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %p) 2000*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 2001*9880d681SAndroid Build Coastguard Worker ret void 2002*9880d681SAndroid Build Coastguard Worker} 2003*9880d681SAndroid Build Coastguard Worker 2004*9880d681SAndroid Build Coastguard Worker; Do retain+release elimination for non-provenance pointers. 2005*9880d681SAndroid Build Coastguard Worker 2006*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test44( 2007*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: objc_ 2008*9880d681SAndroid Build Coastguard Worker; CHECK: } 2009*9880d681SAndroid Build Coastguard Workerdefine void @test44(i8** %pp) { 2010*9880d681SAndroid Build Coastguard Worker %p = load i8*, i8** %pp 2011*9880d681SAndroid Build Coastguard Worker %q = call i8* @objc_retain(i8* %p) 2012*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %q) 2013*9880d681SAndroid Build Coastguard Worker ret void 2014*9880d681SAndroid Build Coastguard Worker} 2015*9880d681SAndroid Build Coastguard Worker 2016*9880d681SAndroid Build Coastguard Worker; Don't delete retain+release with an unknown-provenance 2017*9880d681SAndroid Build Coastguard Worker; may-alias objc_release between them. 2018*9880d681SAndroid Build Coastguard Worker 2019*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test45( 2020*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain(i8* %p) 2021*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %q) 2022*9880d681SAndroid Build Coastguard Worker; CHECK: call void @use_pointer(i8* %p) 2023*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %p) 2024*9880d681SAndroid Build Coastguard Worker; CHECK: } 2025*9880d681SAndroid Build Coastguard Workerdefine void @test45(i8** %pp, i8** %qq) { 2026*9880d681SAndroid Build Coastguard Worker %p = load i8*, i8** %pp 2027*9880d681SAndroid Build Coastguard Worker %q = load i8*, i8** %qq 2028*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 2029*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %q) 2030*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %p) 2031*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 2032*9880d681SAndroid Build Coastguard Worker ret void 2033*9880d681SAndroid Build Coastguard Worker} 2034*9880d681SAndroid Build Coastguard Worker 2035*9880d681SAndroid Build Coastguard Worker; Don't delete retain and autorelease here. 2036*9880d681SAndroid Build Coastguard Worker 2037*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test46( 2038*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %p) [[NUW]] 2039*9880d681SAndroid Build Coastguard Worker; CHECK: true: 2040*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autorelease(i8* %p) [[NUW]] 2041*9880d681SAndroid Build Coastguard Worker; CHECK: } 2042*9880d681SAndroid Build Coastguard Workerdefine void @test46(i8* %p, i1 %a) { 2043*9880d681SAndroid Build Coastguard Workerentry: 2044*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 2045*9880d681SAndroid Build Coastguard Worker br i1 %a, label %true, label %false 2046*9880d681SAndroid Build Coastguard Worker 2047*9880d681SAndroid Build Coastguard Workertrue: 2048*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* %p) 2049*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %p) 2050*9880d681SAndroid Build Coastguard Worker ret void 2051*9880d681SAndroid Build Coastguard Worker 2052*9880d681SAndroid Build Coastguard Workerfalse: 2053*9880d681SAndroid Build Coastguard Worker ret void 2054*9880d681SAndroid Build Coastguard Worker} 2055*9880d681SAndroid Build Coastguard Worker 2056*9880d681SAndroid Build Coastguard Worker; Delete no-op cast calls. 2057*9880d681SAndroid Build Coastguard Worker 2058*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test47( 2059*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call 2060*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8* %p 2061*9880d681SAndroid Build Coastguard Worker; CHECK: } 2062*9880d681SAndroid Build Coastguard Workerdefine i8* @test47(i8* %p) nounwind { 2063*9880d681SAndroid Build Coastguard Worker %x = call i8* @objc_retainedObject(i8* %p) 2064*9880d681SAndroid Build Coastguard Worker ret i8* %x 2065*9880d681SAndroid Build Coastguard Worker} 2066*9880d681SAndroid Build Coastguard Worker 2067*9880d681SAndroid Build Coastguard Worker; Delete no-op cast calls. 2068*9880d681SAndroid Build Coastguard Worker 2069*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test48( 2070*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call 2071*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8* %p 2072*9880d681SAndroid Build Coastguard Worker; CHECK: } 2073*9880d681SAndroid Build Coastguard Workerdefine i8* @test48(i8* %p) nounwind { 2074*9880d681SAndroid Build Coastguard Worker %x = call i8* @objc_unretainedObject(i8* %p) 2075*9880d681SAndroid Build Coastguard Worker ret i8* %x 2076*9880d681SAndroid Build Coastguard Worker} 2077*9880d681SAndroid Build Coastguard Worker 2078*9880d681SAndroid Build Coastguard Worker; Delete no-op cast calls. 2079*9880d681SAndroid Build Coastguard Worker 2080*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test49( 2081*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call 2082*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8* %p 2083*9880d681SAndroid Build Coastguard Worker; CHECK: } 2084*9880d681SAndroid Build Coastguard Workerdefine i8* @test49(i8* %p) nounwind { 2085*9880d681SAndroid Build Coastguard Worker %x = call i8* @objc_unretainedPointer(i8* %p) 2086*9880d681SAndroid Build Coastguard Worker ret i8* %x 2087*9880d681SAndroid Build Coastguard Worker} 2088*9880d681SAndroid Build Coastguard Worker 2089*9880d681SAndroid Build Coastguard Worker; Do delete retain+release with intervening stores of the address value if we 2090*9880d681SAndroid Build Coastguard Worker; have imprecise release attached to objc_release. 2091*9880d681SAndroid Build Coastguard Worker 2092*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test50a( 2093*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_retain 2094*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @callee 2095*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store 2096*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release 2097*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 2098*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 2099*9880d681SAndroid Build Coastguard Workerdefine void @test50a(i8* %p, i8** %pp) { 2100*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 2101*9880d681SAndroid Build Coastguard Worker call void @callee() 2102*9880d681SAndroid Build Coastguard Worker store i8* %p, i8** %pp 2103*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 2104*9880d681SAndroid Build Coastguard Worker ret void 2105*9880d681SAndroid Build Coastguard Worker} 2106*9880d681SAndroid Build Coastguard Worker 2107*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test50b( 2108*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 2109*9880d681SAndroid Build Coastguard Worker; CHECK: } 2110*9880d681SAndroid Build Coastguard Workerdefine void @test50b(i8* %p, i8** %pp) { 2111*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 2112*9880d681SAndroid Build Coastguard Worker call void @callee() 2113*9880d681SAndroid Build Coastguard Worker store i8* %p, i8** %pp 2114*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p), !clang.imprecise_release !0 2115*9880d681SAndroid Build Coastguard Worker ret void 2116*9880d681SAndroid Build Coastguard Worker} 2117*9880d681SAndroid Build Coastguard Worker 2118*9880d681SAndroid Build Coastguard Worker 2119*9880d681SAndroid Build Coastguard Worker; Don't delete retain+release with intervening stores through the 2120*9880d681SAndroid Build Coastguard Worker; address value. 2121*9880d681SAndroid Build Coastguard Worker 2122*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test51a( 2123*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain(i8* %p) 2124*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %p) 2125*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 2126*9880d681SAndroid Build Coastguard Worker; CHECK: } 2127*9880d681SAndroid Build Coastguard Workerdefine void @test51a(i8* %p) { 2128*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 2129*9880d681SAndroid Build Coastguard Worker call void @callee() 2130*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %p 2131*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 2132*9880d681SAndroid Build Coastguard Worker ret void 2133*9880d681SAndroid Build Coastguard Worker} 2134*9880d681SAndroid Build Coastguard Worker 2135*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test51b( 2136*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain(i8* %p) 2137*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %p) 2138*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 2139*9880d681SAndroid Build Coastguard Worker; CHECK: } 2140*9880d681SAndroid Build Coastguard Workerdefine void @test51b(i8* %p) { 2141*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %p) 2142*9880d681SAndroid Build Coastguard Worker call void @callee() 2143*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %p 2144*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p), !clang.imprecise_release !0 2145*9880d681SAndroid Build Coastguard Worker ret void 2146*9880d681SAndroid Build Coastguard Worker} 2147*9880d681SAndroid Build Coastguard Worker 2148*9880d681SAndroid Build Coastguard Worker; Don't delete retain+release with intervening use of a pointer of 2149*9880d681SAndroid Build Coastguard Worker; unknown provenance. 2150*9880d681SAndroid Build Coastguard Worker 2151*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test52a( 2152*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain 2153*9880d681SAndroid Build Coastguard Worker; CHECK: call void @callee() 2154*9880d681SAndroid Build Coastguard Worker; CHECK: call void @use_pointer(i8* %z) 2155*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 2156*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 2157*9880d681SAndroid Build Coastguard Worker; CHECK: } 2158*9880d681SAndroid Build Coastguard Workerdefine void @test52a(i8** %zz, i8** %pp) { 2159*9880d681SAndroid Build Coastguard Worker %p = load i8*, i8** %pp 2160*9880d681SAndroid Build Coastguard Worker %1 = call i8* @objc_retain(i8* %p) 2161*9880d681SAndroid Build Coastguard Worker call void @callee() 2162*9880d681SAndroid Build Coastguard Worker %z = load i8*, i8** %zz 2163*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %z) 2164*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 2165*9880d681SAndroid Build Coastguard Worker ret void 2166*9880d681SAndroid Build Coastguard Worker} 2167*9880d681SAndroid Build Coastguard Worker 2168*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test52b( 2169*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain 2170*9880d681SAndroid Build Coastguard Worker; CHECK: call void @callee() 2171*9880d681SAndroid Build Coastguard Worker; CHECK: call void @use_pointer(i8* %z) 2172*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 2173*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 2174*9880d681SAndroid Build Coastguard Worker; CHECK: } 2175*9880d681SAndroid Build Coastguard Workerdefine void @test52b(i8** %zz, i8** %pp) { 2176*9880d681SAndroid Build Coastguard Worker %p = load i8*, i8** %pp 2177*9880d681SAndroid Build Coastguard Worker %1 = call i8* @objc_retain(i8* %p) 2178*9880d681SAndroid Build Coastguard Worker call void @callee() 2179*9880d681SAndroid Build Coastguard Worker %z = load i8*, i8** %zz 2180*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %z) 2181*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p), !clang.imprecise_release !0 2182*9880d681SAndroid Build Coastguard Worker ret void 2183*9880d681SAndroid Build Coastguard Worker} 2184*9880d681SAndroid Build Coastguard Worker 2185*9880d681SAndroid Build Coastguard Worker; Like test52, but the pointer has function type, so it's assumed to 2186*9880d681SAndroid Build Coastguard Worker; be not reference counted. 2187*9880d681SAndroid Build Coastguard Worker; Oops. That's wrong. Clang sometimes uses function types gratuitously. 2188*9880d681SAndroid Build Coastguard Worker; See rdar://10551239. 2189*9880d681SAndroid Build Coastguard Worker 2190*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test53( 2191*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_ 2192*9880d681SAndroid Build Coastguard Worker; CHECK: } 2193*9880d681SAndroid Build Coastguard Workerdefine void @test53(void ()** %zz, i8** %pp) { 2194*9880d681SAndroid Build Coastguard Worker %p = load i8*, i8** %pp 2195*9880d681SAndroid Build Coastguard Worker %1 = call i8* @objc_retain(i8* %p) 2196*9880d681SAndroid Build Coastguard Worker call void @callee() 2197*9880d681SAndroid Build Coastguard Worker %z = load void ()*, void ()** %zz 2198*9880d681SAndroid Build Coastguard Worker call void @callee_fnptr(void ()* %z) 2199*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %p) 2200*9880d681SAndroid Build Coastguard Worker ret void 2201*9880d681SAndroid Build Coastguard Worker} 2202*9880d681SAndroid Build Coastguard Worker 2203*9880d681SAndroid Build Coastguard Worker; Convert autorelease to release if the value is unused. 2204*9880d681SAndroid Build Coastguard Worker 2205*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test54( 2206*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @returner() 2207*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %t) [[NUW]], !clang.imprecise_release ![[RELEASE]] 2208*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 2209*9880d681SAndroid Build Coastguard Worker; CHECK: } 2210*9880d681SAndroid Build Coastguard Workerdefine void @test54() { 2211*9880d681SAndroid Build Coastguard Worker %t = call i8* @returner() 2212*9880d681SAndroid Build Coastguard Worker call i8* @objc_autorelease(i8* %t) 2213*9880d681SAndroid Build Coastguard Worker ret void 2214*9880d681SAndroid Build Coastguard Worker} 2215*9880d681SAndroid Build Coastguard Worker 2216*9880d681SAndroid Build Coastguard Worker; Nested retain+release pairs. Delete them both. 2217*9880d681SAndroid Build Coastguard Worker 2218*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test55( 2219*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc 2220*9880d681SAndroid Build Coastguard Worker; CHECK: } 2221*9880d681SAndroid Build Coastguard Workerdefine void @test55(i8* %x) { 2222*9880d681SAndroid Build Coastguard Workerentry: 2223*9880d681SAndroid Build Coastguard Worker %0 = call i8* @objc_retain(i8* %x) nounwind 2224*9880d681SAndroid Build Coastguard Worker %1 = call i8* @objc_retain(i8* %x) nounwind 2225*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 2226*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 2227*9880d681SAndroid Build Coastguard Worker ret void 2228*9880d681SAndroid Build Coastguard Worker} 2229*9880d681SAndroid Build Coastguard Worker 2230*9880d681SAndroid Build Coastguard Worker; Nested retain+release pairs where the inner pair depends 2231*9880d681SAndroid Build Coastguard Worker; on the outer pair to be removed, and then the outer pair 2232*9880d681SAndroid Build Coastguard Worker; can be partially eliminated. Plus an extra outer pair to 2233*9880d681SAndroid Build Coastguard Worker; eliminate, for fun. 2234*9880d681SAndroid Build Coastguard Worker 2235*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test56( 2236*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc 2237*9880d681SAndroid Build Coastguard Worker; CHECK: if.then: 2238*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) [[NUW]] 2239*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call void @use_pointer(i8* %x) 2240*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call void @use_pointer(i8* %x) 2241*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call void @objc_release(i8* %x) [[NUW]], !clang.imprecise_release ![[RELEASE]] 2242*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %if.end 2243*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc 2244*9880d681SAndroid Build Coastguard Worker; CHECK: } 2245*9880d681SAndroid Build Coastguard Workerdefine void @test56(i8* %x, i32 %n) { 2246*9880d681SAndroid Build Coastguard Workerentry: 2247*9880d681SAndroid Build Coastguard Worker %0 = tail call i8* @objc_retain(i8* %x) nounwind 2248*9880d681SAndroid Build Coastguard Worker %1 = tail call i8* @objc_retain(i8* %0) nounwind 2249*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %n, 0 2250*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.end, label %if.then 2251*9880d681SAndroid Build Coastguard Worker 2252*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 2253*9880d681SAndroid Build Coastguard Worker %2 = tail call i8* @objc_retain(i8* %1) nounwind 2254*9880d681SAndroid Build Coastguard Worker tail call void @use_pointer(i8* %2) 2255*9880d681SAndroid Build Coastguard Worker tail call void @use_pointer(i8* %2) 2256*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %2) nounwind, !clang.imprecise_release !0 2257*9880d681SAndroid Build Coastguard Worker br label %if.end 2258*9880d681SAndroid Build Coastguard Worker 2259*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %entry, %if.then 2260*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0 2261*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0 2262*9880d681SAndroid Build Coastguard Worker ret void 2263*9880d681SAndroid Build Coastguard Worker} 2264*9880d681SAndroid Build Coastguard Worker 2265*9880d681SAndroid Build Coastguard Worker; When there are adjacent retain+release pairs, the first one is known 2266*9880d681SAndroid Build Coastguard Worker; unnecessary because the presence of the second one means that the first one 2267*9880d681SAndroid Build Coastguard Worker; won't be deleting the object. 2268*9880d681SAndroid Build Coastguard Worker 2269*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test57( 2270*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 2271*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call i8* @objc_retain(i8* %x) [[NUW]] 2272*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %x) 2273*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %x) 2274*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call i8* @objc_retain(i8* %x) [[NUW]] 2275*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %x) 2276*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %x) 2277*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %x) [[NUW]] 2278*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 2279*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 2280*9880d681SAndroid Build Coastguard Workerdefine void @test57(i8* %x) nounwind { 2281*9880d681SAndroid Build Coastguard Workerentry: 2282*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 2283*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 2284*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 2285*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 2286*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 2287*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 2288*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 2289*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 2290*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 2291*9880d681SAndroid Build Coastguard Worker ret void 2292*9880d681SAndroid Build Coastguard Worker} 2293*9880d681SAndroid Build Coastguard Worker 2294*9880d681SAndroid Build Coastguard Worker; An adjacent retain+release pair is sufficient even if it will be 2295*9880d681SAndroid Build Coastguard Worker; removed itself. 2296*9880d681SAndroid Build Coastguard Worker 2297*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test58( 2298*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 2299*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: @objc_retain 2300*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %x) 2301*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %x) 2302*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 2303*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 2304*9880d681SAndroid Build Coastguard Workerdefine void @test58(i8* %x) nounwind { 2305*9880d681SAndroid Build Coastguard Workerentry: 2306*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 2307*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 2308*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 2309*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 2310*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 2311*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) nounwind 2312*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 2313*9880d681SAndroid Build Coastguard Worker ret void 2314*9880d681SAndroid Build Coastguard Worker} 2315*9880d681SAndroid Build Coastguard Worker 2316*9880d681SAndroid Build Coastguard Worker; Don't delete the second retain+release pair in an adjacent set. 2317*9880d681SAndroid Build Coastguard Worker 2318*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test59( 2319*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 2320*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) [[NUW]] 2321*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %x) 2322*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %x) 2323*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %x) [[NUW]] 2324*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 2325*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 2326*9880d681SAndroid Build Coastguard Workerdefine void @test59(i8* %x) nounwind { 2327*9880d681SAndroid Build Coastguard Workerentry: 2328*9880d681SAndroid Build Coastguard Worker %a = call i8* @objc_retain(i8* %x) nounwind 2329*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 2330*9880d681SAndroid Build Coastguard Worker %b = call i8* @objc_retain(i8* %x) nounwind 2331*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 2332*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 2333*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) nounwind 2334*9880d681SAndroid Build Coastguard Worker ret void 2335*9880d681SAndroid Build Coastguard Worker} 2336*9880d681SAndroid Build Coastguard Worker 2337*9880d681SAndroid Build Coastguard Worker; Constant pointers to objects don't need reference counting. 2338*9880d681SAndroid Build Coastguard Worker 2339*9880d681SAndroid Build Coastguard Worker@constptr = external constant i8* 2340*9880d681SAndroid Build Coastguard Worker@something = external global i8* 2341*9880d681SAndroid Build Coastguard Worker 2342*9880d681SAndroid Build Coastguard Worker; We have a precise lifetime retain/release here. We can not remove them since 2343*9880d681SAndroid Build Coastguard Worker; @something is not constant. 2344*9880d681SAndroid Build Coastguard Worker 2345*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test60a( 2346*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain 2347*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release 2348*9880d681SAndroid Build Coastguard Worker; CHECK: } 2349*9880d681SAndroid Build Coastguard Workerdefine void @test60a() { 2350*9880d681SAndroid Build Coastguard Worker %t = load i8*, i8** @constptr 2351*9880d681SAndroid Build Coastguard Worker %s = load i8*, i8** @something 2352*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %s) 2353*9880d681SAndroid Build Coastguard Worker call void @callee() 2354*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %t) 2355*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %s) 2356*9880d681SAndroid Build Coastguard Worker ret void 2357*9880d681SAndroid Build Coastguard Worker} 2358*9880d681SAndroid Build Coastguard Worker 2359*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test60b( 2360*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain 2361*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call i8* @objc_retain 2362*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call i8* @objc_release 2363*9880d681SAndroid Build Coastguard Worker; CHECK: } 2364*9880d681SAndroid Build Coastguard Workerdefine void @test60b() { 2365*9880d681SAndroid Build Coastguard Worker %t = load i8*, i8** @constptr 2366*9880d681SAndroid Build Coastguard Worker %s = load i8*, i8** @something 2367*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %t) 2368*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %t) 2369*9880d681SAndroid Build Coastguard Worker call void @callee() 2370*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %s) 2371*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %t) 2372*9880d681SAndroid Build Coastguard Worker ret void 2373*9880d681SAndroid Build Coastguard Worker} 2374*9880d681SAndroid Build Coastguard Worker 2375*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test60c( 2376*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 2377*9880d681SAndroid Build Coastguard Worker; CHECK: } 2378*9880d681SAndroid Build Coastguard Workerdefine void @test60c() { 2379*9880d681SAndroid Build Coastguard Worker %t = load i8*, i8** @constptr 2380*9880d681SAndroid Build Coastguard Worker %s = load i8*, i8** @something 2381*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %t) 2382*9880d681SAndroid Build Coastguard Worker call void @callee() 2383*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %s) 2384*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %t), !clang.imprecise_release !0 2385*9880d681SAndroid Build Coastguard Worker ret void 2386*9880d681SAndroid Build Coastguard Worker} 2387*9880d681SAndroid Build Coastguard Worker 2388*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test60d( 2389*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 2390*9880d681SAndroid Build Coastguard Worker; CHECK: } 2391*9880d681SAndroid Build Coastguard Workerdefine void @test60d() { 2392*9880d681SAndroid Build Coastguard Worker %t = load i8*, i8** @constptr 2393*9880d681SAndroid Build Coastguard Worker %s = load i8*, i8** @something 2394*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %t) 2395*9880d681SAndroid Build Coastguard Worker call void @callee() 2396*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %s) 2397*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %t) 2398*9880d681SAndroid Build Coastguard Worker ret void 2399*9880d681SAndroid Build Coastguard Worker} 2400*9880d681SAndroid Build Coastguard Worker 2401*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test60e( 2402*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 2403*9880d681SAndroid Build Coastguard Worker; CHECK: } 2404*9880d681SAndroid Build Coastguard Workerdefine void @test60e() { 2405*9880d681SAndroid Build Coastguard Worker %t = load i8*, i8** @constptr 2406*9880d681SAndroid Build Coastguard Worker %s = load i8*, i8** @something 2407*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %t) 2408*9880d681SAndroid Build Coastguard Worker call void @callee() 2409*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %s) 2410*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %t), !clang.imprecise_release !0 2411*9880d681SAndroid Build Coastguard Worker ret void 2412*9880d681SAndroid Build Coastguard Worker} 2413*9880d681SAndroid Build Coastguard Worker 2414*9880d681SAndroid Build Coastguard Worker; Constant pointers to objects don't need to be considered related to other 2415*9880d681SAndroid Build Coastguard Worker; pointers. 2416*9880d681SAndroid Build Coastguard Worker 2417*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test61( 2418*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 2419*9880d681SAndroid Build Coastguard Worker; CHECK: } 2420*9880d681SAndroid Build Coastguard Workerdefine void @test61() { 2421*9880d681SAndroid Build Coastguard Worker %t = load i8*, i8** @constptr 2422*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %t) 2423*9880d681SAndroid Build Coastguard Worker call void @callee() 2424*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %t) 2425*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %t) 2426*9880d681SAndroid Build Coastguard Worker ret void 2427*9880d681SAndroid Build Coastguard Worker} 2428*9880d681SAndroid Build Coastguard Worker 2429*9880d681SAndroid Build Coastguard Worker; Delete a retain matched by releases when one is inside the loop and the 2430*9880d681SAndroid Build Coastguard Worker; other is outside the loop. 2431*9880d681SAndroid Build Coastguard Worker 2432*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test62( 2433*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 2434*9880d681SAndroid Build Coastguard Worker; CHECK: } 2435*9880d681SAndroid Build Coastguard Workerdefine void @test62(i8* %x, i1* %p) nounwind { 2436*9880d681SAndroid Build Coastguard Workerentry: 2437*9880d681SAndroid Build Coastguard Worker br label %loop 2438*9880d681SAndroid Build Coastguard Worker 2439*9880d681SAndroid Build Coastguard Workerloop: 2440*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) 2441*9880d681SAndroid Build Coastguard Worker %q = load i1, i1* %p 2442*9880d681SAndroid Build Coastguard Worker br i1 %q, label %loop.more, label %exit 2443*9880d681SAndroid Build Coastguard Worker 2444*9880d681SAndroid Build Coastguard Workerloop.more: 2445*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) 2446*9880d681SAndroid Build Coastguard Worker br label %loop 2447*9880d681SAndroid Build Coastguard Worker 2448*9880d681SAndroid Build Coastguard Workerexit: 2449*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) 2450*9880d681SAndroid Build Coastguard Worker ret void 2451*9880d681SAndroid Build Coastguard Worker} 2452*9880d681SAndroid Build Coastguard Worker 2453*9880d681SAndroid Build Coastguard Worker; Like test62 but with no release in exit. 2454*9880d681SAndroid Build Coastguard Worker; Don't delete anything! 2455*9880d681SAndroid Build Coastguard Worker 2456*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test63( 2457*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 2458*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %x) 2459*9880d681SAndroid Build Coastguard Worker; CHECK: loop.more: 2460*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %x) 2461*9880d681SAndroid Build Coastguard Worker; CHECK: } 2462*9880d681SAndroid Build Coastguard Workerdefine void @test63(i8* %x, i1* %p) nounwind { 2463*9880d681SAndroid Build Coastguard Workerentry: 2464*9880d681SAndroid Build Coastguard Worker br label %loop 2465*9880d681SAndroid Build Coastguard Worker 2466*9880d681SAndroid Build Coastguard Workerloop: 2467*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) 2468*9880d681SAndroid Build Coastguard Worker %q = load i1, i1* %p 2469*9880d681SAndroid Build Coastguard Worker br i1 %q, label %loop.more, label %exit 2470*9880d681SAndroid Build Coastguard Worker 2471*9880d681SAndroid Build Coastguard Workerloop.more: 2472*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) 2473*9880d681SAndroid Build Coastguard Worker br label %loop 2474*9880d681SAndroid Build Coastguard Worker 2475*9880d681SAndroid Build Coastguard Workerexit: 2476*9880d681SAndroid Build Coastguard Worker ret void 2477*9880d681SAndroid Build Coastguard Worker} 2478*9880d681SAndroid Build Coastguard Worker 2479*9880d681SAndroid Build Coastguard Worker; Like test62 but with no release in loop.more. 2480*9880d681SAndroid Build Coastguard Worker; Don't delete anything! 2481*9880d681SAndroid Build Coastguard Worker 2482*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test64( 2483*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 2484*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %x) 2485*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 2486*9880d681SAndroid Build Coastguard Worker; CHECK: call void @objc_release(i8* %x) 2487*9880d681SAndroid Build Coastguard Worker; CHECK: } 2488*9880d681SAndroid Build Coastguard Workerdefine void @test64(i8* %x, i1* %p) nounwind { 2489*9880d681SAndroid Build Coastguard Workerentry: 2490*9880d681SAndroid Build Coastguard Worker br label %loop 2491*9880d681SAndroid Build Coastguard Worker 2492*9880d681SAndroid Build Coastguard Workerloop: 2493*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) 2494*9880d681SAndroid Build Coastguard Worker %q = load i1, i1* %p 2495*9880d681SAndroid Build Coastguard Worker br i1 %q, label %loop.more, label %exit 2496*9880d681SAndroid Build Coastguard Worker 2497*9880d681SAndroid Build Coastguard Workerloop.more: 2498*9880d681SAndroid Build Coastguard Worker br label %loop 2499*9880d681SAndroid Build Coastguard Worker 2500*9880d681SAndroid Build Coastguard Workerexit: 2501*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x) 2502*9880d681SAndroid Build Coastguard Worker ret void 2503*9880d681SAndroid Build Coastguard Worker} 2504*9880d681SAndroid Build Coastguard Worker 2505*9880d681SAndroid Build Coastguard Worker; Move an autorelease past a phi with a null. 2506*9880d681SAndroid Build Coastguard Worker 2507*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test65( 2508*9880d681SAndroid Build Coastguard Worker; CHECK: if.then: 2509*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autorelease( 2510*9880d681SAndroid Build Coastguard Worker; CHECK: return: 2511*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_autorelease 2512*9880d681SAndroid Build Coastguard Worker; CHECK: } 2513*9880d681SAndroid Build Coastguard Workerdefine i8* @test65(i1 %x) { 2514*9880d681SAndroid Build Coastguard Workerentry: 2515*9880d681SAndroid Build Coastguard Worker br i1 %x, label %return, label %if.then 2516*9880d681SAndroid Build Coastguard Worker 2517*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 2518*9880d681SAndroid Build Coastguard Worker %c = call i8* @returner() 2519*9880d681SAndroid Build Coastguard Worker %s = call i8* @objc_retainAutoreleasedReturnValue(i8* %c) nounwind 2520*9880d681SAndroid Build Coastguard Worker br label %return 2521*9880d681SAndroid Build Coastguard Worker 2522*9880d681SAndroid Build Coastguard Workerreturn: ; preds = %if.then, %entry 2523*9880d681SAndroid Build Coastguard Worker %retval = phi i8* [ %s, %if.then ], [ null, %entry ] 2524*9880d681SAndroid Build Coastguard Worker %q = call i8* @objc_autorelease(i8* %retval) nounwind 2525*9880d681SAndroid Build Coastguard Worker ret i8* %retval 2526*9880d681SAndroid Build Coastguard Worker} 2527*9880d681SAndroid Build Coastguard Worker 2528*9880d681SAndroid Build Coastguard Worker; Don't move an autorelease past an autorelease pool boundary. 2529*9880d681SAndroid Build Coastguard Worker 2530*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test65b( 2531*9880d681SAndroid Build Coastguard Worker; CHECK: if.then: 2532*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_autorelease 2533*9880d681SAndroid Build Coastguard Worker; CHECK: return: 2534*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autorelease( 2535*9880d681SAndroid Build Coastguard Worker; CHECK: } 2536*9880d681SAndroid Build Coastguard Workerdefine i8* @test65b(i1 %x) { 2537*9880d681SAndroid Build Coastguard Workerentry: 2538*9880d681SAndroid Build Coastguard Worker %t = call i8* @objc_autoreleasePoolPush() 2539*9880d681SAndroid Build Coastguard Worker br i1 %x, label %return, label %if.then 2540*9880d681SAndroid Build Coastguard Worker 2541*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 2542*9880d681SAndroid Build Coastguard Worker %c = call i8* @returner() 2543*9880d681SAndroid Build Coastguard Worker %s = call i8* @objc_retainAutoreleasedReturnValue(i8* %c) nounwind 2544*9880d681SAndroid Build Coastguard Worker br label %return 2545*9880d681SAndroid Build Coastguard Worker 2546*9880d681SAndroid Build Coastguard Workerreturn: ; preds = %if.then, %entry 2547*9880d681SAndroid Build Coastguard Worker %retval = phi i8* [ %s, %if.then ], [ null, %entry ] 2548*9880d681SAndroid Build Coastguard Worker call void @objc_autoreleasePoolPop(i8* %t) 2549*9880d681SAndroid Build Coastguard Worker %q = call i8* @objc_autorelease(i8* %retval) nounwind 2550*9880d681SAndroid Build Coastguard Worker ret i8* %retval 2551*9880d681SAndroid Build Coastguard Worker} 2552*9880d681SAndroid Build Coastguard Worker 2553*9880d681SAndroid Build Coastguard Worker; Don't move an autoreleaseReuturnValue, which would break 2554*9880d681SAndroid Build Coastguard Worker; the RV optimization. 2555*9880d681SAndroid Build Coastguard Worker 2556*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test65c( 2557*9880d681SAndroid Build Coastguard Worker; CHECK: if.then: 2558*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_autorelease 2559*9880d681SAndroid Build Coastguard Worker; CHECK: return: 2560*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autoreleaseReturnValue( 2561*9880d681SAndroid Build Coastguard Worker; CHECK: } 2562*9880d681SAndroid Build Coastguard Workerdefine i8* @test65c(i1 %x) { 2563*9880d681SAndroid Build Coastguard Workerentry: 2564*9880d681SAndroid Build Coastguard Worker br i1 %x, label %return, label %if.then 2565*9880d681SAndroid Build Coastguard Worker 2566*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 2567*9880d681SAndroid Build Coastguard Worker %c = call i8* @returner() 2568*9880d681SAndroid Build Coastguard Worker %s = call i8* @objc_retainAutoreleasedReturnValue(i8* %c) nounwind 2569*9880d681SAndroid Build Coastguard Worker br label %return 2570*9880d681SAndroid Build Coastguard Worker 2571*9880d681SAndroid Build Coastguard Workerreturn: ; preds = %if.then, %entry 2572*9880d681SAndroid Build Coastguard Worker %retval = phi i8* [ %s, %if.then ], [ null, %entry ] 2573*9880d681SAndroid Build Coastguard Worker %q = call i8* @objc_autoreleaseReturnValue(i8* %retval) nounwind 2574*9880d681SAndroid Build Coastguard Worker ret i8* %retval 2575*9880d681SAndroid Build Coastguard Worker} 2576*9880d681SAndroid Build Coastguard Worker 2577*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test65d( 2578*9880d681SAndroid Build Coastguard Worker; CHECK: if.then: 2579*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_autorelease 2580*9880d681SAndroid Build Coastguard Worker; CHECK: return: 2581*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autoreleaseReturnValue( 2582*9880d681SAndroid Build Coastguard Worker; CHECK: } 2583*9880d681SAndroid Build Coastguard Workerdefine i8* @test65d(i1 %x) { 2584*9880d681SAndroid Build Coastguard Workerentry: 2585*9880d681SAndroid Build Coastguard Worker br i1 %x, label %return, label %if.then 2586*9880d681SAndroid Build Coastguard Worker 2587*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 2588*9880d681SAndroid Build Coastguard Worker %c = call i8* @returner() 2589*9880d681SAndroid Build Coastguard Worker %s = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* %c) nounwind 2590*9880d681SAndroid Build Coastguard Worker br label %return 2591*9880d681SAndroid Build Coastguard Worker 2592*9880d681SAndroid Build Coastguard Workerreturn: ; preds = %if.then, %entry 2593*9880d681SAndroid Build Coastguard Worker %retval = phi i8* [ %s, %if.then ], [ null, %entry ] 2594*9880d681SAndroid Build Coastguard Worker %q = call i8* @objc_autoreleaseReturnValue(i8* %retval) nounwind 2595*9880d681SAndroid Build Coastguard Worker ret i8* %retval 2596*9880d681SAndroid Build Coastguard Worker} 2597*9880d681SAndroid Build Coastguard Worker 2598*9880d681SAndroid Build Coastguard Worker; An objc_retain can serve as a may-use for a different pointer. 2599*9880d681SAndroid Build Coastguard Worker; rdar://11931823 2600*9880d681SAndroid Build Coastguard Worker 2601*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test66a( 2602*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %cond) [[NUW]] 2603*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @objc_release(i8* %call) [[NUW]] 2604*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %tmp8) [[NUW]] 2605*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @objc_release(i8* %cond) [[NUW]] 2606*9880d681SAndroid Build Coastguard Worker; CHECK: } 2607*9880d681SAndroid Build Coastguard Workerdefine void @test66a(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) { 2608*9880d681SAndroid Build Coastguard Workerentry: 2609*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %cond.true, label %cond.end 2610*9880d681SAndroid Build Coastguard Worker 2611*9880d681SAndroid Build Coastguard Workercond.true: 2612*9880d681SAndroid Build Coastguard Worker br label %cond.end 2613*9880d681SAndroid Build Coastguard Worker 2614*9880d681SAndroid Build Coastguard Workercond.end: ; preds = %cond.true, %entry 2615*9880d681SAndroid Build Coastguard Worker %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ] 2616*9880d681SAndroid Build Coastguard Worker %tmp7 = tail call i8* @objc_retain(i8* %cond) nounwind 2617*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %call) nounwind 2618*9880d681SAndroid Build Coastguard Worker %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar 2619*9880d681SAndroid Build Coastguard Worker %tmp9 = tail call i8* @objc_retain(i8* %tmp8) nounwind 2620*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %cond) nounwind 2621*9880d681SAndroid Build Coastguard Worker ret void 2622*9880d681SAndroid Build Coastguard Worker} 2623*9880d681SAndroid Build Coastguard Worker 2624*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test66b( 2625*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %cond) [[NUW]] 2626*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @objc_release(i8* %call) [[NUW]] 2627*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %tmp8) [[NUW]] 2628*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @objc_release(i8* %cond) [[NUW]] 2629*9880d681SAndroid Build Coastguard Worker; CHECK: } 2630*9880d681SAndroid Build Coastguard Workerdefine void @test66b(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) { 2631*9880d681SAndroid Build Coastguard Workerentry: 2632*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %cond.true, label %cond.end 2633*9880d681SAndroid Build Coastguard Worker 2634*9880d681SAndroid Build Coastguard Workercond.true: 2635*9880d681SAndroid Build Coastguard Worker br label %cond.end 2636*9880d681SAndroid Build Coastguard Worker 2637*9880d681SAndroid Build Coastguard Workercond.end: ; preds = %cond.true, %entry 2638*9880d681SAndroid Build Coastguard Worker %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ] 2639*9880d681SAndroid Build Coastguard Worker %tmp7 = tail call i8* @objc_retain(i8* %cond) nounwind 2640*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %call) nounwind, !clang.imprecise_release !0 2641*9880d681SAndroid Build Coastguard Worker %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar 2642*9880d681SAndroid Build Coastguard Worker %tmp9 = tail call i8* @objc_retain(i8* %tmp8) nounwind 2643*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %cond) nounwind 2644*9880d681SAndroid Build Coastguard Worker ret void 2645*9880d681SAndroid Build Coastguard Worker} 2646*9880d681SAndroid Build Coastguard Worker 2647*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test66c( 2648*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %cond) [[NUW]] 2649*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @objc_release(i8* %call) [[NUW]] 2650*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %tmp8) [[NUW]] 2651*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @objc_release(i8* %cond) [[NUW]] 2652*9880d681SAndroid Build Coastguard Worker; CHECK: } 2653*9880d681SAndroid Build Coastguard Workerdefine void @test66c(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) { 2654*9880d681SAndroid Build Coastguard Workerentry: 2655*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %cond.true, label %cond.end 2656*9880d681SAndroid Build Coastguard Worker 2657*9880d681SAndroid Build Coastguard Workercond.true: 2658*9880d681SAndroid Build Coastguard Worker br label %cond.end 2659*9880d681SAndroid Build Coastguard Worker 2660*9880d681SAndroid Build Coastguard Workercond.end: ; preds = %cond.true, %entry 2661*9880d681SAndroid Build Coastguard Worker %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ] 2662*9880d681SAndroid Build Coastguard Worker %tmp7 = tail call i8* @objc_retain(i8* %cond) nounwind 2663*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %call) nounwind 2664*9880d681SAndroid Build Coastguard Worker %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar 2665*9880d681SAndroid Build Coastguard Worker %tmp9 = tail call i8* @objc_retain(i8* %tmp8) nounwind, !clang.imprecise_release !0 2666*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %cond) nounwind 2667*9880d681SAndroid Build Coastguard Worker ret void 2668*9880d681SAndroid Build Coastguard Worker} 2669*9880d681SAndroid Build Coastguard Worker 2670*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test66d( 2671*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %cond) [[NUW]] 2672*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @objc_release(i8* %call) [[NUW]] 2673*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %tmp8) [[NUW]] 2674*9880d681SAndroid Build Coastguard Worker; CHECK: tail call void @objc_release(i8* %cond) [[NUW]] 2675*9880d681SAndroid Build Coastguard Worker; CHECK: } 2676*9880d681SAndroid Build Coastguard Workerdefine void @test66d(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) { 2677*9880d681SAndroid Build Coastguard Workerentry: 2678*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %cond.true, label %cond.end 2679*9880d681SAndroid Build Coastguard Worker 2680*9880d681SAndroid Build Coastguard Workercond.true: 2681*9880d681SAndroid Build Coastguard Worker br label %cond.end 2682*9880d681SAndroid Build Coastguard Worker 2683*9880d681SAndroid Build Coastguard Workercond.end: ; preds = %cond.true, %entry 2684*9880d681SAndroid Build Coastguard Worker %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ] 2685*9880d681SAndroid Build Coastguard Worker %tmp7 = tail call i8* @objc_retain(i8* %cond) nounwind 2686*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %call) nounwind, !clang.imprecise_release !0 2687*9880d681SAndroid Build Coastguard Worker %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar 2688*9880d681SAndroid Build Coastguard Worker %tmp9 = tail call i8* @objc_retain(i8* %tmp8) nounwind 2689*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %cond) nounwind, !clang.imprecise_release !0 2690*9880d681SAndroid Build Coastguard Worker ret void 2691*9880d681SAndroid Build Coastguard Worker} 2692*9880d681SAndroid Build Coastguard Worker 2693*9880d681SAndroid Build Coastguard Worker; A few real-world testcases. 2694*9880d681SAndroid Build Coastguard Worker 2695*9880d681SAndroid Build Coastguard Worker@.str4 = private unnamed_addr constant [33 x i8] c"-[A z] = { %f, %f, { %f, %f } }\0A\00" 2696*9880d681SAndroid Build Coastguard Worker@"OBJC_IVAR_$_A.myZ" = global i64 20, section "__DATA, __objc_const", align 8 2697*9880d681SAndroid Build Coastguard Workerdeclare i32 @printf(i8* nocapture, ...) nounwind 2698*9880d681SAndroid Build Coastguard Workerdeclare i32 @puts(i8* nocapture) nounwind 2699*9880d681SAndroid Build Coastguard Worker@str = internal constant [16 x i8] c"-[ Top0 _getX ]\00" 2700*9880d681SAndroid Build Coastguard Worker 2701*9880d681SAndroid Build Coastguard Worker; CHECK: define { <2 x float>, <2 x float> } @"\01-[A z]"({}* %self, i8* nocapture %_cmd) [[NUW]] { 2702*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 2703*9880d681SAndroid Build Coastguard Worker; CHECK: } 2704*9880d681SAndroid Build Coastguard Worker 2705*9880d681SAndroid Build Coastguard Workerdefine {<2 x float>, <2 x float>} @"\01-[A z]"({}* %self, i8* nocapture %_cmd) nounwind { 2706*9880d681SAndroid Build Coastguard Workerinvoke.cont: 2707*9880d681SAndroid Build Coastguard Worker %0 = bitcast {}* %self to i8* 2708*9880d681SAndroid Build Coastguard Worker %1 = tail call i8* @objc_retain(i8* %0) nounwind 2709*9880d681SAndroid Build Coastguard Worker tail call void @llvm.dbg.value(metadata {}* %self, i64 0, metadata !DILocalVariable(scope: !2), metadata !DIExpression()), !dbg !DILocation(scope: !2) 2710*9880d681SAndroid Build Coastguard Worker tail call void @llvm.dbg.value(metadata {}* %self, i64 0, metadata !DILocalVariable(scope: !2), metadata !DIExpression()), !dbg !DILocation(scope: !2) 2711*9880d681SAndroid Build Coastguard Worker %ivar = load i64, i64* @"OBJC_IVAR_$_A.myZ", align 8 2712*9880d681SAndroid Build Coastguard Worker %add.ptr = getelementptr i8, i8* %0, i64 %ivar 2713*9880d681SAndroid Build Coastguard Worker %tmp1 = bitcast i8* %add.ptr to float* 2714*9880d681SAndroid Build Coastguard Worker %tmp2 = load float, float* %tmp1, align 4 2715*9880d681SAndroid Build Coastguard Worker %conv = fpext float %tmp2 to double 2716*9880d681SAndroid Build Coastguard Worker %add.ptr.sum = add i64 %ivar, 4 2717*9880d681SAndroid Build Coastguard Worker %tmp6 = getelementptr inbounds i8, i8* %0, i64 %add.ptr.sum 2718*9880d681SAndroid Build Coastguard Worker %2 = bitcast i8* %tmp6 to float* 2719*9880d681SAndroid Build Coastguard Worker %tmp7 = load float, float* %2, align 4 2720*9880d681SAndroid Build Coastguard Worker %conv8 = fpext float %tmp7 to double 2721*9880d681SAndroid Build Coastguard Worker %add.ptr.sum36 = add i64 %ivar, 8 2722*9880d681SAndroid Build Coastguard Worker %tmp12 = getelementptr inbounds i8, i8* %0, i64 %add.ptr.sum36 2723*9880d681SAndroid Build Coastguard Worker %arrayidx = bitcast i8* %tmp12 to float* 2724*9880d681SAndroid Build Coastguard Worker %tmp13 = load float, float* %arrayidx, align 4 2725*9880d681SAndroid Build Coastguard Worker %conv14 = fpext float %tmp13 to double 2726*9880d681SAndroid Build Coastguard Worker %tmp12.sum = add i64 %ivar, 12 2727*9880d681SAndroid Build Coastguard Worker %arrayidx19 = getelementptr inbounds i8, i8* %0, i64 %tmp12.sum 2728*9880d681SAndroid Build Coastguard Worker %3 = bitcast i8* %arrayidx19 to float* 2729*9880d681SAndroid Build Coastguard Worker %tmp20 = load float, float* %3, align 4 2730*9880d681SAndroid Build Coastguard Worker %conv21 = fpext float %tmp20 to double 2731*9880d681SAndroid Build Coastguard Worker %call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str4, i64 0, i64 0), double %conv, double %conv8, double %conv14, double %conv21) 2732*9880d681SAndroid Build Coastguard Worker %ivar23 = load i64, i64* @"OBJC_IVAR_$_A.myZ", align 8 2733*9880d681SAndroid Build Coastguard Worker %add.ptr24 = getelementptr i8, i8* %0, i64 %ivar23 2734*9880d681SAndroid Build Coastguard Worker %4 = bitcast i8* %add.ptr24 to i128* 2735*9880d681SAndroid Build Coastguard Worker %srcval = load i128, i128* %4, align 4 2736*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %0) nounwind 2737*9880d681SAndroid Build Coastguard Worker %tmp29 = trunc i128 %srcval to i64 2738*9880d681SAndroid Build Coastguard Worker %tmp30 = bitcast i64 %tmp29 to <2 x float> 2739*9880d681SAndroid Build Coastguard Worker %tmp31 = insertvalue {<2 x float>, <2 x float>} undef, <2 x float> %tmp30, 0 2740*9880d681SAndroid Build Coastguard Worker %tmp32 = lshr i128 %srcval, 64 2741*9880d681SAndroid Build Coastguard Worker %tmp33 = trunc i128 %tmp32 to i64 2742*9880d681SAndroid Build Coastguard Worker %tmp34 = bitcast i64 %tmp33 to <2 x float> 2743*9880d681SAndroid Build Coastguard Worker %tmp35 = insertvalue {<2 x float>, <2 x float>} %tmp31, <2 x float> %tmp34, 1 2744*9880d681SAndroid Build Coastguard Worker ret {<2 x float>, <2 x float>} %tmp35 2745*9880d681SAndroid Build Coastguard Worker} 2746*9880d681SAndroid Build Coastguard Worker 2747*9880d681SAndroid Build Coastguard Worker; CHECK: @"\01-[Top0 _getX]"({}* %self, i8* nocapture %_cmd) [[NUW]] { 2748*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 2749*9880d681SAndroid Build Coastguard Worker; CHECK: } 2750*9880d681SAndroid Build Coastguard Worker 2751*9880d681SAndroid Build Coastguard Workerdefine i32 @"\01-[Top0 _getX]"({}* %self, i8* nocapture %_cmd) nounwind { 2752*9880d681SAndroid Build Coastguard Workerinvoke.cont: 2753*9880d681SAndroid Build Coastguard Worker %0 = bitcast {}* %self to i8* 2754*9880d681SAndroid Build Coastguard Worker %1 = tail call i8* @objc_retain(i8* %0) nounwind 2755*9880d681SAndroid Build Coastguard Worker %puts = tail call i32 @puts(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @str, i64 0, i64 0)) 2756*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %0) nounwind 2757*9880d681SAndroid Build Coastguard Worker ret i32 0 2758*9880d681SAndroid Build Coastguard Worker} 2759*9880d681SAndroid Build Coastguard Worker 2760*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_METH_VAR_NAME_" = internal global [5 x i8] c"frob\00", section "__TEXT,__cstring,cstring_literals", align 1@"\01L_OBJC_SELECTOR_REFERENCES_" = internal global i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i64 0, i64 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2761*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip" 2762*9880d681SAndroid Build Coastguard Worker@llvm.used = appending global [3 x i8*] [i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i32 0, i32 0), i8* bitcast (i8** @"\01L_OBJC_SELECTOR_REFERENCES_" to i8*), i8* bitcast ([2 x i32]* @"\01L_OBJC_IMAGE_INFO" to i8*)], section "llvm.metadata" 2763*9880d681SAndroid Build Coastguard Worker 2764*9880d681SAndroid Build Coastguard Worker; A simple loop. Eliminate the retain and release inside of it! 2765*9880d681SAndroid Build Coastguard Worker 2766*9880d681SAndroid Build Coastguard Worker; CHECK: define void @loop(i8* %x, i64 %n) { 2767*9880d681SAndroid Build Coastguard Worker; CHECK: for.body: 2768*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 2769*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_msgSend 2770*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_ 2771*9880d681SAndroid Build Coastguard Worker; CHECK: for.end: 2772*9880d681SAndroid Build Coastguard Worker; CHECK: } 2773*9880d681SAndroid Build Coastguard Workerdefine void @loop(i8* %x, i64 %n) { 2774*9880d681SAndroid Build Coastguard Workerentry: 2775*9880d681SAndroid Build Coastguard Worker %0 = tail call i8* @objc_retain(i8* %x) nounwind 2776*9880d681SAndroid Build Coastguard Worker %cmp9 = icmp sgt i64 %n, 0 2777*9880d681SAndroid Build Coastguard Worker br i1 %cmp9, label %for.body, label %for.end 2778*9880d681SAndroid Build Coastguard Worker 2779*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 2780*9880d681SAndroid Build Coastguard Worker %i.010 = phi i64 [ %inc, %for.body ], [ 0, %entry ] 2781*9880d681SAndroid Build Coastguard Worker %1 = tail call i8* @objc_retain(i8* %x) nounwind 2782*9880d681SAndroid Build Coastguard Worker %tmp5 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8 2783*9880d681SAndroid Build Coastguard Worker %call = tail call i8* (i8*, i8*, ...) @objc_msgSend(i8* %1, i8* %tmp5) 2784*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0 2785*9880d681SAndroid Build Coastguard Worker %inc = add nsw i64 %i.010, 1 2786*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %inc, %n 2787*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 2788*9880d681SAndroid Build Coastguard Worker 2789*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body, %entry 2790*9880d681SAndroid Build Coastguard Worker tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 2791*9880d681SAndroid Build Coastguard Worker ret void 2792*9880d681SAndroid Build Coastguard Worker} 2793*9880d681SAndroid Build Coastguard Worker 2794*9880d681SAndroid Build Coastguard Worker; ObjCARCOpt can delete the retain,release on self. 2795*9880d681SAndroid Build Coastguard Worker 2796*9880d681SAndroid Build Coastguard Worker; CHECK: define void @TextEditTest(%2* %self, %3* %pboard) { 2797*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call i8* @objc_retain(i8* %tmp7) 2798*9880d681SAndroid Build Coastguard Worker; CHECK: } 2799*9880d681SAndroid Build Coastguard Worker 2800*9880d681SAndroid Build Coastguard Worker%0 = type { i8* (i8*, %struct._message_ref_t*, ...)*, i8* } 2801*9880d681SAndroid Build Coastguard Worker%1 = type opaque 2802*9880d681SAndroid Build Coastguard Worker%2 = type opaque 2803*9880d681SAndroid Build Coastguard Worker%3 = type opaque 2804*9880d681SAndroid Build Coastguard Worker%4 = type opaque 2805*9880d681SAndroid Build Coastguard Worker%5 = type opaque 2806*9880d681SAndroid Build Coastguard Worker%struct.NSConstantString = type { i32*, i32, i8*, i64 } 2807*9880d681SAndroid Build Coastguard Worker%struct._NSRange = type { i64, i64 } 2808*9880d681SAndroid Build Coastguard Worker%struct.__CFString = type opaque 2809*9880d681SAndroid Build Coastguard Worker%struct.__method_list_t = type { i32, i32, [0 x %struct._objc_method] } 2810*9880d681SAndroid Build Coastguard Worker%struct._class_ro_t = type { i32, i32, i32, i8*, i8*, %struct.__method_list_t*, %struct._objc_protocol_list*, %struct._ivar_list_t*, i8*, %struct._prop_list_t* } 2811*9880d681SAndroid Build Coastguard Worker%struct._class_t = type { %struct._class_t*, %struct._class_t*, %struct._objc_cache*, i8* (i8*, i8*)**, %struct._class_ro_t* } 2812*9880d681SAndroid Build Coastguard Worker%struct._ivar_list_t = type { i32, i32, [0 x %struct._ivar_t] } 2813*9880d681SAndroid Build Coastguard Worker%struct._ivar_t = type { i64*, i8*, i8*, i32, i32 } 2814*9880d681SAndroid Build Coastguard Worker%struct._message_ref_t = type { i8*, i8* } 2815*9880d681SAndroid Build Coastguard Worker%struct._objc_cache = type opaque 2816*9880d681SAndroid Build Coastguard Worker%struct._objc_method = type { i8*, i8*, i8* } 2817*9880d681SAndroid Build Coastguard Worker%struct._objc_protocol_list = type { i64, [0 x %struct._protocol_t*] } 2818*9880d681SAndroid Build Coastguard Worker%struct._prop_list_t = type { i32, i32, [0 x %struct._message_ref_t] } 2819*9880d681SAndroid Build Coastguard Worker%struct._protocol_t = type { i8*, i8*, %struct._objc_protocol_list*, %struct.__method_list_t*, %struct.__method_list_t*, %struct.__method_list_t*, %struct.__method_list_t*, %struct._prop_list_t*, i32, i32 } 2820*9880d681SAndroid Build Coastguard Worker 2821*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_CLASSLIST_REFERENCES_$_17" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 2822*9880d681SAndroid Build Coastguard Worker@kUTTypePlainText = external constant %struct.__CFString* 2823*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_19" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2824*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_21" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2825*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_23" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2826*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_25" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2827*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_CLASSLIST_REFERENCES_$_26" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 2828*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_28" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2829*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_CLASSLIST_REFERENCES_$_29" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 2830*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_31" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2831*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_33" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2832*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_35" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2833*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_37" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2834*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_CLASSLIST_REFERENCES_$_38" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 2835*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_40" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2836*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_42" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2837*9880d681SAndroid Build Coastguard Worker@_unnamed_cfstring_44 = external hidden constant %struct.NSConstantString, section "__DATA,__cfstring" 2838*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_46" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2839*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_48" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2840*9880d681SAndroid Build Coastguard Worker@"\01l_objc_msgSend_fixup_isEqual_" = external hidden global %0, section "__DATA, __objc_msgrefs, coalesced", align 16 2841*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_CLASSLIST_REFERENCES_$_50" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 2842*9880d681SAndroid Build Coastguard Worker@NSCocoaErrorDomain = external constant %1* 2843*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_CLASSLIST_REFERENCES_$_51" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 2844*9880d681SAndroid Build Coastguard Worker@NSFilePathErrorKey = external constant %1* 2845*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_53" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2846*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_55" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2847*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_CLASSLIST_REFERENCES_$_56" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 2848*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_58" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2849*9880d681SAndroid Build Coastguard Worker@"\01L_OBJC_SELECTOR_REFERENCES_60" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 2850*9880d681SAndroid Build Coastguard Worker 2851*9880d681SAndroid Build Coastguard Workerdeclare %1* @truncatedString(%1*, i64) 2852*9880d681SAndroid Build Coastguard Workerdefine void @TextEditTest(%2* %self, %3* %pboard) { 2853*9880d681SAndroid Build Coastguard Workerentry: 2854*9880d681SAndroid Build Coastguard Worker %err = alloca %4*, align 8 2855*9880d681SAndroid Build Coastguard Worker %tmp7 = bitcast %2* %self to i8* 2856*9880d681SAndroid Build Coastguard Worker %tmp8 = call i8* @objc_retain(i8* %tmp7) nounwind 2857*9880d681SAndroid Build Coastguard Worker store %4* null, %4** %err, align 8 2858*9880d681SAndroid Build Coastguard Worker %tmp1 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_17", align 8 2859*9880d681SAndroid Build Coastguard Worker %tmp2 = load %struct.__CFString*, %struct.__CFString** @kUTTypePlainText, align 8 2860*9880d681SAndroid Build Coastguard Worker %tmp3 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_19", align 8 2861*9880d681SAndroid Build Coastguard Worker %tmp4 = bitcast %struct._class_t* %tmp1 to i8* 2862*9880d681SAndroid Build Coastguard Worker %call5 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp4, i8* %tmp3, %struct.__CFString* %tmp2) 2863*9880d681SAndroid Build Coastguard Worker %tmp5 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_21", align 8 2864*9880d681SAndroid Build Coastguard Worker %tmp6 = bitcast %3* %pboard to i8* 2865*9880d681SAndroid Build Coastguard Worker %call76 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp6, i8* %tmp5, i8* %call5) 2866*9880d681SAndroid Build Coastguard Worker %tmp9 = call i8* @objc_retain(i8* %call76) nounwind 2867*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i8* %tmp9, null 2868*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %end, label %land.lhs.true 2869*9880d681SAndroid Build Coastguard Worker 2870*9880d681SAndroid Build Coastguard Workerland.lhs.true: ; preds = %entry 2871*9880d681SAndroid Build Coastguard Worker %tmp11 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_23", align 8 2872*9880d681SAndroid Build Coastguard Worker %call137 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp6, i8* %tmp11, i8* %tmp9) 2873*9880d681SAndroid Build Coastguard Worker %tmp = bitcast i8* %call137 to %1* 2874*9880d681SAndroid Build Coastguard Worker %tmp10 = call i8* @objc_retain(i8* %call137) nounwind 2875*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* null) nounwind 2876*9880d681SAndroid Build Coastguard Worker %tmp12 = call i8* @objc_retain(i8* %call137) nounwind 2877*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* null) nounwind 2878*9880d681SAndroid Build Coastguard Worker %tobool16 = icmp eq i8* %call137, null 2879*9880d681SAndroid Build Coastguard Worker br i1 %tobool16, label %end, label %if.then 2880*9880d681SAndroid Build Coastguard Worker 2881*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %land.lhs.true 2882*9880d681SAndroid Build Coastguard Worker %tmp19 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_25", align 8 2883*9880d681SAndroid Build Coastguard Worker %call21 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*)*)(i8* %call137, i8* %tmp19) 2884*9880d681SAndroid Build Coastguard Worker %tobool22 = icmp eq i8 %call21, 0 2885*9880d681SAndroid Build Coastguard Worker br i1 %tobool22, label %if.then44, label %land.lhs.true23 2886*9880d681SAndroid Build Coastguard Worker 2887*9880d681SAndroid Build Coastguard Workerland.lhs.true23: ; preds = %if.then 2888*9880d681SAndroid Build Coastguard Worker %tmp24 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_26", align 8 2889*9880d681SAndroid Build Coastguard Worker %tmp26 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_28", align 8 2890*9880d681SAndroid Build Coastguard Worker %tmp27 = bitcast %struct._class_t* %tmp24 to i8* 2891*9880d681SAndroid Build Coastguard Worker %call2822 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp27, i8* %tmp26, i8* %call137) 2892*9880d681SAndroid Build Coastguard Worker %tmp13 = bitcast i8* %call2822 to %5* 2893*9880d681SAndroid Build Coastguard Worker %tmp14 = call i8* @objc_retain(i8* %call2822) nounwind 2894*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* null) nounwind 2895*9880d681SAndroid Build Coastguard Worker %tobool30 = icmp eq i8* %call2822, null 2896*9880d681SAndroid Build Coastguard Worker br i1 %tobool30, label %if.then44, label %if.end 2897*9880d681SAndroid Build Coastguard Worker 2898*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %land.lhs.true23 2899*9880d681SAndroid Build Coastguard Worker %tmp32 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_29", align 8 2900*9880d681SAndroid Build Coastguard Worker %tmp33 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_31", align 8 2901*9880d681SAndroid Build Coastguard Worker %tmp34 = bitcast %struct._class_t* %tmp32 to i8* 2902*9880d681SAndroid Build Coastguard Worker %call35 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp34, i8* %tmp33) 2903*9880d681SAndroid Build Coastguard Worker %tmp37 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_33", align 8 2904*9880d681SAndroid Build Coastguard Worker %call3923 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call35, i8* %tmp37, i8* %call2822, i32 signext 1, %4** %err) 2905*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i8* %call3923, null 2906*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %if.then44, label %end 2907*9880d681SAndroid Build Coastguard Worker 2908*9880d681SAndroid Build Coastguard Workerif.then44: ; preds = %if.end, %land.lhs.true23, %if.then 2909*9880d681SAndroid Build Coastguard Worker %url.025 = phi %5* [ %tmp13, %if.end ], [ %tmp13, %land.lhs.true23 ], [ null, %if.then ] 2910*9880d681SAndroid Build Coastguard Worker %tmp49 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_35", align 8 2911*9880d681SAndroid Build Coastguard Worker %call51 = call %struct._NSRange bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %struct._NSRange (i8*, i8*, i64, i64)*)(i8* %call137, i8* %tmp49, i64 0, i64 0) 2912*9880d681SAndroid Build Coastguard Worker %call513 = extractvalue %struct._NSRange %call51, 0 2913*9880d681SAndroid Build Coastguard Worker %call514 = extractvalue %struct._NSRange %call51, 1 2914*9880d681SAndroid Build Coastguard Worker %tmp52 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_37", align 8 2915*9880d681SAndroid Build Coastguard Worker %call548 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call137, i8* %tmp52, i64 %call513, i64 %call514) 2916*9880d681SAndroid Build Coastguard Worker %tmp55 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_38", align 8 2917*9880d681SAndroid Build Coastguard Worker %tmp56 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_40", align 8 2918*9880d681SAndroid Build Coastguard Worker %tmp57 = bitcast %struct._class_t* %tmp55 to i8* 2919*9880d681SAndroid Build Coastguard Worker %call58 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp57, i8* %tmp56) 2920*9880d681SAndroid Build Coastguard Worker %tmp59 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_42", align 8 2921*9880d681SAndroid Build Coastguard Worker %call6110 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call548, i8* %tmp59, i8* %call58) 2922*9880d681SAndroid Build Coastguard Worker %tmp15 = call i8* @objc_retain(i8* %call6110) nounwind 2923*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %call137) nounwind 2924*9880d681SAndroid Build Coastguard Worker %tmp64 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_46", align 8 2925*9880d681SAndroid Build Coastguard Worker %call66 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*, %1*)*)(i8* %call6110, i8* %tmp64, %1* bitcast (%struct.NSConstantString* @_unnamed_cfstring_44 to %1*)) 2926*9880d681SAndroid Build Coastguard Worker %tobool67 = icmp eq i8 %call66, 0 2927*9880d681SAndroid Build Coastguard Worker br i1 %tobool67, label %if.end74, label %if.then68 2928*9880d681SAndroid Build Coastguard Worker 2929*9880d681SAndroid Build Coastguard Workerif.then68: ; preds = %if.then44 2930*9880d681SAndroid Build Coastguard Worker %tmp70 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_48", align 8 2931*9880d681SAndroid Build Coastguard Worker %call7220 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call6110, i8* %tmp70) 2932*9880d681SAndroid Build Coastguard Worker %tmp16 = call i8* @objc_retain(i8* %call7220) nounwind 2933*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %call6110) nounwind 2934*9880d681SAndroid Build Coastguard Worker br label %if.end74 2935*9880d681SAndroid Build Coastguard Worker 2936*9880d681SAndroid Build Coastguard Workerif.end74: ; preds = %if.then68, %if.then44 2937*9880d681SAndroid Build Coastguard Worker %filename.0.in = phi i8* [ %call7220, %if.then68 ], [ %call6110, %if.then44 ] 2938*9880d681SAndroid Build Coastguard Worker %filename.0 = bitcast i8* %filename.0.in to %1* 2939*9880d681SAndroid Build Coastguard Worker %tmp17 = load i8*, i8** bitcast (%0* @"\01l_objc_msgSend_fixup_isEqual_" to i8**), align 16 2940*9880d681SAndroid Build Coastguard Worker %tmp18 = bitcast i8* %tmp17 to i8 (i8*, %struct._message_ref_t*, i8*, ...)* 2941*9880d681SAndroid Build Coastguard Worker %call78 = call signext i8 (i8*, %struct._message_ref_t*, i8*, ...) %tmp18(i8* %call137, %struct._message_ref_t* bitcast (%0* @"\01l_objc_msgSend_fixup_isEqual_" to %struct._message_ref_t*), i8* %filename.0.in) 2942*9880d681SAndroid Build Coastguard Worker %tobool79 = icmp eq i8 %call78, 0 2943*9880d681SAndroid Build Coastguard Worker br i1 %tobool79, label %land.lhs.true80, label %if.then109 2944*9880d681SAndroid Build Coastguard Worker 2945*9880d681SAndroid Build Coastguard Workerland.lhs.true80: ; preds = %if.end74 2946*9880d681SAndroid Build Coastguard Worker %tmp82 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_25", align 8 2947*9880d681SAndroid Build Coastguard Worker %call84 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*)*)(i8* %filename.0.in, i8* %tmp82) 2948*9880d681SAndroid Build Coastguard Worker %tobool86 = icmp eq i8 %call84, 0 2949*9880d681SAndroid Build Coastguard Worker br i1 %tobool86, label %if.then109, label %if.end106 2950*9880d681SAndroid Build Coastguard Worker 2951*9880d681SAndroid Build Coastguard Workerif.end106: ; preds = %land.lhs.true80 2952*9880d681SAndroid Build Coastguard Worker %tmp88 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_26", align 8 2953*9880d681SAndroid Build Coastguard Worker %tmp90 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_28", align 8 2954*9880d681SAndroid Build Coastguard Worker %tmp91 = bitcast %struct._class_t* %tmp88 to i8* 2955*9880d681SAndroid Build Coastguard Worker %call9218 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp91, i8* %tmp90, i8* %filename.0.in) 2956*9880d681SAndroid Build Coastguard Worker %tmp20 = bitcast i8* %call9218 to %5* 2957*9880d681SAndroid Build Coastguard Worker %tmp21 = call i8* @objc_retain(i8* %call9218) nounwind 2958*9880d681SAndroid Build Coastguard Worker %tmp22 = bitcast %5* %url.025 to i8* 2959*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %tmp22) nounwind 2960*9880d681SAndroid Build Coastguard Worker %tmp94 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_29", align 8 2961*9880d681SAndroid Build Coastguard Worker %tmp95 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_31", align 8 2962*9880d681SAndroid Build Coastguard Worker %tmp96 = bitcast %struct._class_t* %tmp94 to i8* 2963*9880d681SAndroid Build Coastguard Worker %call97 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp96, i8* %tmp95) 2964*9880d681SAndroid Build Coastguard Worker %tmp99 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_33", align 8 2965*9880d681SAndroid Build Coastguard Worker %call10119 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call97, i8* %tmp99, i8* %call9218, i32 signext 1, %4** %err) 2966*9880d681SAndroid Build Coastguard Worker %phitmp = icmp eq i8* %call10119, null 2967*9880d681SAndroid Build Coastguard Worker br i1 %phitmp, label %if.then109, label %end 2968*9880d681SAndroid Build Coastguard Worker 2969*9880d681SAndroid Build Coastguard Workerif.then109: ; preds = %if.end106, %land.lhs.true80, %if.end74 2970*9880d681SAndroid Build Coastguard Worker %url.129 = phi %5* [ %tmp20, %if.end106 ], [ %url.025, %if.end74 ], [ %url.025, %land.lhs.true80 ] 2971*9880d681SAndroid Build Coastguard Worker %tmp110 = load %4*, %4** %err, align 8 2972*9880d681SAndroid Build Coastguard Worker %tobool111 = icmp eq %4* %tmp110, null 2973*9880d681SAndroid Build Coastguard Worker br i1 %tobool111, label %if.then112, label %if.end125 2974*9880d681SAndroid Build Coastguard Worker 2975*9880d681SAndroid Build Coastguard Workerif.then112: ; preds = %if.then109 2976*9880d681SAndroid Build Coastguard Worker %tmp113 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_50", align 8 2977*9880d681SAndroid Build Coastguard Worker %tmp114 = load %1*, %1** @NSCocoaErrorDomain, align 8 2978*9880d681SAndroid Build Coastguard Worker %tmp115 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_51", align 8 2979*9880d681SAndroid Build Coastguard Worker %call117 = call %1* @truncatedString(%1* %filename.0, i64 1034) 2980*9880d681SAndroid Build Coastguard Worker %tmp118 = load %1*, %1** @NSFilePathErrorKey, align 8 2981*9880d681SAndroid Build Coastguard Worker %tmp119 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_53", align 8 2982*9880d681SAndroid Build Coastguard Worker %tmp120 = bitcast %struct._class_t* %tmp115 to i8* 2983*9880d681SAndroid Build Coastguard Worker %call12113 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp120, i8* %tmp119, %1* %call117, %1* %tmp118, i8* null) 2984*9880d681SAndroid Build Coastguard Worker %tmp122 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_55", align 8 2985*9880d681SAndroid Build Coastguard Worker %tmp123 = bitcast %struct._class_t* %tmp113 to i8* 2986*9880d681SAndroid Build Coastguard Worker %call12414 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp123, i8* %tmp122, %1* %tmp114, i64 258, i8* %call12113) 2987*9880d681SAndroid Build Coastguard Worker %tmp23 = call i8* @objc_retain(i8* %call12414) nounwind 2988*9880d681SAndroid Build Coastguard Worker %tmp25 = call i8* @objc_autorelease(i8* %tmp23) nounwind 2989*9880d681SAndroid Build Coastguard Worker %tmp28 = bitcast i8* %tmp25 to %4* 2990*9880d681SAndroid Build Coastguard Worker store %4* %tmp28, %4** %err, align 8 2991*9880d681SAndroid Build Coastguard Worker br label %if.end125 2992*9880d681SAndroid Build Coastguard Worker 2993*9880d681SAndroid Build Coastguard Workerif.end125: ; preds = %if.then112, %if.then109 2994*9880d681SAndroid Build Coastguard Worker %tmp127 = phi %4* [ %tmp110, %if.then109 ], [ %tmp28, %if.then112 ] 2995*9880d681SAndroid Build Coastguard Worker %tmp126 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_56", align 8 2996*9880d681SAndroid Build Coastguard Worker %tmp128 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_58", align 8 2997*9880d681SAndroid Build Coastguard Worker %tmp129 = bitcast %struct._class_t* %tmp126 to i8* 2998*9880d681SAndroid Build Coastguard Worker %call13015 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp129, i8* %tmp128, %4* %tmp127) 2999*9880d681SAndroid Build Coastguard Worker %tmp131 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_60", align 8 3000*9880d681SAndroid Build Coastguard Worker %call13317 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call13015, i8* %tmp131) 3001*9880d681SAndroid Build Coastguard Worker br label %end 3002*9880d681SAndroid Build Coastguard Worker 3003*9880d681SAndroid Build Coastguard Workerend: ; preds = %if.end125, %if.end106, %if.end, %land.lhs.true, %entry 3004*9880d681SAndroid Build Coastguard Worker %filename.2 = phi %1* [ %filename.0, %if.end106 ], [ %filename.0, %if.end125 ], [ %tmp, %land.lhs.true ], [ null, %entry ], [ %tmp, %if.end ] 3005*9880d681SAndroid Build Coastguard Worker %origFilename.0 = phi %1* [ %tmp, %if.end106 ], [ %tmp, %if.end125 ], [ %tmp, %land.lhs.true ], [ null, %entry ], [ %tmp, %if.end ] 3006*9880d681SAndroid Build Coastguard Worker %url.2 = phi %5* [ %tmp20, %if.end106 ], [ %url.129, %if.end125 ], [ null, %land.lhs.true ], [ null, %entry ], [ %tmp13, %if.end ] 3007*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %tmp9) nounwind, !clang.imprecise_release !0 3008*9880d681SAndroid Build Coastguard Worker %tmp29 = bitcast %5* %url.2 to i8* 3009*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %tmp29) nounwind, !clang.imprecise_release !0 3010*9880d681SAndroid Build Coastguard Worker %tmp30 = bitcast %1* %origFilename.0 to i8* 3011*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %tmp30) nounwind, !clang.imprecise_release !0 3012*9880d681SAndroid Build Coastguard Worker %tmp31 = bitcast %1* %filename.2 to i8* 3013*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %tmp31) nounwind, !clang.imprecise_release !0 3014*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %tmp7) nounwind, !clang.imprecise_release !0 3015*9880d681SAndroid Build Coastguard Worker ret void 3016*9880d681SAndroid Build Coastguard Worker} 3017*9880d681SAndroid Build Coastguard Worker 3018*9880d681SAndroid Build Coastguard Workerdeclare i32 @__gxx_personality_v0(...) 3019*9880d681SAndroid Build Coastguard Worker 3020*9880d681SAndroid Build Coastguard Workerdeclare i32 @objc_sync_enter(i8*) 3021*9880d681SAndroid Build Coastguard Workerdeclare i32 @objc_sync_exit(i8*) 3022*9880d681SAndroid Build Coastguard Worker 3023*9880d681SAndroid Build Coastguard Worker; Make sure that we understand that objc_sync_{enter,exit} are IC_User not 3024*9880d681SAndroid Build Coastguard Worker; IC_Call/IC_CallOrUser. 3025*9880d681SAndroid Build Coastguard Worker 3026*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test67( 3027*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i32 @objc_sync_enter(i8* %x) 3028*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i32 @objc_sync_exit(i8* %x) 3029*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 3030*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 3031*9880d681SAndroid Build Coastguard Workerdefine void @test67(i8* %x) { 3032*9880d681SAndroid Build Coastguard Worker call i8* @objc_retain(i8* %x) 3033*9880d681SAndroid Build Coastguard Worker call i32 @objc_sync_enter(i8* %x) 3034*9880d681SAndroid Build Coastguard Worker call i32 @objc_sync_exit(i8* %x) 3035*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x), !clang.imprecise_release !0 3036*9880d681SAndroid Build Coastguard Worker ret void 3037*9880d681SAndroid Build Coastguard Worker} 3038*9880d681SAndroid Build Coastguard Worker 3039*9880d681SAndroid Build Coastguard Worker!llvm.module.flags = !{!1} 3040*9880d681SAndroid Build Coastguard Worker!llvm.dbg.cu = !{!3} 3041*9880d681SAndroid Build Coastguard Worker 3042*9880d681SAndroid Build Coastguard Worker!0 = !{} 3043*9880d681SAndroid Build Coastguard Worker!1 = !{i32 1, !"Debug Info Version", i32 3} 3044*9880d681SAndroid Build Coastguard Worker!2 = distinct !DISubprogram(unit: !3) 3045*9880d681SAndroid Build Coastguard Worker!3 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang", 3046*9880d681SAndroid Build Coastguard Worker file: !4, 3047*9880d681SAndroid Build Coastguard Worker isOptimized: true, flags: "-O2", 3048*9880d681SAndroid Build Coastguard Worker splitDebugFilename: "abc.debug", emissionKind: 2) 3049*9880d681SAndroid Build Coastguard Worker!4 = !DIFile(filename: "path/to/file", directory: "/path/to/dir") 3050*9880d681SAndroid Build Coastguard Worker!5 = !{i32 2, !"Debug Info Version", i32 3} 3051*9880d681SAndroid Build Coastguard Worker 3052*9880d681SAndroid Build Coastguard Worker; CHECK: attributes #0 = { nounwind readnone } 3053*9880d681SAndroid Build Coastguard Worker; CHECK: attributes [[NUW]] = { nounwind } 3054*9880d681SAndroid Build Coastguard Worker; CHECK: ![[RELEASE]] = !{} 3055