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