1
- // RUN: %clang_cc1 -no-opaque-pointers - triple x86_64-apple-darwin -fblocks -emit-llvm -o - %s | FileCheck -check-prefix CHECK -check-prefix CHECK-NOARC %s
2
- // RUN: %clang_cc1 -no-opaque-pointers - triple x86_64-apple-darwin -fblocks -emit-llvm -fobjc-arc -o - %s | FileCheck -check-prefix CHECK -check-prefix CHECK-ARC %s
1
+ // RUN: %clang_cc1 -triple x86_64-apple-darwin -fblocks -emit-llvm -o - %s | FileCheck -check-prefix CHECK -check-prefix CHECK-NOARC %s
2
+ // RUN: %clang_cc1 -triple x86_64-apple-darwin -fblocks -emit-llvm -fobjc-arc -o - %s | FileCheck -check-prefix CHECK -check-prefix CHECK-ARC %s
3
3
4
4
typedef void (^BlockTy)(void );
5
5
17
17
// Block descriptors of non-escaping blocks don't need pointers to copy/dispose
18
18
// helper functions.
19
19
20
- // CHECK: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i64, i64 }
21
-
22
20
// When the block is non-escaping, copy/dispose helpers aren't generated, so the
23
21
// block layout string must include information about __strong captures.
24
22
25
- // CHECK-NOARC: %[[STRUCT_BLOCK_BYREF_B0:.*]] = type { i8*, %[[STRUCT_BLOCK_BYREF_B0]]* , i32, i32, i8* , %[[STRUCT_S0:.*]] }
26
- // CHECK-ARC: %[[STRUCT_BLOCK_BYREF_B0:.*]] = type { i8*, %[[STRUCT_BLOCK_BYREF_B0]]* , i32, i32, i8*, i8*, i8* , %[[STRUCT_S0:.*]] }
27
- // CHECK: %[[STRUCT_S0]] = type { i8*, i8* }
28
- // CHECK: @[[BLOCK_DESCIPTOR_TMP_2:.*ls32l8"]] = linkonce_odr hidden unnamed_addr constant { i64, i64, i8* , i64 } { i64 0, i64 40, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0) , i64 256 }, align 8
23
+ // CHECK-NOARC: %[[STRUCT_BLOCK_BYREF_B0:.*]] = type { ptr, ptr , i32, i32, ptr , %[[STRUCT_S0:.*]] }
24
+ // CHECK-ARC: %[[STRUCT_BLOCK_BYREF_B0:.*]] = type { ptr, ptr , i32, i32, ptr, ptr, ptr , %[[STRUCT_S0:.*]] }
25
+ // CHECK: %[[STRUCT_S0]] = type { ptr, ptr }
26
+ // CHECK: @[[BLOCK_DESCIPTOR_TMP_2:.*ls32l8"]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr , i64 } { i64 0, i64 40, ptr @{{.*}}, i64 256 }, align 8
29
27
30
28
// CHECK-LABEL: define{{.*}} void @test0(
31
29
// CHECK: call void @noescapeFunc0({{.*}}, {{.*}} nocapture {{.*}})
32
- // CHECK: declare void @noescapeFunc0(i8* noundef, {{.*}} nocapture noundef)
30
+ // CHECK: declare void @noescapeFunc0(ptr noundef, {{.*}} nocapture noundef)
33
31
void test0 (BlockTy b) {
34
32
noescapeFunc0 (0 , b);
35
33
}
@@ -58,7 +56,7 @@ void test3(union U u) {
58
56
// CHECK: define internal void @"\01-[C0 m0:]"({{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
59
57
60
58
// CHECK-LABEL: define{{.*}} void @test4(
61
- // CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32*)*)(i8* {{.*}}, i8* {{.*}}, i32* nocapture {{.*}})
59
+ // CHECK: call void @objc_msgSend(ptr {{.*}}, ptr {{.*}}, ptr nocapture {{.*}})
62
60
63
61
@interface C0
64
62
-(void ) m0 : (int *)__attribute__ ((noescape)) p0 ;
@@ -74,9 +72,9 @@ void test4(C0 *c0, int *p) {
74
72
}
75
73
76
74
// CHECK-LABEL: define{{.*}} void @test5(
77
- // CHECK: call void {{.*}}(i8* noundef bitcast ({ i8**, i32, i32, i8*, {{.*}} }* @{{.*}} to i8*), i32* nocapture {{.*}})
78
- // CHECK: call void {{.*}}(i8* {{.*}}, i32* nocapture {{.*}})
79
- // CHECK: define internal void @{{.*}}(i8* {{.*}}, i32* nocapture {{.*}})
75
+ // CHECK: call void {{.*}}(ptr noundef @{{.*}}, ptr nocapture {{.*}})
76
+ // CHECK: call void {{.*}}(ptr {{.*}}, ptr nocapture {{.*}})
77
+ // CHECK: define internal void @{{.*}}(ptr {{.*}}, ptr nocapture {{.*}})
80
78
81
79
typedef void (^BlockTy2)(__attribute__((noescape)) int *);
82
80
@@ -88,28 +86,28 @@ void test5(BlockTy2 b, int *p) {
88
86
// If the block is non-escaping, set the BLOCK_IS_NOESCAPE and BLOCK_IS_GLOBAL
89
87
// bits of field 'flags' and set the 'isa' field to 'NSConcreteGlobalBlock'.
90
88
91
- // CHECK: define{{.*}} void @test6(i8* noundef %{{.*}}, i8* noundef %[[B:.*]])
92
- // CHECK: %{{.*}} = alloca i8* , align 8
93
- // CHECK: %[[B_ADDR:.*]] = alloca i8* , align 8
94
- // CHECK: %[[BLOCK:.*]] = alloca <{ i8* , i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
95
- // CHECK-NOARC: store i8* %[[B]], i8** %[[B_ADDR]], align 8
96
- // CHECK-ARC: store i8* null, i8** %[[B_ADDR]], align 8
97
- // CHECK-ARC: call void @llvm.objc.storeStrong(i8** %[[B_ADDR]], i8* %[[B]])
98
- // CHECK: %[[BLOCK_ISA:.*]] = getelementptr inbounds <{ i8* , i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]], i32 0, i32 0
99
- // CHECK: store i8* bitcast (i8** @_NSConcreteGlobalBlock to i8*), i8** %[[BLOCK_ISA]], align 8
100
- // CHECK: %[[BLOCK_FLAGS:.*]] = getelementptr inbounds <{ i8* , i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]], i32 0, i32 1
101
- // CHECK: store i32 -796917760, i32* %[[BLOCK_FLAGS]], align 8
102
- // CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ i8* , i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]], i32 0, i32 4
103
- // CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i64 }* @[[BLOCK_DESCIPTOR_TMP_2]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %[[BLOCK_DESCRIPTOR]], align 8
104
- // CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8* , i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]], i32 0, i32 5
105
- // CHECK-NOARC: %[[V1:.*]] = load i8*, i8** %[[B_ADDR]], align 8
106
- // CHECK-NOARC: store i8* %[[V1]], i8** %[[BLOCK_CAPTURED]], align 8
107
- // CHECK-ARC: %[[V2:.*]] = load i8*, i8** %[[B_ADDR]], align 8
108
- // CHECK-ARC: %[[V3:.*]] = call i8* @llvm.objc.retain(i8* %[[V2]])
109
- // CHECK-ARC: store i8* %[[V3]], i8** %[[BLOCK_CAPTURED]], align 8
89
+ // CHECK: define{{.*}} void @test6(ptr noundef %{{.*}}, ptr noundef %[[B:.*]])
90
+ // CHECK: %{{.*}} = alloca ptr , align 8
91
+ // CHECK: %[[B_ADDR:.*]] = alloca ptr , align 8
92
+ // CHECK: %[[BLOCK:.*]] = alloca <{ ptr , i32, i32, ptr, ptr, ptr }>, align 8
93
+ // CHECK-NOARC: store ptr %[[B]], ptr %[[B_ADDR]], align 8
94
+ // CHECK-ARC: store ptr null, ptr %[[B_ADDR]], align 8
95
+ // CHECK-ARC: call void @llvm.objc.storeStrong(ptr %[[B_ADDR]], ptr %[[B]])
96
+ // CHECK: %[[BLOCK_ISA:.*]] = getelementptr inbounds <{ ptr , i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK]], i32 0, i32 0
97
+ // CHECK: store ptr @_NSConcreteGlobalBlock, ptr %[[BLOCK_ISA]], align 8
98
+ // CHECK: %[[BLOCK_FLAGS:.*]] = getelementptr inbounds <{ ptr , i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK]], i32 0, i32 1
99
+ // CHECK: store i32 -796917760, ptr %[[BLOCK_FLAGS]], align 8
100
+ // CHECK: %[[BLOCK_DESCRIPTOR:.*]] = getelementptr inbounds <{ ptr , i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK]], i32 0, i32 4
101
+ // CHECK: store ptr @[[BLOCK_DESCIPTOR_TMP_2]], ptr %[[BLOCK_DESCRIPTOR]], align 8
102
+ // CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ ptr , i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK]], i32 0, i32 5
103
+ // CHECK-NOARC: %[[V1:.*]] = load ptr, ptr %[[B_ADDR]], align 8
104
+ // CHECK-NOARC: store ptr %[[V1]], ptr %[[BLOCK_CAPTURED]], align 8
105
+ // CHECK-ARC: %[[V2:.*]] = load ptr, ptr %[[B_ADDR]], align 8
106
+ // CHECK-ARC: %[[V3:.*]] = call ptr @llvm.objc.retain(ptr %[[V2]])
107
+ // CHECK-ARC: store ptr %[[V3]], ptr %[[BLOCK_CAPTURED]], align 8
110
108
// CHECK: call void @noescapeFunc0(
111
- // CHECK-ARC: call void @llvm.objc.storeStrong(i8** %[[BLOCK_CAPTURED]], i8* null)
112
- // CHECK-ARC: call void @llvm.objc.storeStrong(i8** %[[B_ADDR]], i8* null)
109
+ // CHECK-ARC: call void @llvm.objc.storeStrong(ptr %[[BLOCK_CAPTURED]], ptr null)
110
+ // CHECK-ARC: call void @llvm.objc.storeStrong(ptr %[[B_ADDR]], ptr null)
113
111
114
112
// Non-escaping blocks don't need copy/dispose helper functions.
115
113
@@ -126,11 +124,11 @@ void test6(id a, id b) {
126
124
// __block variables that are not captured by escaping blocks.
127
125
128
126
// CHECK: define{{.*}} void @test7(
129
- // CHECK: alloca i8* , align 8
130
- // CHECK: %[[B0:.*]] = alloca i8* , align 8
131
- // CHECK: %[[BLOCK:.*]] = alloca <{ i8* , i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8** }>, align 8
132
- // CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8* , i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8** }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8** }>* %[[BLOCK]], i32 0, i32 5
133
- // CHECK: store i8** %[[B0]], i8*** %[[BLOCK_CAPTURED]], align 8
127
+ // CHECK: alloca ptr , align 8
128
+ // CHECK: %[[B0:.*]] = alloca ptr , align 8
129
+ // CHECK: %[[BLOCK:.*]] = alloca <{ ptr , i32, i32, ptr, ptr, ptr }>, align 8
130
+ // CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ ptr , i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK]], i32 0, i32 5
131
+ // CHECK: store ptr %[[B0]], ptr %[[BLOCK_CAPTURED]], align 8
134
132
135
133
// CHECK-ARC-NOT: define internal void @__Block_byref_object_copy_
136
134
// CHECK-ARC-NOT: define internal void @__Block_byref_object_dispose_
@@ -144,13 +142,12 @@ void test7(void) {
144
142
// __block variables captured by escaping blocks need byref helper functions.
145
143
146
144
// CHECK: define{{.*}} void @test8(
147
- // CHECK: %[[A:.*]] = alloca i8* , align 8
145
+ // CHECK: %[[A:.*]] = alloca ptr , align 8
148
146
// CHECK: %[[B0:.*]] = alloca %[[STRUCT_BLOCK_BYREF_B0]], align 8
149
- // CHECK: alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
150
- // CHECK: %[[BLOCK1:.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
151
- // CHECK: %[[BLOCK_CAPTURED7:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK1]], i32 0, i32 5
152
- // CHECK: %[[V3:.*]] = bitcast %[[STRUCT_BLOCK_BYREF_B0]]* %[[B0]] to i8*
153
- // CHECK: store i8* %[[V3]], i8** %[[BLOCK_CAPTURED7]], align 8
147
+ // CHECK: alloca <{ ptr, i32, i32, ptr, ptr, ptr }>, align 8
148
+ // CHECK: %[[BLOCK1:.*]] = alloca <{ ptr, i32, i32, ptr, ptr, ptr }>, align 8
149
+ // CHECK: %[[BLOCK_CAPTURED7:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %[[BLOCK1]], i32 0, i32 5
150
+ // CHECK: store ptr %[[B0]], ptr %[[BLOCK_CAPTURED7]], align 8
154
151
155
152
// CHECK-ARC: define internal void @__Block_byref_object_copy_
156
153
// CHECK-ARC: define internal void @__Block_byref_object_dispose_
0 commit comments