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