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 18 A *makeA(void); 19 20 void 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 43 void 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 64 void 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 91 void 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 118 void 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 134 void 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 155 void 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 179 void 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 205 void 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 216 void 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