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