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