1*67e74705SXin Li// Make sure it works on x86-64. 2*67e74705SXin Li// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime=macosx-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED 3*67e74705SXin Li 4*67e74705SXin Li// Make sure it works on ARM. 5*67e74705SXin Li// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED 6*67e74705SXin Li// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED 7*67e74705SXin Li 8*67e74705SXin Li// Make sure it works on ARM64. 9*67e74705SXin Li// RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED 10*67e74705SXin Li// RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED 11*67e74705SXin Li 12*67e74705SXin Li// Make sure that it's implicitly disabled if the runtime version isn't high enough. 13*67e74705SXin Li// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-10.10 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=DISABLED 14*67e74705SXin Li// RUN: %clang_cc1 -triple arm64-apple-ios8 -fobjc-runtime=ios-8 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=DISABLED -check-prefix=DISABLED-MARKED 15*67e74705SXin Li 16*67e74705SXin Li@class A; 17*67e74705SXin Li 18*67e74705SXin LiA *makeA(void); 19*67e74705SXin Li 20*67e74705SXin Livoid test_assign() { 21*67e74705SXin Li __unsafe_unretained id x; 22*67e74705SXin Li x = makeA(); 23*67e74705SXin Li} 24*67e74705SXin Li// CHECK-LABEL: define void @test_assign() 25*67e74705SXin Li// CHECK: [[X:%.*]] = alloca i8* 26*67e74705SXin Li// CHECK: [[T0:%.*]] = call [[A:.*]]* @makeA() 27*67e74705SXin Li// CHECK-MARKED-NEXT: call void asm sideeffect 28*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 29*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) 30*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* 31*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* 32*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[X]] 33*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 34*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 35*67e74705SXin Li// CHECK-NEXT: ret void 36*67e74705SXin Li 37*67e74705SXin Li// DISABLED-LABEL: define void @test_assign() 38*67e74705SXin Li// DISABLED: [[T0:%.*]] = call [[A:.*]]* @makeA() 39*67e74705SXin Li// DISABLED-MARKED-NEXT: call void asm sideeffect 40*67e74705SXin Li// DISABLED-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 41*67e74705SXin Li// DISABLED-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 42*67e74705SXin Li 43*67e74705SXin Livoid test_assign_assign() { 44*67e74705SXin Li __unsafe_unretained id x, y; 45*67e74705SXin Li x = y = makeA(); 46*67e74705SXin Li} 47*67e74705SXin Li// CHECK-LABEL: define void @test_assign_assign() 48*67e74705SXin Li// CHECK: [[X:%.*]] = alloca i8* 49*67e74705SXin Li// CHECK: [[Y:%.*]] = alloca i8* 50*67e74705SXin Li// CHECK: [[T0:%.*]] = call [[A]]* @makeA() 51*67e74705SXin Li// CHECK-MARKED-NEXT: call void asm sideeffect 52*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 53*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) 54*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* 55*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* 56*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[Y]] 57*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[X]] 58*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 59*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 60*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 61*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 62*67e74705SXin Li// CHECK-NEXT: ret void 63*67e74705SXin Li 64*67e74705SXin Livoid test_strong_assign_assign() { 65*67e74705SXin Li __strong id x; 66*67e74705SXin Li __unsafe_unretained id y; 67*67e74705SXin Li x = y = makeA(); 68*67e74705SXin Li} 69*67e74705SXin Li// CHECK-LABEL: define void @test_strong_assign_assign() 70*67e74705SXin Li// CHECK: [[X:%.*]] = alloca i8* 71*67e74705SXin Li// CHECK: [[Y:%.*]] = alloca i8* 72*67e74705SXin Li// CHECK: [[T0:%.*]] = call [[A]]* @makeA() 73*67e74705SXin Li// CHECK-MARKED-NEXT: call void asm sideeffect 74*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 75*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 76*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* 77*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* 78*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[Y]] 79*67e74705SXin Li// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]] 80*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[X]] 81*67e74705SXin Li// CHECK-NEXT: call void @objc_release(i8* [[OLD]] 82*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 83*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 84*67e74705SXin Li// CHECK-UNOPTIMIZED-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) 85*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] 86*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: call void @objc_release(i8* [[T0]]) 87*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 88*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 89*67e74705SXin Li// CHECK-NEXT: ret void 90*67e74705SXin Li 91*67e74705SXin Livoid test_assign_strong_assign() { 92*67e74705SXin Li __unsafe_unretained id x; 93*67e74705SXin Li __strong id y; 94*67e74705SXin Li x = y = makeA(); 95*67e74705SXin Li} 96*67e74705SXin Li// CHECK-LABEL: define void @test_assign_strong_assign() 97*67e74705SXin Li// CHECK: [[X:%.*]] = alloca i8* 98*67e74705SXin Li// CHECK: [[Y:%.*]] = alloca i8* 99*67e74705SXin Li// CHECK: [[T0:%.*]] = call [[A]]* @makeA() 100*67e74705SXin Li// CHECK-MARKED-NEXT: call void asm sideeffect 101*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 102*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 103*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* 104*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* 105*67e74705SXin Li// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[Y]] 106*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[Y]] 107*67e74705SXin Li// CHECK-NEXT: call void @objc_release(i8* [[OLD]] 108*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[X]] 109*67e74705SXin Li// CHECK-UNOPTIMIZED-NEXT: call void @objc_storeStrong(i8** [[Y]], i8* null) 110*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] 111*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: call void @objc_release(i8* [[T0]]) 112*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 113*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 114*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 115*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 116*67e74705SXin Li// CHECK-NEXT: ret void 117*67e74705SXin Li 118*67e74705SXin Livoid test_init() { 119*67e74705SXin Li __unsafe_unretained id x = makeA(); 120*67e74705SXin Li} 121*67e74705SXin Li// CHECK-LABEL: define void @test_init() 122*67e74705SXin Li// CHECK: [[X:%.*]] = alloca i8* 123*67e74705SXin Li// CHECK: [[T0:%.*]] = call [[A]]* @makeA() 124*67e74705SXin Li// CHECK-MARKED-NEXT: call void asm sideeffect 125*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 126*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) 127*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* 128*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* 129*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[X]] 130*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 131*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 132*67e74705SXin Li// CHECK-NEXT: ret void 133*67e74705SXin Li 134*67e74705SXin Livoid test_init_assignment() { 135*67e74705SXin Li __unsafe_unretained id x; 136*67e74705SXin Li __unsafe_unretained id y = x = makeA(); 137*67e74705SXin Li} 138*67e74705SXin Li// CHECK-LABEL: define void @test_init_assignment() 139*67e74705SXin Li// CHECK: [[X:%.*]] = alloca i8* 140*67e74705SXin Li// CHECK: [[Y:%.*]] = alloca i8* 141*67e74705SXin Li// CHECK: [[T0:%.*]] = call [[A]]* @makeA() 142*67e74705SXin Li// CHECK-MARKED-NEXT: call void asm sideeffect 143*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 144*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) 145*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* 146*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* 147*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[X]] 148*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[Y]] 149*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 150*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 151*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 152*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 153*67e74705SXin Li// CHECK-NEXT: ret void 154*67e74705SXin Li 155*67e74705SXin Livoid test_strong_init_assignment() { 156*67e74705SXin Li __unsafe_unretained id x; 157*67e74705SXin Li __strong id y = x = makeA(); 158*67e74705SXin Li} 159*67e74705SXin Li// CHECK-LABEL: define void @test_strong_init_assignment() 160*67e74705SXin Li// CHECK: [[X:%.*]] = alloca i8* 161*67e74705SXin Li// CHECK: [[Y:%.*]] = alloca i8* 162*67e74705SXin Li// CHECK: [[T0:%.*]] = call [[A]]* @makeA() 163*67e74705SXin Li// CHECK-MARKED-NEXT: call void asm sideeffect 164*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 165*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 166*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* 167*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* 168*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[X]] 169*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[Y]] 170*67e74705SXin Li// CHECK-UNOPTIMIZED-NEXT: call void @objc_storeStrong(i8** [[Y]], i8* null) 171*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] 172*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: call void @objc_release(i8* [[T0]]) 173*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 174*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 175*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 176*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 177*67e74705SXin Li// CHECK-NEXT: ret void 178*67e74705SXin Li 179*67e74705SXin Livoid test_init_strong_assignment() { 180*67e74705SXin Li __strong id x; 181*67e74705SXin Li __unsafe_unretained id y = x = makeA(); 182*67e74705SXin Li} 183*67e74705SXin Li// CHECK-LABEL: define void @test_init_strong_assignment() 184*67e74705SXin Li// CHECK: [[X:%.*]] = alloca i8* 185*67e74705SXin Li// CHECK: [[Y:%.*]] = alloca i8* 186*67e74705SXin Li// CHECK: [[T0:%.*]] = call [[A]]* @makeA() 187*67e74705SXin Li// CHECK-MARKED-NEXT: call void asm sideeffect 188*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 189*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]]) 190*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* 191*67e74705SXin Li// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8* 192*67e74705SXin Li// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]] 193*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[X]] 194*67e74705SXin Li// CHECK-NEXT: call void @objc_release(i8* [[OLD]]) 195*67e74705SXin Li// CHECK-NEXT: store i8* [[T4]], i8** [[Y]] 196*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 197*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 198*67e74705SXin Li// CHECK-UNOPTIMIZED-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) 199*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] 200*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: call void @objc_release(i8* [[T0]]) 201*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: bitcast 202*67e74705SXin Li// CHECK-OPTIMIZED-NEXT: lifetime.end 203*67e74705SXin Li// CHECK-NEXT: ret void 204*67e74705SXin Li 205*67e74705SXin Livoid test_ignored() { 206*67e74705SXin Li makeA(); 207*67e74705SXin Li} 208*67e74705SXin Li// CHECK-LABEL: define void @test_ignored() 209*67e74705SXin Li// CHECK: [[T0:%.*]] = call [[A]]* @makeA() 210*67e74705SXin Li// CHECK-MARKED-NEXT: call void asm sideeffect 211*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 212*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) 213*67e74705SXin Li// CHECK-NEXT: bitcast i8* [[T2]] to [[A]]* 214*67e74705SXin Li// CHECK-NEXT: ret void 215*67e74705SXin Li 216*67e74705SXin Livoid test_cast_to_void() { 217*67e74705SXin Li (void) makeA(); 218*67e74705SXin Li} 219*67e74705SXin Li// CHECK-LABEL: define void @test_cast_to_void() 220*67e74705SXin Li// CHECK: [[T0:%.*]] = call [[A]]* @makeA() 221*67e74705SXin Li// CHECK-MARKED-NEXT: call void asm sideeffect 222*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* 223*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* [[T1]]) 224*67e74705SXin Li// CHECK-NEXT: bitcast i8* [[T2]] to [[A]]* 225*67e74705SXin Li// CHECK-NEXT: ret void 226*67e74705SXin Li 227*67e74705SXin Li 228*67e74705SXin Li 229*67e74705SXin Li// This is always at the end of the module. 230*67e74705SXin Li 231*67e74705SXin Li// CHECK-OPTIMIZED: !clang.arc.retainAutoreleasedReturnValueMarker = !{!0} 232