1*9880d681SAndroid Build Coastguard Worker; RUN: opt -objc-arc -S < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retain(i8*) 4*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainAutoreleasedReturnValue(i8*) 5*9880d681SAndroid Build Coastguard Workerdeclare void @objc_release(i8*) 6*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_autorelease(i8*) 7*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_autoreleaseReturnValue(i8*) 8*9880d681SAndroid Build Coastguard Workerdeclare void @objc_autoreleasePoolPop(i8*) 9*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_autoreleasePoolPush() 10*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainBlock(i8*) 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainedObject(i8*) 13*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_unretainedObject(i8*) 14*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_unretainedPointer(i8*) 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Workerdeclare void @use_pointer(i8*) 17*9880d681SAndroid Build Coastguard Workerdeclare void @callee() 18*9880d681SAndroid Build Coastguard Workerdeclare void @callee_fnptr(void ()*) 19*9880d681SAndroid Build Coastguard Workerdeclare void @invokee() 20*9880d681SAndroid Build Coastguard Workerdeclare i8* @returner() 21*9880d681SAndroid Build Coastguard Workerdeclare i8* @returner1() 22*9880d681SAndroid Build Coastguard Workerdeclare i8* @returner2() 23*9880d681SAndroid Build Coastguard Workerdeclare void @bar(i32 ()*) 24*9880d681SAndroid Build Coastguard Workerdeclare void @use_alloca(i8**) 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 31*9880d681SAndroid Build Coastguard Worker; In the presence of allocas, unconditionally remove retain/release pairs only 32*9880d681SAndroid Build Coastguard Worker; if they are known safe in both directions. This prevents matching up an inner 33*9880d681SAndroid Build Coastguard Worker; retain with the boundary guarding release in the following situation: 34*9880d681SAndroid Build Coastguard Worker; 35*9880d681SAndroid Build Coastguard Worker; %A = alloca 36*9880d681SAndroid Build Coastguard Worker; retain(%x) 37*9880d681SAndroid Build Coastguard Worker; retain(%x) <--- Inner Retain 38*9880d681SAndroid Build Coastguard Worker; store %x, %A 39*9880d681SAndroid Build Coastguard Worker; %y = load %A 40*9880d681SAndroid Build Coastguard Worker; ... DO STUFF ... 41*9880d681SAndroid Build Coastguard Worker; release(%y) 42*9880d681SAndroid Build Coastguard Worker; release(%x) <--- Guarding Release 43*9880d681SAndroid Build Coastguard Worker; 44*9880d681SAndroid Build Coastguard Worker; rdar://13750319 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1a(i8* %x) 47*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 48*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 49*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y) 50*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x) 51*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 52*9880d681SAndroid Build Coastguard Worker; CHECK: } 53*9880d681SAndroid Build Coastguard Workerdefine void @test1a(i8* %x) { 54*9880d681SAndroid Build Coastguard Workerentry: 55*9880d681SAndroid Build Coastguard Worker %A = alloca i8* 56*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 57*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 58*9880d681SAndroid Build Coastguard Worker store i8* %x, i8** %A, align 8 59*9880d681SAndroid Build Coastguard Worker %y = load i8*, i8** %A 60*9880d681SAndroid Build Coastguard Worker call void @use_alloca(i8** %A) 61*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %y), !clang.imprecise_release !0 62*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 63*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x), !clang.imprecise_release !0 64*9880d681SAndroid Build Coastguard Worker ret void 65*9880d681SAndroid Build Coastguard Worker} 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1b(i8* %x) 68*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 69*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 70*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y) 71*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x) 72*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 73*9880d681SAndroid Build Coastguard Worker; CHECK: } 74*9880d681SAndroid Build Coastguard Workerdefine void @test1b(i8* %x) { 75*9880d681SAndroid Build Coastguard Workerentry: 76*9880d681SAndroid Build Coastguard Worker %A = alloca i8* 77*9880d681SAndroid Build Coastguard Worker %gep = getelementptr i8*, i8** %A, i32 0 78*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 79*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 80*9880d681SAndroid Build Coastguard Worker store i8* %x, i8** %gep, align 8 81*9880d681SAndroid Build Coastguard Worker %y = load i8*, i8** %A 82*9880d681SAndroid Build Coastguard Worker call void @use_alloca(i8** %A) 83*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %y), !clang.imprecise_release !0 84*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 85*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x), !clang.imprecise_release !0 86*9880d681SAndroid Build Coastguard Worker ret void 87*9880d681SAndroid Build Coastguard Worker} 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1c(i8* %x) 91*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 92*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 93*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y) 94*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x) 95*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 96*9880d681SAndroid Build Coastguard Worker; CHECK: } 97*9880d681SAndroid Build Coastguard Workerdefine void @test1c(i8* %x) { 98*9880d681SAndroid Build Coastguard Workerentry: 99*9880d681SAndroid Build Coastguard Worker %A = alloca i8*, i32 3 100*9880d681SAndroid Build Coastguard Worker %gep = getelementptr i8*, i8** %A, i32 2 101*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 102*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 103*9880d681SAndroid Build Coastguard Worker store i8* %x, i8** %gep, align 8 104*9880d681SAndroid Build Coastguard Worker %y = load i8*, i8** %gep 105*9880d681SAndroid Build Coastguard Worker call void @use_alloca(i8** %A) 106*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %y), !clang.imprecise_release !0 107*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 108*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x), !clang.imprecise_release !0 109*9880d681SAndroid Build Coastguard Worker ret void 110*9880d681SAndroid Build Coastguard Worker} 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1d(i8* %x) 114*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 115*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 116*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y) 117*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x) 118*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 119*9880d681SAndroid Build Coastguard Worker; CHECK: } 120*9880d681SAndroid Build Coastguard Workerdefine void @test1d(i8* %x) { 121*9880d681SAndroid Build Coastguard Workerentry: 122*9880d681SAndroid Build Coastguard Worker br i1 undef, label %use_allocaA, label %use_allocaB 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Workeruse_allocaA: 125*9880d681SAndroid Build Coastguard Worker %allocaA = alloca i8* 126*9880d681SAndroid Build Coastguard Worker br label %exit 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Workeruse_allocaB: 129*9880d681SAndroid Build Coastguard Worker %allocaB = alloca i8* 130*9880d681SAndroid Build Coastguard Worker br label %exit 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Workerexit: 133*9880d681SAndroid Build Coastguard Worker %A = phi i8** [ %allocaA, %use_allocaA ], [ %allocaB, %use_allocaB ] 134*9880d681SAndroid Build Coastguard Worker %gep = getelementptr i8*, i8** %A, i32 0 135*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 136*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 137*9880d681SAndroid Build Coastguard Worker store i8* %x, i8** %gep, align 8 138*9880d681SAndroid Build Coastguard Worker %y = load i8*, i8** %gep 139*9880d681SAndroid Build Coastguard Worker call void @use_alloca(i8** %A) 140*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %y), !clang.imprecise_release !0 141*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 142*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x), !clang.imprecise_release !0 143*9880d681SAndroid Build Coastguard Worker ret void 144*9880d681SAndroid Build Coastguard Worker} 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1e(i8* %x) 147*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 148*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 149*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y) 150*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x) 151*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 152*9880d681SAndroid Build Coastguard Worker; CHECK: } 153*9880d681SAndroid Build Coastguard Workerdefine void @test1e(i8* %x) { 154*9880d681SAndroid Build Coastguard Workerentry: 155*9880d681SAndroid Build Coastguard Worker br i1 undef, label %use_allocaA, label %use_allocaB 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Workeruse_allocaA: 158*9880d681SAndroid Build Coastguard Worker %allocaA = alloca i8*, i32 4 159*9880d681SAndroid Build Coastguard Worker br label %exit 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Workeruse_allocaB: 162*9880d681SAndroid Build Coastguard Worker %allocaB = alloca i8*, i32 4 163*9880d681SAndroid Build Coastguard Worker br label %exit 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Workerexit: 166*9880d681SAndroid Build Coastguard Worker %A = phi i8** [ %allocaA, %use_allocaA ], [ %allocaB, %use_allocaB ] 167*9880d681SAndroid Build Coastguard Worker %gep = getelementptr i8*, i8** %A, i32 2 168*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 169*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 170*9880d681SAndroid Build Coastguard Worker store i8* %x, i8** %gep, align 8 171*9880d681SAndroid Build Coastguard Worker %y = load i8*, i8** %gep 172*9880d681SAndroid Build Coastguard Worker call void @use_alloca(i8** %A) 173*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %y), !clang.imprecise_release !0 174*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 175*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x), !clang.imprecise_release !0 176*9880d681SAndroid Build Coastguard Worker ret void 177*9880d681SAndroid Build Coastguard Worker} 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1f(i8* %x) 180*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 181*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 182*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y) 183*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x) 184*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 185*9880d681SAndroid Build Coastguard Worker; CHECK: } 186*9880d681SAndroid Build Coastguard Workerdefine void @test1f(i8* %x) { 187*9880d681SAndroid Build Coastguard Workerentry: 188*9880d681SAndroid Build Coastguard Worker %allocaOne = alloca i8* 189*9880d681SAndroid Build Coastguard Worker %allocaTwo = alloca i8* 190*9880d681SAndroid Build Coastguard Worker %A = select i1 undef, i8** %allocaOne, i8** %allocaTwo 191*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 192*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 193*9880d681SAndroid Build Coastguard Worker store i8* %x, i8** %A, align 8 194*9880d681SAndroid Build Coastguard Worker %y = load i8*, i8** %A 195*9880d681SAndroid Build Coastguard Worker call void @use_alloca(i8** %A) 196*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %y), !clang.imprecise_release !0 197*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 198*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x), !clang.imprecise_release !0 199*9880d681SAndroid Build Coastguard Worker ret void 200*9880d681SAndroid Build Coastguard Worker} 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Worker; Make sure that if a store is in a different basic block we handle known safe 203*9880d681SAndroid Build Coastguard Worker; conservatively. 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Worker 206*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test2a(i8* %x) 207*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 208*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 209*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y) 210*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x) 211*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 212*9880d681SAndroid Build Coastguard Worker; CHECK: } 213*9880d681SAndroid Build Coastguard Workerdefine void @test2a(i8* %x) { 214*9880d681SAndroid Build Coastguard Workerentry: 215*9880d681SAndroid Build Coastguard Worker %A = alloca i8* 216*9880d681SAndroid Build Coastguard Worker store i8* %x, i8** %A, align 8 217*9880d681SAndroid Build Coastguard Worker %y = load i8*, i8** %A 218*9880d681SAndroid Build Coastguard Worker br label %bb1 219*9880d681SAndroid Build Coastguard Worker 220*9880d681SAndroid Build Coastguard Workerbb1: 221*9880d681SAndroid Build Coastguard Worker br label %bb2 222*9880d681SAndroid Build Coastguard Worker 223*9880d681SAndroid Build Coastguard Workerbb2: 224*9880d681SAndroid Build Coastguard Worker br label %bb3 225*9880d681SAndroid Build Coastguard Worker 226*9880d681SAndroid Build Coastguard Workerbb3: 227*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 228*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 229*9880d681SAndroid Build Coastguard Worker call void @use_alloca(i8** %A) 230*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %y), !clang.imprecise_release !0 231*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 232*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x), !clang.imprecise_release !0 233*9880d681SAndroid Build Coastguard Worker ret void 234*9880d681SAndroid Build Coastguard Worker} 235*9880d681SAndroid Build Coastguard Worker 236*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test2b(i8* %x) 237*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 238*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 239*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y) 240*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x) 241*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 242*9880d681SAndroid Build Coastguard Worker; CHECK: } 243*9880d681SAndroid Build Coastguard Workerdefine void @test2b(i8* %x) { 244*9880d681SAndroid Build Coastguard Workerentry: 245*9880d681SAndroid Build Coastguard Worker %A = alloca i8* 246*9880d681SAndroid Build Coastguard Worker %gep1 = getelementptr i8*, i8** %A, i32 0 247*9880d681SAndroid Build Coastguard Worker store i8* %x, i8** %gep1, align 8 248*9880d681SAndroid Build Coastguard Worker %gep2 = getelementptr i8*, i8** %A, i32 0 249*9880d681SAndroid Build Coastguard Worker %y = load i8*, i8** %gep2 250*9880d681SAndroid Build Coastguard Worker br label %bb1 251*9880d681SAndroid Build Coastguard Worker 252*9880d681SAndroid Build Coastguard Workerbb1: 253*9880d681SAndroid Build Coastguard Worker br label %bb2 254*9880d681SAndroid Build Coastguard Worker 255*9880d681SAndroid Build Coastguard Workerbb2: 256*9880d681SAndroid Build Coastguard Worker br label %bb3 257*9880d681SAndroid Build Coastguard Worker 258*9880d681SAndroid Build Coastguard Workerbb3: 259*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 260*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 261*9880d681SAndroid Build Coastguard Worker call void @use_alloca(i8** %A) 262*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %y), !clang.imprecise_release !0 263*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 264*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x), !clang.imprecise_release !0 265*9880d681SAndroid Build Coastguard Worker ret void 266*9880d681SAndroid Build Coastguard Worker} 267*9880d681SAndroid Build Coastguard Worker 268*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test2c(i8* %x) 269*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 270*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 271*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y) 272*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x) 273*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 274*9880d681SAndroid Build Coastguard Worker; CHECK: } 275*9880d681SAndroid Build Coastguard Workerdefine void @test2c(i8* %x) { 276*9880d681SAndroid Build Coastguard Workerentry: 277*9880d681SAndroid Build Coastguard Worker %A = alloca i8*, i32 3 278*9880d681SAndroid Build Coastguard Worker %gep1 = getelementptr i8*, i8** %A, i32 2 279*9880d681SAndroid Build Coastguard Worker store i8* %x, i8** %gep1, align 8 280*9880d681SAndroid Build Coastguard Worker %gep2 = getelementptr i8*, i8** %A, i32 2 281*9880d681SAndroid Build Coastguard Worker %y = load i8*, i8** %gep2 282*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 283*9880d681SAndroid Build Coastguard Worker br label %bb1 284*9880d681SAndroid Build Coastguard Worker 285*9880d681SAndroid Build Coastguard Workerbb1: 286*9880d681SAndroid Build Coastguard Worker br label %bb2 287*9880d681SAndroid Build Coastguard Worker 288*9880d681SAndroid Build Coastguard Workerbb2: 289*9880d681SAndroid Build Coastguard Worker br label %bb3 290*9880d681SAndroid Build Coastguard Worker 291*9880d681SAndroid Build Coastguard Workerbb3: 292*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 293*9880d681SAndroid Build Coastguard Worker call void @use_alloca(i8** %A) 294*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %y), !clang.imprecise_release !0 295*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 296*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x), !clang.imprecise_release !0 297*9880d681SAndroid Build Coastguard Worker ret void 298*9880d681SAndroid Build Coastguard Worker} 299*9880d681SAndroid Build Coastguard Worker 300*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test2d(i8* %x) 301*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 302*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x) 303*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y) 304*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x) 305*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 306*9880d681SAndroid Build Coastguard Worker; CHECK: } 307*9880d681SAndroid Build Coastguard Workerdefine void @test2d(i8* %x) { 308*9880d681SAndroid Build Coastguard Workerentry: 309*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 310*9880d681SAndroid Build Coastguard Worker br label %bb1 311*9880d681SAndroid Build Coastguard Worker 312*9880d681SAndroid Build Coastguard Workerbb1: 313*9880d681SAndroid Build Coastguard Worker %Abb1 = alloca i8*, i32 3 314*9880d681SAndroid Build Coastguard Worker %gepbb11 = getelementptr i8*, i8** %Abb1, i32 2 315*9880d681SAndroid Build Coastguard Worker store i8* %x, i8** %gepbb11, align 8 316*9880d681SAndroid Build Coastguard Worker %gepbb12 = getelementptr i8*, i8** %Abb1, i32 2 317*9880d681SAndroid Build Coastguard Worker %ybb1 = load i8*, i8** %gepbb12 318*9880d681SAndroid Build Coastguard Worker br label %bb3 319*9880d681SAndroid Build Coastguard Worker 320*9880d681SAndroid Build Coastguard Workerbb2: 321*9880d681SAndroid Build Coastguard Worker %Abb2 = alloca i8*, i32 4 322*9880d681SAndroid Build Coastguard Worker %gepbb21 = getelementptr i8*, i8** %Abb2, i32 2 323*9880d681SAndroid Build Coastguard Worker store i8* %x, i8** %gepbb21, align 8 324*9880d681SAndroid Build Coastguard Worker %gepbb22 = getelementptr i8*, i8** %Abb2, i32 2 325*9880d681SAndroid Build Coastguard Worker %ybb2 = load i8*, i8** %gepbb22 326*9880d681SAndroid Build Coastguard Worker br label %bb3 327*9880d681SAndroid Build Coastguard Worker 328*9880d681SAndroid Build Coastguard Workerbb3: 329*9880d681SAndroid Build Coastguard Worker %A = phi i8** [ %Abb1, %bb1 ], [ %Abb2, %bb2 ] 330*9880d681SAndroid Build Coastguard Worker %y = phi i8* [ %ybb1, %bb1 ], [ %ybb2, %bb2 ] 331*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %x) 332*9880d681SAndroid Build Coastguard Worker call void @use_alloca(i8** %A) 333*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %y), !clang.imprecise_release !0 334*9880d681SAndroid Build Coastguard Worker call void @use_pointer(i8* %x) 335*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %x), !clang.imprecise_release !0 336*9880d681SAndroid Build Coastguard Worker ret void 337*9880d681SAndroid Build Coastguard Worker} 338*9880d681SAndroid Build Coastguard Worker 339*9880d681SAndroid Build Coastguard Worker; Make sure in the presence of allocas, if we find a cfghazard we do not perform 340*9880d681SAndroid Build Coastguard Worker; code motion even if we are known safe. These two concepts are separate and 341*9880d681SAndroid Build Coastguard Worker; should be treated as such. 342*9880d681SAndroid Build Coastguard Worker; 343*9880d681SAndroid Build Coastguard Worker; rdar://13949644 344*9880d681SAndroid Build Coastguard Worker 345*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test3a() { 346*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 347*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retainAutoreleasedReturnValue 348*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 349*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 350*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 351*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 352*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.body: 353*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 354*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 355*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.done: 356*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 357*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.body1: 358*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 359*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 360*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.done1: 361*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 362*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 363*9880d681SAndroid Build Coastguard Worker; CHECK: } 364*9880d681SAndroid Build Coastguard Workerdefine void @test3a() { 365*9880d681SAndroid Build Coastguard Workerentry: 366*9880d681SAndroid Build Coastguard Worker %keys = alloca [2 x i8*], align 16 367*9880d681SAndroid Build Coastguard Worker %objs = alloca [2 x i8*], align 16 368*9880d681SAndroid Build Coastguard Worker 369*9880d681SAndroid Build Coastguard Worker %call1 = call i8* @returner() 370*9880d681SAndroid Build Coastguard Worker %tmp0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call1) 371*9880d681SAndroid Build Coastguard Worker 372*9880d681SAndroid Build Coastguard Worker %objs.begin = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 0 373*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %call1) 374*9880d681SAndroid Build Coastguard Worker store i8* %call1, i8** %objs.begin, align 8 375*9880d681SAndroid Build Coastguard Worker %objs.elt = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 1 376*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %call1) 377*9880d681SAndroid Build Coastguard Worker store i8* %call1, i8** %objs.elt 378*9880d681SAndroid Build Coastguard Worker 379*9880d681SAndroid Build Coastguard Worker %call2 = call i8* @returner1() 380*9880d681SAndroid Build Coastguard Worker %call3 = call i8* @returner2() 381*9880d681SAndroid Build Coastguard Worker %keys.begin = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 0 382*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %call2) 383*9880d681SAndroid Build Coastguard Worker store i8* %call2, i8** %keys.begin, align 8 384*9880d681SAndroid Build Coastguard Worker %keys.elt = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 1 385*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %call3) 386*9880d681SAndroid Build Coastguard Worker store i8* %call3, i8** %keys.elt 387*9880d681SAndroid Build Coastguard Worker 388*9880d681SAndroid Build Coastguard Worker %gep = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 2 389*9880d681SAndroid Build Coastguard Worker br label %arraydestroy.body 390*9880d681SAndroid Build Coastguard Worker 391*9880d681SAndroid Build Coastguard Workerarraydestroy.body: 392*9880d681SAndroid Build Coastguard Worker %arraydestroy.elementPast = phi i8** [ %gep, %entry ], [ %arraydestroy.element, %arraydestroy.body ] 393*9880d681SAndroid Build Coastguard Worker %arraydestroy.element = getelementptr inbounds i8*, i8** %arraydestroy.elementPast, i64 -1 394*9880d681SAndroid Build Coastguard Worker %destroy_tmp = load i8*, i8** %arraydestroy.element, align 8 395*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %destroy_tmp), !clang.imprecise_release !0 396*9880d681SAndroid Build Coastguard Worker %objs_ptr = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 0 397*9880d681SAndroid Build Coastguard Worker %arraydestroy.cmp = icmp eq i8** %arraydestroy.element, %objs_ptr 398*9880d681SAndroid Build Coastguard Worker br i1 %arraydestroy.cmp, label %arraydestroy.done, label %arraydestroy.body 399*9880d681SAndroid Build Coastguard Worker 400*9880d681SAndroid Build Coastguard Workerarraydestroy.done: 401*9880d681SAndroid Build Coastguard Worker %gep1 = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 2 402*9880d681SAndroid Build Coastguard Worker br label %arraydestroy.body1 403*9880d681SAndroid Build Coastguard Worker 404*9880d681SAndroid Build Coastguard Workerarraydestroy.body1: 405*9880d681SAndroid Build Coastguard Worker %arraydestroy.elementPast1 = phi i8** [ %gep1, %arraydestroy.done ], [ %arraydestroy.element1, %arraydestroy.body1 ] 406*9880d681SAndroid Build Coastguard Worker %arraydestroy.element1 = getelementptr inbounds i8*, i8** %arraydestroy.elementPast1, i64 -1 407*9880d681SAndroid Build Coastguard Worker %destroy_tmp1 = load i8*, i8** %arraydestroy.element1, align 8 408*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %destroy_tmp1), !clang.imprecise_release !0 409*9880d681SAndroid Build Coastguard Worker %keys_ptr = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 0 410*9880d681SAndroid Build Coastguard Worker %arraydestroy.cmp1 = icmp eq i8** %arraydestroy.element1, %keys_ptr 411*9880d681SAndroid Build Coastguard Worker br i1 %arraydestroy.cmp1, label %arraydestroy.done1, label %arraydestroy.body1 412*9880d681SAndroid Build Coastguard Worker 413*9880d681SAndroid Build Coastguard Workerarraydestroy.done1: 414*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %call1), !clang.imprecise_release !0 415*9880d681SAndroid Build Coastguard Worker ret void 416*9880d681SAndroid Build Coastguard Worker} 417*9880d681SAndroid Build Coastguard Worker 418*9880d681SAndroid Build Coastguard Worker; Make sure that even though we stop said code motion we still allow for 419*9880d681SAndroid Build Coastguard Worker; pointers to be removed if we are known safe in both directions. 420*9880d681SAndroid Build Coastguard Worker; 421*9880d681SAndroid Build Coastguard Worker; rdar://13949644 422*9880d681SAndroid Build Coastguard Worker 423*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test3b() { 424*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 425*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retainAutoreleasedReturnValue 426*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 427*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 428*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 429*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain 430*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.body: 431*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 432*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 433*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.done: 434*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 435*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.body1: 436*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 437*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release 438*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.done1: 439*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release 440*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 441*9880d681SAndroid Build Coastguard Worker; CHECK: } 442*9880d681SAndroid Build Coastguard Workerdefine void @test3b() { 443*9880d681SAndroid Build Coastguard Workerentry: 444*9880d681SAndroid Build Coastguard Worker %keys = alloca [2 x i8*], align 16 445*9880d681SAndroid Build Coastguard Worker %objs = alloca [2 x i8*], align 16 446*9880d681SAndroid Build Coastguard Worker 447*9880d681SAndroid Build Coastguard Worker %call1 = call i8* @returner() 448*9880d681SAndroid Build Coastguard Worker %tmp0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call1) 449*9880d681SAndroid Build Coastguard Worker %tmp1 = tail call i8* @objc_retain(i8* %call1) 450*9880d681SAndroid Build Coastguard Worker 451*9880d681SAndroid Build Coastguard Worker %objs.begin = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 0 452*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %call1) 453*9880d681SAndroid Build Coastguard Worker store i8* %call1, i8** %objs.begin, align 8 454*9880d681SAndroid Build Coastguard Worker %objs.elt = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 1 455*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %call1) 456*9880d681SAndroid Build Coastguard Worker store i8* %call1, i8** %objs.elt 457*9880d681SAndroid Build Coastguard Worker 458*9880d681SAndroid Build Coastguard Worker %call2 = call i8* @returner1() 459*9880d681SAndroid Build Coastguard Worker %call3 = call i8* @returner2() 460*9880d681SAndroid Build Coastguard Worker %keys.begin = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 0 461*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %call2) 462*9880d681SAndroid Build Coastguard Worker store i8* %call2, i8** %keys.begin, align 8 463*9880d681SAndroid Build Coastguard Worker %keys.elt = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 1 464*9880d681SAndroid Build Coastguard Worker tail call i8* @objc_retain(i8* %call3) 465*9880d681SAndroid Build Coastguard Worker store i8* %call3, i8** %keys.elt 466*9880d681SAndroid Build Coastguard Worker 467*9880d681SAndroid Build Coastguard Worker %gep = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 2 468*9880d681SAndroid Build Coastguard Worker br label %arraydestroy.body 469*9880d681SAndroid Build Coastguard Worker 470*9880d681SAndroid Build Coastguard Workerarraydestroy.body: 471*9880d681SAndroid Build Coastguard Worker %arraydestroy.elementPast = phi i8** [ %gep, %entry ], [ %arraydestroy.element, %arraydestroy.body ] 472*9880d681SAndroid Build Coastguard Worker %arraydestroy.element = getelementptr inbounds i8*, i8** %arraydestroy.elementPast, i64 -1 473*9880d681SAndroid Build Coastguard Worker %destroy_tmp = load i8*, i8** %arraydestroy.element, align 8 474*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %destroy_tmp), !clang.imprecise_release !0 475*9880d681SAndroid Build Coastguard Worker %objs_ptr = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 0 476*9880d681SAndroid Build Coastguard Worker %arraydestroy.cmp = icmp eq i8** %arraydestroy.element, %objs_ptr 477*9880d681SAndroid Build Coastguard Worker br i1 %arraydestroy.cmp, label %arraydestroy.done, label %arraydestroy.body 478*9880d681SAndroid Build Coastguard Worker 479*9880d681SAndroid Build Coastguard Workerarraydestroy.done: 480*9880d681SAndroid Build Coastguard Worker %gep1 = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 2 481*9880d681SAndroid Build Coastguard Worker br label %arraydestroy.body1 482*9880d681SAndroid Build Coastguard Worker 483*9880d681SAndroid Build Coastguard Workerarraydestroy.body1: 484*9880d681SAndroid Build Coastguard Worker %arraydestroy.elementPast1 = phi i8** [ %gep1, %arraydestroy.done ], [ %arraydestroy.element1, %arraydestroy.body1 ] 485*9880d681SAndroid Build Coastguard Worker %arraydestroy.element1 = getelementptr inbounds i8*, i8** %arraydestroy.elementPast1, i64 -1 486*9880d681SAndroid Build Coastguard Worker %destroy_tmp1 = load i8*, i8** %arraydestroy.element1, align 8 487*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %destroy_tmp1), !clang.imprecise_release !0 488*9880d681SAndroid Build Coastguard Worker %keys_ptr = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 0 489*9880d681SAndroid Build Coastguard Worker %arraydestroy.cmp1 = icmp eq i8** %arraydestroy.element1, %keys_ptr 490*9880d681SAndroid Build Coastguard Worker br i1 %arraydestroy.cmp1, label %arraydestroy.done1, label %arraydestroy.body1 491*9880d681SAndroid Build Coastguard Worker 492*9880d681SAndroid Build Coastguard Workerarraydestroy.done1: 493*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %call1), !clang.imprecise_release !0 494*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %call1), !clang.imprecise_release !0 495*9880d681SAndroid Build Coastguard Worker ret void 496*9880d681SAndroid Build Coastguard Worker} 497*9880d681SAndroid Build Coastguard Worker 498*9880d681SAndroid Build Coastguard Worker!0 = !{} 499*9880d681SAndroid Build Coastguard Worker 500*9880d681SAndroid Build Coastguard Workerdeclare i32 @__gxx_personality_v0(...) 501