1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-passes -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CHECK-COMMON %s 2// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-UNOPT -check-prefix=CHECK-COMMON %s 3 4// CHECK-COMMON: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i64, i64 } 5// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP44:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, i64 } { i64 0, i64 40, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_8_32s to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_8_32s to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i64 256 }, align 8 6// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP9:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, i64 } { i64 0, i64 40, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_8_32r to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_8_32r to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i64 16 }, align 8 7// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP46:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, i8* } { i64 0, i64 48, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_8_32s to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_8_32s to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @{{.*}}, i32 0, i32 0) }, align 8 8// CHECK-COMMON: @[[BLOCK_DESCRIPTOR_TMP48:.*]] = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, i64 } { i64 0, i64 40, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_8_32b to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_8_32s to i8*), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @{{.*}}, i32 0, i32 0), i64 256 }, align 8 9 10// This shouldn't crash. 11void test0(id (^maker)(void)) { 12 maker(); 13} 14 15int (^test1(int x))(void) { 16 // CHECK-LABEL: define{{.*}} i32 ()* @test1( 17 // CHECK: [[X:%.*]] = alloca i32, 18 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], 19 // CHECK-NEXT: store i32 {{%.*}}, i32* [[X]] 20 // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to i32 ()* 21 // CHECK-NEXT: [[T1:%.*]] = bitcast i32 ()* [[T0]] to i8* 22 // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) [[NUW:#[0-9]+]] 23 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i32 ()* 24 // CHECK-NEXT: [[T4:%.*]] = bitcast i32 ()* [[T3]] to i8* 25 // CHECK-NEXT: [[T5:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T4]]) [[NUW]] 26 // CHECK-NEXT: [[T6:%.*]] = bitcast i8* [[T5]] to i32 ()* 27 // CHECK-NEXT: ret i32 ()* [[T6]] 28 return ^{ return x; }; 29} 30 31void test2(id x) { 32// CHECK-LABEL: define{{.*}} void @test2( 33// CHECK: [[X:%.*]] = alloca i8*, 34// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], 35// CHECK-NEXT: [[PARM:%.*]] = call i8* @llvm.objc.retain(i8* {{%.*}}) 36// CHECK-NEXT: store i8* [[PARM]], i8** [[X]] 37// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 38// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]], 39// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) 40// CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]], 41// CHECK-NEXT: bitcast 42// CHECK-NEXT: call void @test2_helper( 43// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]] 44// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release 45// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] 46// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) [[NUW]], !clang.imprecise_release 47// CHECK-NEXT: ret void 48 extern void test2_helper(id (^)(void)); 49 test2_helper(^{ return x; }); 50 51// CHECK: define linkonce_odr hidden void @__copy_helper_block_8_32s(i8* %0, i8* %1) unnamed_addr #{{[0-9]+}} { 52// CHECK: [[T0:%.*]] = load i8*, i8** 53// CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]* 54// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** 55// CHECK-NEXT: [[DST:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]* 56// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[SRC]], i32 0, i32 5 57// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]] 58// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) [[NUW]] 59// CHECK-NEXT: ret void 60 61 62// CHECK: define linkonce_odr hidden void @__destroy_helper_block_8_32s(i8* %0) unnamed_addr #{{[0-9]+}} { 63// CHECK: [[T0:%.*]] = load i8*, i8** 64// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]* 65// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[T1]], i32 0, i32 5 66// CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[T2]] 67// CHECK-NEXT: call void @llvm.objc.release(i8* [[T3]]) 68// CHECK-NEXT: ret void 69} 70 71void test3(void (^sink)(id*)) { 72 __strong id strong; 73 sink(&strong); 74 75 // CHECK-LABEL: define{{.*}} void @test3( 76 // CHECK: [[SINK:%.*]] = alloca void (i8**)* 77 // CHECK-NEXT: [[STRONG:%.*]] = alloca i8* 78 // CHECK-NEXT: [[TEMP:%.*]] = alloca i8* 79 // CHECK-NEXT: bitcast void (i8**)* {{%.*}} to i8* 80 // CHECK-NEXT: call i8* @llvm.objc.retain( 81 // CHECK-NEXT: bitcast i8* 82 // CHECK-NEXT: store void (i8**)* {{%.*}}, void (i8**)** [[SINK]] 83 // CHECK-NEXT: [[STRONGPTR1:%.*]] = bitcast i8** [[STRONG]] to i8* 84 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[STRONGPTR1]]) 85 // CHECK-NEXT: store i8* null, i8** [[STRONG]] 86 87 // CHECK-NEXT: load void (i8**)*, void (i8**)** [[SINK]] 88 // CHECK-NEXT: bitcast 89 // CHECK-NEXT: getelementptr 90 // CHECK-NEXT: [[BLOCK:%.*]] = bitcast 91 // CHECK-NEXT: [[V:%.*]] = load i8*, i8** [[STRONG]] 92 // CHECK-NEXT: store i8* [[V]], i8** [[TEMP]] 93 // CHECK-NEXT: [[F0:%.*]] = load i8*, i8** 94 // CHECK-NEXT: [[F1:%.*]] = bitcast i8* [[F0]] to void (i8*, i8**)* 95 // CHECK-NEXT: call void [[F1]](i8* [[BLOCK]], i8** [[TEMP]]) 96 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[TEMP]] 97 // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) 98 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V]]) [[NUW]] 99 // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[STRONG]] 100 // CHECK-NEXT: store i8* [[T1]], i8** [[STRONG]] 101 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) 102 103 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[STRONG]] 104 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) 105 // CHECK-NEXT: [[STRONGPTR2:%.*]] = bitcast i8** [[STRONG]] to i8* 106 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[STRONGPTR2]]) 107 108 // CHECK-NEXT: load void (i8**)*, void (i8**)** [[SINK]] 109 // CHECK-NEXT: bitcast 110 // CHECK-NEXT: call void @llvm.objc.release 111 // CHECK-NEXT: ret void 112 113} 114 115void test4(void) { 116 id test4_source(void); 117 void test4_helper(void (^)(void)); 118 __block id var = test4_source(); 119 test4_helper(^{ var = 0; }); 120 121 // CHECK-LABEL: define{{.*}} void @test4() 122 // CHECK: [[VAR:%.*]] = alloca [[BYREF_T:%.*]], 123 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], 124 // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 2 125 // 0x02000000 - has copy/dispose helpers strong 126 // CHECK-NEXT: store i32 838860800, i32* [[T0]] 127 // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6 128 // CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source() 129 // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) 130 // CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]] 131 // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6 132 // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT 133 // CHECK: store i32 -1040187392, 134 // CHECK: [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8* 135 // CHECK-NEXT: store i8* [[T0]], i8** 136 // CHECK: call void @test4_helper( 137 // CHECK: [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8* 138 // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8) 139 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]] 140 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) 141 // CHECK: ret void 142 143 // CHECK-LABEL: define internal void @__Block_byref_object_copy_(i8* %0, i8* %1) #{{[0-9]+}} { 144 // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6 145 // CHECK-NEXT: load i8*, i8** 146 // CHECK-NEXT: bitcast i8* {{%.*}} to [[BYREF_T]]* 147 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6 148 // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[T1]] 149 // CHECK-NEXT: store i8* [[T2]], i8** [[T0]] 150 // CHECK-NEXT: store i8* null, i8** [[T1]] 151 152 // CHECK-LABEL: define internal void @__Block_byref_object_dispose_(i8* %0) #{{[0-9]+}} { 153 // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6 154 // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]] 155 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) 156 157 // CHECK-LABEL: define internal void @__test4_block_invoke 158 // CHECK: [[SLOT:%.*]] = getelementptr inbounds {{.*}}, i32 0, i32 6 159 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]], align 8 160 // CHECK-NEXT: store i8* null, i8** [[SLOT]], 161 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) 162 // CHECK-NEXT: ret void 163 164 // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32r(i8* %0, i8* %1) unnamed_addr #{{[0-9]+}} { 165 // CHECK: call void @_Block_object_assign(i8* {{%.*}}, i8* {{%.*}}, i32 8) 166 167 // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_8_32r(i8* %0) unnamed_addr #{{[0-9]+}} { 168 // CHECK: call void @_Block_object_dispose(i8* {{%.*}}, i32 8) 169} 170 171void test5(void) { 172 extern id test5_source(void); 173 void test5_helper(void (^)(void)); 174 __unsafe_unretained id var = test5_source(); 175 test5_helper(^{ (void) var; }); 176 177 // CHECK-LABEL: define{{.*}} void @test5() 178 // CHECK: [[VAR:%.*]] = alloca i8* 179 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], 180 // CHECK-NEXT: [[VARPTR1:%.*]] = bitcast i8** [[VAR]] to i8* 181 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[VARPTR1]]) 182 // CHECK: [[T0:%.*]] = call i8* @test5_source() 183 // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) 184 // CHECK-NEXT: store i8* [[T1]], i8** [[VAR]], 185 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) 186 // 0x40800000 - has signature but no copy/dispose, as well as BLOCK_HAS_EXTENDED_LAYOUT 187 // CHECK: store i32 -1073741824, i32* 188 // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 189 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[VAR]] 190 // CHECK-NEXT: store i8* [[T0]], i8** [[CAPTURE]] 191 // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to 192 // CHECK: call void @test5_helper 193 // CHECK-NEXT: [[VARPTR2:%.*]] = bitcast i8** [[VAR]] to i8* 194 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[VARPTR2]]) 195 // CHECK-NEXT: ret void 196} 197 198void test6(void) { 199 id test6_source(void); 200 void test6_helper(void (^)(void)); 201 __block __weak id var = test6_source(); 202 test6_helper(^{ var = 0; }); 203 204 // CHECK-LABEL: define{{.*}} void @test6() 205 // CHECK: [[VAR:%.*]] = alloca [[BYREF_T:%.*]], 206 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], 207 // CHECK-NEXT: [[VARPTR1:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8* 208 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 48, i8* [[VARPTR1]]) 209 // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 2 210 // 0x02000000 - has copy/dispose helpers weak 211 // CHECK-NEXT: store i32 1107296256, i32* [[T0]] 212 // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6 213 // CHECK-NEXT: [[T0:%.*]] = call i8* @test6_source() 214 // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) 215 // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[SLOT]], i8* [[T1]]) 216 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) 217 // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6 218 // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT 219 // CHECK: store i32 -1040187392, 220 // CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %{{.*}}, i32 0, i32 4 221// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i64 }* @[[BLOCK_DESCRIPTOR_TMP9]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8 222 // CHECK: [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8* 223 // CHECK-NEXT: store i8* [[T0]], i8** 224 // CHECK: call void @test6_helper( 225 // CHECK: [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8* 226 // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8) 227 // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[SLOT]]) 228 // CHECK-NEXT: [[VARPTR2:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8* 229 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 48, i8* [[VARPTR2]]) 230 // CHECK-NEXT: ret void 231 232 // CHECK-LABEL: define internal void @__Block_byref_object_copy_.{{[0-9]+}}(i8* %0, i8* %1) #{{[0-9]+}} { 233 // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6 234 // CHECK-NEXT: load i8*, i8** 235 // CHECK-NEXT: bitcast i8* {{%.*}} to [[BYREF_T]]* 236 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6 237 // CHECK-NEXT: call void @llvm.objc.moveWeak(i8** [[T0]], i8** [[T1]]) 238 239 // CHECK-LABEL: define internal void @__Block_byref_object_dispose_.{{[0-9]+}}(i8* %0) #{{[0-9]+}} { 240 // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6 241 // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[T0]]) 242 243 // CHECK-LABEL: define internal void @__test6_block_invoke 244 // CHECK: [[SLOT:%.*]] = getelementptr inbounds {{.*}}, i32 0, i32 6 245 // CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[SLOT]], i8* null) 246 // CHECK-NEXT: ret void 247} 248 249void test7(void) { 250 id test7_source(void); 251 void test7_helper(void (^)(void)); 252 void test7_consume(id); 253 __weak id var = test7_source(); 254 test7_helper(^{ test7_consume(var); }); 255 256 // CHECK-LABEL: define{{.*}} void @test7() 257 // CHECK: [[VAR:%.*]] = alloca i8*, 258 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], 259 // CHECK: [[T0:%.*]] = call i8* @test7_source() 260 // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) 261 // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[VAR]], i8* [[T1]]) 262 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) 263 // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT 264 // CHECK: store i32 -1040187392, 265 // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 266 // CHECK-NEXT: call void @llvm.objc.copyWeak(i8** [[SLOT]], i8** [[VAR]]) 267 // CHECK: call void @test7_helper( 268 // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** {{%.*}}) 269 // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[VAR]]) 270 // CHECK: ret void 271 272 // CHECK-LABEL: define internal void @__test7_block_invoke 273 // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* {{%.*}}, i32 0, i32 5 274 // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[SLOT]]) 275 // CHECK-NEXT: call void @test7_consume(i8* [[T0]]) 276 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) 277 // CHECK: ret void 278 279 // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32w(i8* %0, i8* %1) unnamed_addr #{{[0-9]+}} { 280 // CHECK: getelementptr 281 // CHECK-NEXT: getelementptr 282 // CHECK-NEXT: call void @llvm.objc.copyWeak( 283 284 // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_8_32w(i8* %0) unnamed_addr #{{[0-9]+}} { 285 // CHECK: getelementptr 286 // CHECK-NEXT: call void @llvm.objc.destroyWeak( 287} 288 289@interface Test8 @end 290@implementation Test8 291- (void) test { 292// CHECK: define internal void @"\01-[Test8 test]" 293// CHECK: [[SELF:%.*]] = alloca [[TEST8:%.*]]*, 294// CHECK-NEXT: alloca i8* 295// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], 296// CHECK: store 297// CHECK-NEXT: store 298// CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 299// CHECK-NEXT: [[T1:%.*]] = load [[TEST8]]*, [[TEST8]]** [[SELF]], 300// CHECK-NEXT: store %0* [[T1]], %0** [[T0]] 301// CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to 302// CHECK: call void @test8_helper( 303// CHECK-NEXT: [[T2:%.*]] = load [[TEST8]]*, [[TEST8]]** [[T0]] 304// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use([[TEST8]]* [[T2]]) 305// CHECK: ret void 306 307 extern void test8_helper(void (^)(void)); 308 test8_helper(^{ (void) self; }); 309} 310@end 311 312id test9(void) { 313 typedef id __attribute__((ns_returns_retained)) blocktype(void); 314 extern void test9_consume_block(blocktype^); 315 return ^blocktype { 316 extern id test9_produce(void); 317 return test9_produce(); 318 }(); 319 320// CHECK-LABEL: define{{.*}} i8* @test9( 321// CHECK: load i8*, i8** getelementptr 322// CHECK-NEXT: bitcast i8* 323// CHECK-NEXT: call i8* 324// CHECK-NEXT: tail call i8* @llvm.objc.autoreleaseReturnValue 325// CHECK-NEXT: ret i8* 326 327// CHECK: call i8* @test9_produce() 328// CHECK-NEXT: call i8* @llvm.objc.retain 329// CHECK-NEXT: ret i8* 330} 331 332// rdar://problem/9814099 333// Test that we correctly initialize __block variables 334// when the initialization captures the variable. 335void test10a(void) { 336 __block void (^block)(void) = ^{ block(); }; 337 // CHECK-LABEL: define{{.*}} void @test10a() 338 // CHECK: [[BYREF:%.*]] = alloca [[BYREF_T:%.*]], 339 // CHECK: [[BLOCK1:%.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8 340 341 // Zero-initialization before running the initializer. 342 // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 6 343 // CHECK-NEXT: store void ()* null, void ()** [[T0]], align 8 344 345 // Run the initializer as an assignment. 346 // CHECK: [[T2:%.*]] = bitcast <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* [[BLOCK1]] to void ()* 347 // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 1 348 // CHECK-NEXT: [[T4:%.*]] = load [[BYREF_T]]*, [[BYREF_T]]** [[T3]] 349 // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[T4]], i32 0, i32 6 350 // CHECK-NEXT: [[T6:%.*]] = load void ()*, void ()** [[T5]], align 8 351 // CHECK-NEXT: store void ()* [[T2]], void ()** [[T5]], align 8 352 // CHECK-NEXT: [[T7:%.*]] = bitcast void ()* [[T6]] to i8* 353 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T7]]) 354 355 // Destroy at end of function. 356 // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 6 357 // CHECK-NEXT: [[T0:%.*]] = bitcast [[BYREF_T]]* [[BYREF]] to i8* 358 // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8) 359 // CHECK-NEXT: [[T1:%.*]] = load void ()*, void ()** [[SLOT]] 360 // CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8* 361 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) 362 // CHECK: ret void 363} 364 365// <rdar://problem/10402698>: do this copy and dispose with 366// objc_retainBlock/release instead of _Block_object_assign/destroy. 367// We can also use _Block_object_assign/destroy with 368// BLOCK_FIELD_IS_BLOCK as long as we don't pass BLOCK_BYREF_CALLER. 369 370// CHECK-LABEL: define internal void @__Block_byref_object_copy_.{{[0-9]+}}(i8* %0, i8* %1) #{{[0-9]+}} { 371// CHECK: [[D0:%.*]] = load i8*, i8** {{%.*}} 372// CHECK-NEXT: [[D1:%.*]] = bitcast i8* [[D0]] to [[BYREF_T]]* 373// CHECK-NEXT: [[D2:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[D1]], i32 0, i32 6 374// CHECK-NEXT: [[S0:%.*]] = load i8*, i8** {{%.*}} 375// CHECK-NEXT: [[S1:%.*]] = bitcast i8* [[S0]] to [[BYREF_T]]* 376// CHECK-NEXT: [[S2:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[S1]], i32 0, i32 6 377// CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[S2]], align 8 378// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* 379// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) 380// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()* 381// CHECK-NEXT: store void ()* [[T3]], void ()** [[D2]], align 8 382// CHECK: ret void 383 384// CHECK-LABEL: define internal void @__Block_byref_object_dispose_.{{[0-9]+}}(i8* %0) #{{[0-9]+}} { 385// CHECK: [[T0:%.*]] = load i8*, i8** {{%.*}} 386// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[BYREF_T]]* 387// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[T1]], i32 0, i32 6 388// CHECK-NEXT: [[T3:%.*]] = load void ()*, void ()** [[T2]] 389// CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8* 390// CHECK-NEXT: call void @llvm.objc.release(i8* [[T4]]) 391// CHECK-NEXT: ret void 392 393// Test that we correctly assign to __block variables when the 394// assignment captures the variable. 395void test10b(void) { 396 __block void (^block)(void); 397 block = ^{ block(); }; 398 399 // CHECK-LABEL: define{{.*}} void @test10b() 400 // CHECK: [[BYREF:%.*]] = alloca [[BYREF_T:%.*]], 401 // CHECK: [[BLOCK3:%.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8 402 403 // Zero-initialize. 404 // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 6 405 // CHECK-NEXT: store void ()* null, void ()** [[T0]], align 8 406 407 // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 6 408 409 // The assignment. 410 // CHECK: [[T2:%.*]] = bitcast <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* [[BLOCK3]] to void ()* 411 // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 1 412 // CHECK-NEXT: [[T4:%.*]] = load [[BYREF_T]]*, [[BYREF_T]]** [[T3]] 413 // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[T4]], i32 0, i32 6 414 // CHECK-NEXT: [[T6:%.*]] = load void ()*, void ()** [[T5]], align 8 415 // CHECK-NEXT: store void ()* [[T2]], void ()** [[T5]], align 8 416 // CHECK-NEXT: [[T7:%.*]] = bitcast void ()* [[T6]] to i8* 417 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T7]]) 418 419 // Destroy at end of function. 420 // CHECK-NEXT: [[T0:%.*]] = bitcast [[BYREF_T]]* [[BYREF]] to i8* 421 // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8) 422 // CHECK-NEXT: [[T1:%.*]] = load void ()*, void ()** [[SLOT]] 423 // CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8* 424 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) 425 // CHECK: ret void 426} 427 428// rdar://problem/10088932 429void test11_helper(id); 430void test11a(void) { 431 int x; 432 test11_helper(^{ (void) x; }); 433 434 // CHECK-LABEL: define{{.*}} void @test11a() 435 // CHECK: [[X:%.*]] = alloca i32, align 4 436 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], align 8 437 // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* 438 // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* 439 // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) 440 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()* 441 // CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8* 442 // CHECK-NEXT: call void @test11_helper(i8* [[T4]]) 443 // CHECK-NEXT: [[T5:%.*]] = bitcast void ()* [[T3]] to i8* 444 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]]) 445 // CHECK: ret void 446} 447void test11b(void) { 448 int x; 449 id b = ^{ (void) x; }; 450 451 // CHECK-LABEL: define{{.*}} void @test11b() 452 // CHECK: [[X:%.*]] = alloca i32, align 4 453 // CHECK-NEXT: [[B:%.*]] = alloca i8*, align 8 454 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], align 8 455 // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* 456 // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* 457 // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) 458 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()* 459 // CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8* 460 // CHECK-NEXT: store i8* [[T4]], i8** [[B]], align 8 461 // CHECK-NEXT: [[T5:%.*]] = load i8*, i8** [[B]] 462 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T5]]) 463 // CHECK: ret void 464} 465 466// rdar://problem/9979150 467@interface Test12 468@property (strong) void(^ablock)(void); 469@property (nonatomic, strong) void(^nblock)(void); 470@end 471@implementation Test12 472@synthesize ablock, nblock; 473// CHECK: define internal void ()* @"\01-[Test12 ablock]"( 474// CHECK: call i8* @objc_getProperty(i8* {{%.*}}, i8* {{%.*}}, i64 {{%.*}}, i1 zeroext true) 475 476// CHECK: define internal void @"\01-[Test12 setAblock:]"( 477// CHECK: call void @objc_setProperty(i8* {{%.*}}, i8* {{%.*}}, i64 {{%.*}}, i8* {{%.*}}, i1 zeroext true, i1 zeroext true) 478 479// CHECK: define internal void ()* @"\01-[Test12 nblock]"( 480// CHECK: call i8* @objc_getProperty(i8* {{%.*}}, i8* {{%.*}}, i64 {{%.*}}, i1 zeroext false) 481 482// CHECK: define internal void @"\01-[Test12 setNblock:]"( 483// CHECK: call void @objc_setProperty(i8* {{%.*}}, i8* {{%.*}}, i64 {{%.*}}, i8* {{%.*}}, i1 zeroext false, i1 zeroext true) 484@end 485 486// rdar://problem/10131784 487void test13(id x) { 488 extern void test13_helper(id); 489 extern void test13_use(void(^)(void)); 490 491 void (^b)(void) = (x ? ^{test13_helper(x);} : 0); 492 test13_use(b); 493 494 // CHECK-LABEL: define{{.*}} void @test13( 495 // CHECK: [[X:%.*]] = alloca i8*, align 8 496 // CHECK-NEXT: [[B:%.*]] = alloca void ()*, align 8 497 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:.*]], align 8 498 // CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1 499 // CHECK-NEXT: [[COND_CLEANUP_SAVE:%.*]] = alloca i8**, 500 // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* {{%.*}}) 501 // CHECK-NEXT: store i8* [[T0]], i8** [[X]], align 8 502 // CHECK-NEXT: [[BPTR1:%.*]] = bitcast void ()** [[B]] to i8* 503 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[BPTR1]]) 504 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]], align 8 505 // CHECK-NEXT: [[T1:%.*]] = icmp ne i8* [[T0]], null 506 // CHECK-NEXT: store i1 false, i1* [[CLEANUP_ACTIVE]] 507 // CHECK-NEXT: br i1 [[T1]], 508 509 // CHECK-NOT: br 510 // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 511 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]], align 8 512 // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) 513 // CHECK-NEXT: store i8* [[T1]], i8** [[CAPTURE]], align 8 514 // CHECK-NEXT: store i1 true, i1* [[CLEANUP_ACTIVE]] 515 // CHECK-NEXT: store i8** [[CAPTURE]], i8*** [[COND_CLEANUP_SAVE]], align 8 516 // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* 517 // CHECK-NEXT: br label 518 // CHECK: br label 519 // CHECK: [[T0:%.*]] = phi void ()* 520 // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* 521 // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) 522 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()* 523 // CHECK-NEXT: store void ()* [[T3]], void ()** [[B]], align 8 524 // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]], align 8 525 // CHECK-NEXT: call void @test13_use(void ()* [[T0]]) 526 // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]] 527 // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* 528 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) 529 530 // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[CLEANUP_ACTIVE]] 531 // CHECK-NEXT: br i1 [[T0]] 532 // CHECK: [[V12:%.*]] = load i8**, i8*** [[COND_CLEANUP_SAVE]], align 8 533 // CHECK: [[T0:%.*]] = load i8*, i8** [[V12]] 534 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) 535 // CHECK-NEXT: br label 536 537 // CHECK: [[BPTR2:%.*]] = bitcast void ()** [[B]] to i8* 538 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[BPTR2]]) 539 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] 540 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) 541 // CHECK-NEXT: ret void 542} 543 544// <rdar://problem/10907510> 545void test14() { 546 void (^const x[1])(void) = { ^{} }; 547} 548 549// rdar://11149025 550// Don't make invalid ASTs and crash. 551void test15_helper(void (^block)(void), int x); 552void test15(int a) { 553 test15_helper(^{ (void) a; }, ({ a; })); 554} 555 556// rdar://11016025 557void test16() { 558 void (^BLKVAR)(void) = ^{ BLKVAR(); }; 559 560 // CHECK-LABEL: define{{.*}} void @test16( 561 // CHECK: [[BLKVAR:%.*]] = alloca void ()*, align 8 562 // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], 563 // CHECK-NEXT: [[BLKVARPTR1:%.*]] = bitcast void ()** [[BLKVAR]] to i8* 564 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[BLKVARPTR1]]) 565 // CHECK-NEXT: store void ()* null, void ()** [[BLKVAR]], align 8 566} 567 568// rdar://12151005 569// 570// This is an intentional exception to our conservative jump-scope 571// checking for full-expressions containing block literals with 572// non-trivial cleanups: if the block literal appears in the operand 573// of a return statement, there's no need to extend its lifetime. 574id (^test17(id self, int which))(void) { 575 switch (which) { 576 case 1: return ^{ return self; }; 577 case 0: return ^{ return self; }; 578 } 579 return (void*) 0; 580} 581// CHECK-LABEL: define{{.*}} i8* ()* @test17( 582// CHECK: [[RET:%.*]] = alloca i8* ()*, align 583// CHECK-NEXT: [[SELF:%.*]] = alloca i8*, 584// CHECK: [[B0:%.*]] = alloca [[BLOCK:<.*>]], align 585// CHECK: [[B1:%.*]] = alloca [[BLOCK]], align 586// CHECK: [[T0:%.*]] = call i8* @llvm.objc.retain(i8* 587// CHECK-NEXT: store i8* [[T0]], i8** [[SELF]], align 588// CHECK-NOT: objc_retain 589// CHECK-NOT: objc_release 590// CHECK: [[CAPTURED:%.*]] = getelementptr inbounds [[BLOCK]], [[BLOCK]]* [[B0]], i32 0, i32 5 591// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[SELF]], align 592// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) 593// CHECK-NEXT: store i8* [[T2]], i8** [[CAPTURED]], 594// CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK]]* [[B0]] to i8* ()* 595// CHECK-NEXT: [[T1:%.*]] = bitcast i8* ()* [[T0]] to i8* 596// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) 597// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8* ()* 598// CHECK-NEXT: store i8* ()* [[T3]], i8* ()** [[RET]] 599// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[CAPTURED]] 600// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) 601// CHECK-NEXT: store i32 602// CHECK-NEXT: br label 603// CHECK-NOT: objc_retain 604// CHECK-NOT: objc_release 605// CHECK: [[CAPTURED:%.*]] = getelementptr inbounds [[BLOCK]], [[BLOCK]]* [[B1]], i32 0, i32 5 606// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[SELF]], align 607// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) 608// CHECK-NEXT: store i8* [[T2]], i8** [[CAPTURED]], 609// CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK]]* [[B1]] to i8* ()* 610// CHECK-NEXT: [[T1:%.*]] = bitcast i8* ()* [[T0]] to i8* 611// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T1]]) 612// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8* ()* 613// CHECK-NEXT: store i8* ()* [[T3]], i8* ()** [[RET]] 614// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[CAPTURED]] 615// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) 616// CHECK-NEXT: store i32 617// CHECK-NEXT: br label 618 619void test18(id x) { 620// CHECK-UNOPT-LABEL: define{{.*}} void @test18( 621// CHECK-UNOPT: [[X:%.*]] = alloca i8*, 622// CHECK-UNOPT-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], 623// CHECK-UNOPT-NEXT: store i8* null, i8** [[X]] 624// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], 625// CHECK-UNOPT: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 4 626// CHECK-UNOPT: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i64 }* @[[BLOCK_DESCRIPTOR_TMP44]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8 627// CHECK-UNOPT: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 628// CHECK-UNOPT-NEXT: [[T0:%.*]] = load i8*, i8** [[X]], 629// CHECK-UNOPT-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) 630// CHECK-UNOPT-NEXT: store i8* [[T1]], i8** [[SLOT]], 631// CHECK-UNOPT-NEXT: bitcast 632// CHECK-UNOPT-NEXT: call void @test18_helper( 633// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[SLOT]], i8* null) [[NUW:#[0-9]+]] 634// CHECK-UNOPT-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) [[NUW]] 635// CHECK-UNOPT-NEXT: ret void 636 extern void test18_helper(id (^)(void)); 637 test18_helper(^{ return x; }); 638} 639 640// Ensure that we don't emit helper code in copy/dispose routines for variables 641// that are const-captured. 642void testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers(id x, id y) { 643 id __unsafe_unretained unsafeObject = x; 644 (^ { testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers(x, unsafeObject); })(); 645} 646 647// CHECK-LABEL: define{{.*}} void @testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers 648// %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8*, i8* }>* %{{.*}}, i32 0, i32 4 649// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @[[BLOCK_DESCRIPTOR_TMP46]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8 650 651// CHECK-LABEL: define internal void @__testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers_block_invoke 652// CHECK-UNOPT-LABEL: define internal void @__testUnsafeUnretainedLifetimeInCopyAndDestroyHelpers_block_invoke 653 654// rdar://13588325 655void test19_sink(void (^)(int)); 656void test19(void (^b)(void)) { 657// CHECK-LABEL: define{{.*}} void @test19( 658// Prologue. 659// CHECK: [[B:%.*]] = alloca void ()*, 660// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], 661// CHECK-NEXT: [[T0:%.*]] = bitcast void ()* {{%.*}} to i8* 662// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) 663// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to void ()* 664// CHECK-NEXT: store void ()* [[T2]], void ()** [[B]] 665 666// Block setup. We skip most of this. Note the bare retain. 667// CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 4 668// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i64 }* @[[BLOCK_DESCRIPTOR_TMP48]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8 669// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 670// CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]], 671// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* 672// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retain(i8* [[T1]]) 673// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()* 674// CHECK-NEXT: store void ()* [[T3]], void ()** [[SLOT]], 675// Call. 676// CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void (i32)* 677// CHECK-NEXT: call void @test19_sink(void (i32)* [[T0]]) 678 679 test19_sink(^(int x) { b(); }); 680 681// Block teardown. 682// CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[SLOT]] 683// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* 684// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) 685 686// Local cleanup. 687// CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]] 688// CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* 689// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) 690 691// CHECK-NEXT: ret void 692} 693 694// CHECK-LABEL: define{{.*}} void @test20( 695// CHECK: [[XADDR:%.*]] = alloca i8* 696// CHECK-NEXT: [[BLOCK:%.*]] = alloca <[[BLOCKTY:.*]]> 697// CHECK-NEXT: [[RETAINEDX:%.*]] = call i8* @llvm.objc.retain(i8* %{{.*}}) 698// CHECK-NEXT: store i8* [[RETAINEDX]], i8** [[XADDR]] 699// CHECK: [[BLOCKCAPTURED:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, <[[BLOCKTY]]>* [[BLOCK]], i32 0, i32 5 700// CHECK: [[CAPTURED:%.*]] = load i8*, i8** [[XADDR]] 701// CHECK: store i8* [[CAPTURED]], i8** [[BLOCKCAPTURED]] 702// CHECK: [[CAPTURE:%.*]] = load i8*, i8** [[BLOCKCAPTURED]] 703// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[CAPTURE]]) 704// CHECK-NEXT: [[X:%.*]] = load i8*, i8** [[XADDR]] 705// CHECK-NEXT: call void @llvm.objc.release(i8* [[X]]) 706// CHECK-NEXT: ret void 707 708// CHECK-UNOPT-LABEL: define{{.*}} void @test20( 709// CHECK-UNOPT: [[XADDR:%.*]] = alloca i8* 710// CHECK-UNOPT-NEXT: [[BLOCK:%.*]] = alloca <[[BLOCKTY:.*]]> 711// CHECK-UNOPT: [[BLOCKCAPTURED:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, <[[BLOCKTY]]>* [[BLOCK]], i32 0, i32 5 712// CHECK-UNOPT: [[CAPTURED:%.*]] = load i8*, i8** [[XADDR]] 713// CHECK-UNOPT: [[RETAINED:%.*]] = call i8* @llvm.objc.retain(i8* [[CAPTURED]]) 714// CHECK-UNOPT: store i8* [[RETAINED]], i8** [[BLOCKCAPTURED]] 715// CHECK-UNOPT: call void @llvm.objc.storeStrong(i8** [[BLOCKCAPTURED]], i8* null) 716 717void test20_callee(void (^)()); 718void test20(const id x) { 719 test20_callee(^{ (void)x; }); 720} 721 722// CHECK-LABEL: define{{.*}} void @test21( 723// CHECK: %[[V6:.*]] = call i8* @llvm.objc.retainBlock( 724// CHECK: %[[V7:.*]] = bitcast i8* %[[V6]] to void ()* 725// CHECK: call void (i32, ...) @test21_callee(i32 1, void ()* %[[V7]]), 726 727void test21_callee(int n, ...); 728void test21(id x) { 729 test21_callee(1, ^{ (void)x; }); 730} 731 732// The lifetime of 'x', which is captured by the block in the statement 733// expression, should be extended. 734 735// CHECK-COMMON-LABEL: define{{.*}} i8* @test22( 736// CHECK-COMMON: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %{{.*}}*, i8* }>, <{ i8*, i32, i32, i8*, %{{.*}}*, i8* }>* %{{.*}}, i32 0, i32 5 737// CHECK-COMMON: %[[V3:.*]] = call i8* @llvm.objc.retain(i8* %{{.*}}) 738// CHECK-COMMON: store i8* %[[V3]], i8** %[[BLOCK_CAPTURED]], align 8 739// CHECK-COMMON: call void @test22_1() 740// CHECK-UNOPT: call void @llvm.objc.storeStrong(i8** %[[BLOCK_CAPTURED]], i8* null) 741// CHECK: %[[V15:.*]] = load i8*, i8** %[[BLOCK_CAPTURED]], align 8 742// CHECK: call void @llvm.objc.release(i8* %[[V15]]) 743 744id test22(int c, id x) { 745 extern id test22_0(void); 746 extern void test22_1(void); 747 return c ? test22_0() : ({ id (^b)(void) = ^{ return x; }; test22_1(); b(); }); 748} 749 750@interface Test23 751-(void)m:(int)i, ...; 752@end 753 754// CHECK-COMMON-LABEL: define{{.*}} void @test23( 755// CHECK-COMMON: %[[V9:.*]] = call i8* @llvm.objc.retainBlock( 756// CHECK-COMMON: %[[V10:.*]] = bitcast i8* %[[V9]] to void ()* 757// CHECK-COMMON: call void (i8*, i8*, i32, ...) bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, ...)*)(i8* %{{.*}}, i8* %{{.*}}, i32 123, void ()* %[[V10]]) 758 759void test23(id x, Test23 *t) { 760 [t m:123, ^{ (void)x; }]; 761} 762 763// CHECK: attributes [[NUW]] = { nounwind } 764// CHECK-UNOPT: attributes [[NUW]] = { nounwind } 765