1 | // RUN: %clang_cc1 %s -cl-std=CL2.0 -include opencl-c.h -triple amdgcn -emit-llvm -o - | FileCheck %s |
2 | // RUN: %clang_cc1 %s -O0 -cl-std=CL2.0 -include opencl-c.h -triple amdgcn -emit-llvm -o - | FileCheck --check-prefix=NOOPT %s |
3 | // RUN: %clang_cc1 %s -cl-std=CL2.0 -include opencl-c.h -triple amdgcn---opencl -emit-llvm -o - | FileCheck %s |
4 | |
5 | typedef struct { |
6 | private char *p1; |
7 | local char *p2; |
8 | constant char *p3; |
9 | global char *p4; |
10 | generic char *p5; |
11 | } StructTy1; |
12 | |
13 | typedef struct { |
14 | constant char *p3; |
15 | global char *p4; |
16 | generic char *p5; |
17 | } StructTy2; |
18 | |
19 | // LLVM requests global variable with common linkage to be initialized with zeroinitializer, therefore use -fno-common |
20 | // to suppress common linkage for tentative definition. |
21 | |
22 | // Test 0 as initializer. |
23 | |
24 | // CHECK: @private_p = local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4 |
25 | private char *private_p = 0; |
26 | |
27 | // CHECK: @local_p = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4 |
28 | local char *local_p = 0; |
29 | |
30 | // CHECK: @global_p = local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8 |
31 | global char *global_p = 0; |
32 | |
33 | // CHECK: @constant_p = local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8 |
34 | constant char *constant_p = 0; |
35 | |
36 | // CHECK: @generic_p = local_unnamed_addr addrspace(1) global i8* null, align 8 |
37 | generic char *generic_p = 0; |
38 | |
39 | // Test NULL as initializer. |
40 | |
41 | // CHECK: @private_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4 |
42 | private char *private_p_NULL = NULL; |
43 | |
44 | // CHECK: @local_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4 |
45 | local char *local_p_NULL = NULL; |
46 | |
47 | // CHECK: @global_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8 |
48 | global char *global_p_NULL = NULL; |
49 | |
50 | // CHECK: @constant_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8 |
51 | constant char *constant_p_NULL = NULL; |
52 | |
53 | // CHECK: @generic_p_NULL = local_unnamed_addr addrspace(1) global i8* null, align 8 |
54 | generic char *generic_p_NULL = NULL; |
55 | |
56 | // Test constant folding of null pointer. |
57 | // A null pointer should be folded to a null pointer in the target address space. |
58 | |
59 | // CHECK: @fold_generic = local_unnamed_addr addrspace(1) global i32* null, align 8 |
60 | generic int *fold_generic = (global int*)(generic float*)(private char*)0; |
61 | |
62 | // CHECK: @fold_priv = local_unnamed_addr addrspace(1) global i16 addrspace(5)* null, align 4 |
63 | private short *fold_priv = (private short*)(generic int*)(global void*)0; |
64 | |
65 | // CHECK: @fold_priv_arith = local_unnamed_addr addrspace(1) global i8 addrspace(5)* inttoptr (i32 10 to i8 addrspace(5)*), align 4 |
66 | private char *fold_priv_arith = (private char*)0 + 10; |
67 | |
68 | // CHECK: @fold_int = local_unnamed_addr addrspace(1) global i32 14, align 4 |
69 | int fold_int = (int)(private void*)(generic char*)(global int*)0 + 14; |
70 | |
71 | // CHECK: @fold_int2 = local_unnamed_addr addrspace(1) global i32 13, align 4 |
72 | int fold_int2 = (int) ((private void*)0 + 13); |
73 | |
74 | // CHECK: @fold_int3 = local_unnamed_addr addrspace(1) global i32 0, align 4 |
75 | int fold_int3 = (int) ((private int*)0); |
76 | |
77 | // CHECK: @fold_int4 = local_unnamed_addr addrspace(1) global i32 8, align 4 |
78 | int fold_int4 = (int) &((private int*)0)[2]; |
79 | |
80 | // CHECK: @fold_int5 = local_unnamed_addr addrspace(1) global i32 4, align 4 |
81 | int fold_int5 = (int) &((private StructTy1*)0)->p2; |
82 | |
83 | |
84 | // CHECK: @fold_int_local = local_unnamed_addr addrspace(1) global i32 13, align 4 |
85 | int fold_int_local = (int)(local void*)(generic char*)(global int*)0 + 14; |
86 | |
87 | // CHECK: @fold_int2_local = local_unnamed_addr addrspace(1) global i32 12, align 4 |
88 | int fold_int2_local = (int) ((local void*)0 + 13); |
89 | |
90 | // CHECK: @fold_int3_local = local_unnamed_addr addrspace(1) global i32 -1, align 4 |
91 | int fold_int3_local = (int) ((local int*)0); |
92 | |
93 | // CHECK: @fold_int4_local = local_unnamed_addr addrspace(1) global i32 7, align 4 |
94 | int fold_int4_local = (int) &((local int*)0)[2]; |
95 | |
96 | // CHECK: @fold_int5_local = local_unnamed_addr addrspace(1) global i32 3, align 4 |
97 | int fold_int5_local = (int) &((local StructTy1*)0)->p2; |
98 | |
99 | |
100 | // Test static variable initialization. |
101 | |
102 | // NOOPT: @test_static_var_private.sp1 = internal addrspace(1) global i8 addrspace(5)* null, align 4 |
103 | // NOOPT: @test_static_var_private.sp2 = internal addrspace(1) global i8 addrspace(5)* null, align 4 |
104 | // NOOPT: @test_static_var_private.sp3 = internal addrspace(1) global i8 addrspace(5)* null, align 4 |
105 | // NOOPT: @test_static_var_private.sp4 = internal addrspace(1) global i8 addrspace(5)* null, align 4 |
106 | // NOOPT: @test_static_var_private.sp5 = internal addrspace(1) global i8 addrspace(5)* null, align 4 |
107 | // NOOPT: @test_static_var_private.SS1 = internal addrspace(1) global %struct.StructTy1 { i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }, align 8 |
108 | // NOOPT: @test_static_var_private.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 8 |
109 | |
110 | void test_static_var_private(void) { |
111 | static private char *sp1 = 0; |
112 | static private char *sp2 = NULL; |
113 | static private char *sp3; |
114 | static private char *sp4 = (private char*)((void)0, 0); |
115 | const int x = 0; |
116 | static private char *sp5 = (private char*)x; |
117 | static StructTy1 SS1; |
118 | static StructTy2 SS2; |
119 | } |
120 | |
121 | // NOOPT: @test_static_var_local.sp1 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4 |
122 | // NOOPT: @test_static_var_local.sp2 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4 |
123 | // NOOPT: @test_static_var_local.sp3 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4 |
124 | // NOOPT: @test_static_var_local.sp4 = internal addrspace(1) global i8 addrspace(3)* null, align 4 |
125 | // NOOPT: @test_static_var_local.sp5 = internal addrspace(1) global i8 addrspace(3)* null, align 4 |
126 | // NOOPT: @test_static_var_local.SS1 = internal addrspace(1) global %struct.StructTy1 { i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }, align 8 |
127 | // NOOPT: @test_static_var_local.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 8 |
128 | void test_static_var_local(void) { |
129 | static local char *sp1 = 0; |
130 | static local char *sp2 = NULL; |
131 | static local char *sp3; |
132 | static local char *sp4 = (local char*)((void)0, 0); |
133 | const int x = 0; |
134 | static local char *sp5 = (local char*)x; |
135 | static StructTy1 SS1; |
136 | static StructTy2 SS2; |
137 | } |
138 | |
139 | // Test function-scope variable initialization. |
140 | // NOOPT-LABEL: @test_func_scope_var_private( |
141 | // NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp1, align 4 |
142 | // NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp2, align 4 |
143 | // NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp3, align 4 |
144 | // NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp4, align 4 |
145 | // NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1 addrspace(5)* %SS1 to i8 addrspace(5)* |
146 | // NOOPT: call void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* align 8 %[[SS1]], i8 addrspace(4)* align 8 bitcast (%struct.StructTy1 addrspace(4)* @__const.test_func_scope_var_private.SS1 to i8 addrspace(4)*), i64 32, i1 false) |
147 | // NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2 addrspace(5)* %SS2 to i8 addrspace(5)* |
148 | // NOOPT: call void @llvm.memset.p5i8.i64(i8 addrspace(5)* align 8 %[[SS2]], i8 0, i64 24, i1 false) |
149 | void test_func_scope_var_private(void) { |
150 | private char *sp1 = 0; |
151 | private char *sp2 = NULL; |
152 | private char *sp3 = (private char*)((void)0, 0); |
153 | const int x = 0; |
154 | private char *sp4 = (private char*)x; |
155 | StructTy1 SS1 = {0, 0, 0, 0, 0}; |
156 | StructTy2 SS2 = {0, 0, 0}; |
157 | } |
158 | |
159 | // Test function-scope variable initialization. |
160 | // NOOPT-LABEL: @test_func_scope_var_local( |
161 | // NOOPT: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(5)* %sp1, align 4 |
162 | // NOOPT: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(5)* %sp2, align 4 |
163 | // NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)* addrspace(5)* %sp3, align 4 |
164 | // NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)* addrspace(5)* %sp4, align 4 |
165 | // NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1 addrspace(5)* %SS1 to i8 addrspace(5)* |
166 | // NOOPT: call void @llvm.memcpy.p5i8.p4i8.i64(i8 addrspace(5)* align 8 %[[SS1]], i8 addrspace(4)* align 8 bitcast (%struct.StructTy1 addrspace(4)* @__const.test_func_scope_var_local.SS1 to i8 addrspace(4)*), i64 32, i1 false) |
167 | // NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2 addrspace(5)* %SS2 to i8 addrspace(5)* |
168 | // NOOPT: call void @llvm.memset.p5i8.i64(i8 addrspace(5)* align 8 %[[SS2]], i8 0, i64 24, i1 false) |
169 | void test_func_scope_var_local(void) { |
170 | local char *sp1 = 0; |
171 | local char *sp2 = NULL; |
172 | local char *sp3 = (local char*)((void)0, 0); |
173 | const int x = 0; |
174 | local char *sp4 = (local char*)x; |
175 | StructTy1 SS1 = {0, 0, 0, 0, 0}; |
176 | StructTy2 SS2 = {0, 0, 0}; |
177 | } |
178 | |
179 | |
180 | // Test default initialization of pointers. |
181 | |
182 | // Tentative definition of global variables with non-zero initializer |
183 | // cannot have common linkage since common linkage requires zero initialization |
184 | // and does not have explicit section. |
185 | |
186 | // CHECK: @p1 = common local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4 |
187 | private char *p1; |
188 | |
189 | // CHECK: @p2 = weak local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4 |
190 | local char *p2; |
191 | |
192 | // CHECK: @p3 = common local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8 |
193 | constant char *p3; |
194 | |
195 | // CHECK: @p4 = common local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8 |
196 | global char *p4; |
197 | |
198 | // CHECK: @p5 = common local_unnamed_addr addrspace(1) global i8* null, align 8 |
199 | generic char *p5; |
200 | |
201 | // Test default initialization of structure. |
202 | |
203 | // CHECK: @S1 = weak local_unnamed_addr addrspace(1) global %struct.StructTy1 { i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }, align 8 |
204 | StructTy1 S1; |
205 | |
206 | // CHECK: @S2 = common local_unnamed_addr addrspace(1) global %struct.StructTy2 zeroinitializer, align 8 |
207 | StructTy2 S2; |
208 | |
209 | // Test default initialization of array. |
210 | // CHECK: @A1 = weak local_unnamed_addr addrspace(1) global [2 x %struct.StructTy1] [%struct.StructTy1 { i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }, %struct.StructTy1 { i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(4)* null, i8 addrspace(1)* null, i8* null }], align 8 |
211 | StructTy1 A1[2]; |
212 | |
213 | // CHECK: @A2 = common local_unnamed_addr addrspace(1) global [2 x %struct.StructTy2] zeroinitializer, align 8 |
214 | StructTy2 A2[2]; |
215 | |
216 | // Test comparison with 0. |
217 | |
218 | // CHECK-LABEL: cmp_private |
219 | // CHECK: icmp eq i8 addrspace(5)* %p, null |
220 | void cmp_private(private char* p) { |
221 | if (p != 0) |
222 | *p = 0; |
223 | } |
224 | |
225 | // CHECK-LABEL: cmp_local |
226 | // CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*) |
227 | void cmp_local(local char* p) { |
228 | if (p != 0) |
229 | *p = 0; |
230 | } |
231 | |
232 | // CHECK-LABEL: cmp_global |
233 | // CHECK: icmp eq i8 addrspace(1)* %p, null |
234 | void cmp_global(global char* p) { |
235 | if (p != 0) |
236 | *p = 0; |
237 | } |
238 | |
239 | // CHECK-LABEL: cmp_constant |
240 | // CHECK: icmp eq i8 addrspace(4)* %p, null |
241 | char cmp_constant(constant char* p) { |
242 | if (p != 0) |
243 | return *p; |
244 | else |
245 | return 0; |
246 | } |
247 | |
248 | // CHECK-LABEL: cmp_generic |
249 | // CHECK: icmp eq i8* %p, null |
250 | void cmp_generic(generic char* p) { |
251 | if (p != 0) |
252 | *p = 0; |
253 | } |
254 | |
255 | // Test comparison with NULL. |
256 | |
257 | // CHECK-LABEL: cmp_NULL_private |
258 | // CHECK: icmp eq i8 addrspace(5)* %p, null |
259 | void cmp_NULL_private(private char* p) { |
260 | if (p != NULL) |
261 | *p = 0; |
262 | } |
263 | |
264 | // CHECK-LABEL: cmp_NULL_local |
265 | // CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*) |
266 | void cmp_NULL_local(local char* p) { |
267 | if (p != NULL) |
268 | *p = 0; |
269 | } |
270 | |
271 | // CHECK-LABEL: cmp_NULL_global |
272 | // CHECK: icmp eq i8 addrspace(1)* %p, null |
273 | void cmp_NULL_global(global char* p) { |
274 | if (p != NULL) |
275 | *p = 0; |
276 | } |
277 | |
278 | // CHECK-LABEL: cmp_NULL_constant |
279 | // CHECK: icmp eq i8 addrspace(4)* %p, null |
280 | char cmp_NULL_constant(constant char* p) { |
281 | if (p != NULL) |
282 | return *p; |
283 | else |
284 | return 0; |
285 | } |
286 | |
287 | // CHECK-LABEL: cmp_NULL_generic |
288 | // CHECK: icmp eq i8* %p, null |
289 | void cmp_NULL_generic(generic char* p) { |
290 | if (p != NULL) |
291 | *p = 0; |
292 | } |
293 | |
294 | // Test storage 0 as null pointer. |
295 | // CHECK-LABEL: test_storage_null_pointer |
296 | // CHECK: store i8 addrspace(5)* null, i8 addrspace(5)** %arg_private |
297 | // CHECK: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)** %arg_local |
298 | // CHECK: store i8 addrspace(1)* null, i8 addrspace(1)** %arg_global |
299 | // CHECK: store i8 addrspace(4)* null, i8 addrspace(4)** %arg_constant |
300 | // CHECK: store i8* null, i8** %arg_generic |
301 | void test_storage_null_pointer(private char** arg_private, |
302 | local char** arg_local, |
303 | global char** arg_global, |
304 | constant char** arg_constant, |
305 | generic char** arg_generic) { |
306 | *arg_private = 0; |
307 | *arg_local = 0; |
308 | *arg_global = 0; |
309 | *arg_constant = 0; |
310 | *arg_generic = 0; |
311 | } |
312 | |
313 | // Test storage NULL as null pointer. |
314 | // CHECK-LABEL: test_storage_null_pointer_NULL |
315 | // CHECK: store i8 addrspace(5)* null, i8 addrspace(5)** %arg_private |
316 | // CHECK: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)** %arg_local |
317 | // CHECK: store i8 addrspace(1)* null, i8 addrspace(1)** %arg_global |
318 | // CHECK: store i8 addrspace(4)* null, i8 addrspace(4)** %arg_constant |
319 | // CHECK: store i8* null, i8** %arg_generic |
320 | void test_storage_null_pointer_NULL(private char** arg_private, |
321 | local char** arg_local, |
322 | global char** arg_global, |
323 | constant char** arg_constant, |
324 | generic char** arg_generic) { |
325 | *arg_private = NULL; |
326 | *arg_local = NULL; |
327 | *arg_global = NULL; |
328 | *arg_constant = NULL; |
329 | *arg_generic = NULL; |
330 | } |
331 | |
332 | // Test pass null pointer to function as argument. |
333 | void test_pass_null_pointer_arg_calee(private char* arg_private, |
334 | local char* arg_local, |
335 | global char* arg_global, |
336 | constant char* arg_constant, |
337 | generic char* arg_generic); |
338 | |
339 | // CHECK-LABEL: test_pass_null_pointer_arg |
340 | // CHECK: call void @test_pass_null_pointer_arg_calee(i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(4)* null, i8* null) |
341 | // CHECK: call void @test_pass_null_pointer_arg_calee(i8 addrspace(5)* null, i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(4)* null, i8* null) |
342 | void test_pass_null_pointer_arg(void) { |
343 | test_pass_null_pointer_arg_calee(0, 0, 0, 0, 0); |
344 | test_pass_null_pointer_arg_calee(NULL, NULL, NULL, NULL, NULL); |
345 | } |
346 | |
347 | // Test cast null pointer to size_t. |
348 | void test_cast_null_pointer_to_sizet_calee(size_t arg_private, |
349 | size_t arg_local, |
350 | size_t arg_global, |
351 | size_t arg_constant, |
352 | size_t arg_generic); |
353 | |
354 | // CHECK-LABEL: test_cast_null_pointer_to_sizet |
355 | // CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 0, i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0) |
356 | // CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 0, i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0) |
357 | void test_cast_null_pointer_to_sizet(void) { |
358 | test_cast_null_pointer_to_sizet_calee((size_t)((private char*)0), |
359 | (size_t)((local char*)0), |
360 | (size_t)((global char*)0), |
361 | (size_t)((constant char*)0), |
362 | (size_t)((generic char*)0)); |
363 | test_cast_null_pointer_to_sizet_calee((size_t)((private char*)NULL), |
364 | (size_t)((local char*)NULL), |
365 | (size_t)((global char*)NULL), |
366 | (size_t)((constant char*)0), // NULL cannot be casted to constant pointer since it is defined as a generic pointer |
367 | (size_t)((generic char*)NULL)); |
368 | } |
369 | |
370 | // Test comparison between null pointers. |
371 | #define TEST_EQ00(addr1, addr2) int test_eq00_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)0; } |
372 | #define TEST_EQ0N(addr1, addr2) int test_eq0N_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; } |
373 | #define TEST_EQN0(addr1, addr2) int test_eqN0_##addr1##_##addr2(void) { return (addr1 char*)NULL == (addr2 char*)0; } |
374 | #define TEST_EQNN(addr1, addr2) int test_eqNN_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; } |
375 | #define TEST_NE00(addr1, addr2) int test_ne00_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)0; } |
376 | #define TEST_NE0N(addr1, addr2) int test_ne0N_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; } |
377 | #define TEST_NEN0(addr1, addr2) int test_neN0_##addr1##_##addr2(void) { return (addr1 char*)NULL != (addr2 char*)0; } |
378 | #define TEST_NENN(addr1, addr2) int test_neNN_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; } |
379 | #define TEST(addr1, addr2) \ |
380 | TEST_EQ00(addr1, addr2) \ |
381 | TEST_EQ0N(addr1, addr2) \ |
382 | TEST_EQN0(addr1, addr2) \ |
383 | TEST_EQNN(addr1, addr2) \ |
384 | TEST_NE00(addr1, addr2) \ |
385 | TEST_NE0N(addr1, addr2) \ |
386 | TEST_NEN0(addr1, addr2) \ |
387 | TEST_NENN(addr1, addr2) |
388 | |
389 | // CHECK-LABEL: test_eq00_generic_private |
390 | // CHECK: ret i32 1 |
391 | // CHECK-LABEL: test_eq0N_generic_private |
392 | // CHECK: ret i32 1 |
393 | // CHECK-LABEL: test_eqN0_generic_private |
394 | // CHECK: ret i32 1 |
395 | // CHECK-LABEL: test_eqNN_generic_private |
396 | // CHECK: ret i32 1 |
397 | // CHECK-LABEL: test_ne00_generic_private |
398 | // CHECK: ret i32 0 |
399 | // CHECK-LABEL: test_ne0N_generic_private |
400 | // CHECK: ret i32 0 |
401 | // CHECK-LABEL: test_neN0_generic_private |
402 | // CHECK: ret i32 0 |
403 | // CHECK-LABEL: test_neNN_generic_private |
404 | // CHECK: ret i32 0 |
405 | TEST(generic, private) |
406 | |
407 | // CHECK-LABEL: test_eq00_generic_local |
408 | // CHECK: ret i32 1 |
409 | // CHECK-LABEL: test_eq0N_generic_local |
410 | // CHECK: ret i32 1 |
411 | // CHECK-LABEL: test_eqN0_generic_local |
412 | // CHECK: ret i32 1 |
413 | // CHECK-LABEL: test_eqNN_generic_local |
414 | // CHECK: ret i32 1 |
415 | // CHECK-LABEL: test_ne00_generic_local |
416 | // CHECK: ret i32 0 |
417 | // CHECK-LABEL: test_ne0N_generic_local |
418 | // CHECK: ret i32 0 |
419 | // CHECK-LABEL: test_neN0_generic_local |
420 | // CHECK: ret i32 0 |
421 | // CHECK-LABEL: test_neNN_generic_local |
422 | // CHECK: ret i32 0 |
423 | TEST(generic, local) |
424 | |
425 | // CHECK-LABEL: test_eq00_generic_global |
426 | // CHECK: ret i32 1 |
427 | // CHECK-LABEL: test_eq0N_generic_global |
428 | // CHECK: ret i32 1 |
429 | // CHECK-LABEL: test_eqN0_generic_global |
430 | // CHECK: ret i32 1 |
431 | // CHECK-LABEL: test_eqNN_generic_global |
432 | // CHECK: ret i32 1 |
433 | // CHECK-LABEL: test_ne00_generic_global |
434 | // CHECK: ret i32 0 |
435 | // CHECK-LABEL: test_ne0N_generic_global |
436 | // CHECK: ret i32 0 |
437 | // CHECK-LABEL: test_neN0_generic_global |
438 | // CHECK: ret i32 0 |
439 | // CHECK-LABEL: test_neNN_generic_global |
440 | // CHECK: ret i32 0 |
441 | TEST(generic, global) |
442 | |
443 | // CHECK-LABEL: test_eq00_generic_generic |
444 | // CHECK: ret i32 1 |
445 | // CHECK-LABEL: test_eq0N_generic_generic |
446 | // CHECK: ret i32 1 |
447 | // CHECK-LABEL: test_eqN0_generic_generic |
448 | // CHECK: ret i32 1 |
449 | // CHECK-LABEL: test_eqNN_generic_generic |
450 | // CHECK: ret i32 1 |
451 | // CHECK-LABEL: test_ne00_generic_generic |
452 | // CHECK: ret i32 0 |
453 | // CHECK-LABEL: test_ne0N_generic_generic |
454 | // CHECK: ret i32 0 |
455 | // CHECK-LABEL: test_neN0_generic_generic |
456 | // CHECK: ret i32 0 |
457 | // CHECK-LABEL: test_neNN_generic_generic |
458 | // CHECK: ret i32 0 |
459 | TEST(generic, generic) |
460 | |
461 | // CHECK-LABEL: test_eq00_constant_constant |
462 | // CHECK: ret i32 1 |
463 | TEST_EQ00(constant, constant) |
464 | |
465 | // Test cast to bool. |
466 | |
467 | // CHECK-LABEL: cast_bool_private |
468 | // CHECK: icmp eq i8 addrspace(5)* %p, null |
469 | void cast_bool_private(private char* p) { |
470 | if (p) |
471 | *p = 0; |
472 | } |
473 | |
474 | // CHECK-LABEL: cast_bool_local |
475 | // CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*) |
476 | void cast_bool_local(local char* p) { |
477 | if (p) |
478 | *p = 0; |
479 | } |
480 | |
481 | // CHECK-LABEL: cast_bool_global |
482 | // CHECK: icmp eq i8 addrspace(1)* %p, null |
483 | void cast_bool_global(global char* p) { |
484 | if (p) |
485 | *p = 0; |
486 | } |
487 | |
488 | // CHECK-LABEL: cast_bool_constant |
489 | // CHECK: icmp eq i8 addrspace(4)* %p, null |
490 | char cast_bool_constant(constant char* p) { |
491 | if (p) |
492 | return *p; |
493 | else |
494 | return 0; |
495 | } |
496 | |
497 | // CHECK-LABEL: cast_bool_generic |
498 | // CHECK: icmp eq i8* %p, null |
499 | void cast_bool_generic(generic char* p) { |
500 | if (p) |
501 | *p = 0; |
502 | } |
503 | |
504 | // Test initialize a struct using memset. |
505 | // For large structures which is mostly zero, clang generats llvm.memset for |
506 | // the zero part and store for non-zero members. |
507 | typedef struct { |
508 | long a, b, c, d; |
509 | private char *p; |
510 | } StructTy3; |
511 | |
512 | // CHECK-LABEL: test_memset_private |
513 | // CHECK: call void @llvm.memset.p5i8.i64(i8 addrspace(5)* align 8 {{.*}}, i8 0, i64 40, i1 false) |
514 | void test_memset_private(private StructTy3 *ptr) { |
515 | StructTy3 S3 = {0, 0, 0, 0, 0}; |
516 | *ptr = S3; |
517 | } |
518 | |
519 | // Test casting literal 0 to pointer. |
520 | // A 0 literal casted to pointer should become a null pointer. |
521 | |
522 | // CHECK-LABEL: test_cast_0_to_local_ptr |
523 | // CHECK: ret i32 addrspace(3)* addrspacecast (i32* null to i32 addrspace(3)*) |
524 | local int* test_cast_0_to_local_ptr(void) { |
525 | return (local int*)0; |
526 | } |
527 | |
528 | // CHECK-LABEL: test_cast_0_to_private_ptr |
529 | // CHECK: ret i32 addrspace(5)* null |
530 | private int* test_cast_0_to_private_ptr(void) { |
531 | return (private int*)0; |
532 | } |
533 | |
534 | // Test casting non-literal integer with 0 value to pointer. |
535 | // A non-literal integer expression with 0 value is casted to a pointer with |
536 | // zero value. |
537 | |
538 | // CHECK-LABEL: test_cast_int_to_ptr1_private |
539 | // CHECK: ret i32 addrspace(5)* null |
540 | private int* test_cast_int_to_ptr1_private(void) { |
541 | return (private int*)((void)0, 0); |
542 | } |
543 | |
544 | // CHECK-LABEL: test_cast_int_to_ptr1_local |
545 | // CHECK: ret i32 addrspace(3)* null |
546 | local int* test_cast_int_to_ptr1_local(void) { |
547 | return (local int*)((void)0, 0); |
548 | } |
549 | |
550 | // CHECK-LABEL: test_cast_int_to_ptr2 |
551 | // CHECK: ret i32 addrspace(5)* null |
552 | private int* test_cast_int_to_ptr2(void) { |
553 | int x = 0; |
554 | return (private int*)x; |
555 | } |
556 | |
557 | // Test logical operations. |
558 | // CHECK-LABEL: test_not_nullptr |
559 | // CHECK: ret i32 1 |
560 | int test_not_nullptr(void) { |
561 | return !(private char*)NULL; |
562 | } |
563 | |
564 | // CHECK-LABEL: test_and_nullptr |
565 | // CHECK: ret i32 0 |
566 | int test_and_nullptr(int a) { |
567 | return a && ((private char*)NULL); |
568 | } |
569 | |
570 | // CHECK-LABEL: test_not_private_ptr |
571 | // CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(5)* %p, null |
572 | // CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32 |
573 | // CHECK: ret i32 %[[lnot_ext]] |
574 | int test_not_private_ptr(private char* p) { |
575 | return !p; |
576 | } |
577 | |
578 | // CHECK-LABEL: test_not_local_ptr |
579 | // CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*) |
580 | // CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32 |
581 | // CHECK: ret i32 %[[lnot_ext]] |
582 | int test_not_local_ptr(local char* p) { |
583 | return !p; |
584 | } |
585 | |
586 | |
587 | // CHECK-LABEL: test_and_ptr |
588 | // CHECK: %[[tobool:.*]] = icmp ne i8 addrspace(5)* %p1, null |
589 | // CHECK: %[[tobool1:.*]] = icmp ne i8 addrspace(3)* %p2, addrspacecast (i8* null to i8 addrspace(3)*) |
590 | // CHECK: %[[res:.*]] = and i1 %[[tobool]], %[[tobool1]] |
591 | // CHECK: %[[land_ext:.*]] = zext i1 %[[res]] to i32 |
592 | // CHECK: ret i32 %[[land_ext]] |
593 | int test_and_ptr(private char* p1, local char* p2) { |
594 | return p1 && p2; |
595 | } |
596 | |
597 | // Test folding of null pointer in function scope. |
598 | // NOOPT-LABEL: test_fold_private |
599 | // NOOPT: call void @test_fold_callee |
600 | // NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)* addrspace(5)* %glob, align 8 |
601 | // NOOPT: %{{.*}} = sub i64 %{{.*}}, 0 |
602 | // NOOPT: call void @test_fold_callee |
603 | // NOOPT: %{{.*}} = add nsw i64 %{{.*}}, 0 |
604 | // NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1 |
605 | void test_fold_callee(void); |
606 | void test_fold_private(void) { |
607 | global int* glob = (test_fold_callee(), (global int*)(generic char*)0); |
608 | long x = glob - (global int*)(generic char*)0; |
609 | x = x + (int)(test_fold_callee(), (private int*)(generic char*)(global short*)0); |
610 | x = x - (int)((private int*)0 == (private int*)(generic char*)0); |
611 | } |
612 | |
613 | // NOOPT-LABEL: test_fold_local |
614 | // NOOPT: call void @test_fold_callee |
615 | // NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)* addrspace(5)* %glob, align 8 |
616 | // NOOPT: %{{.*}} = sub i64 %{{.*}}, 0 |
617 | // NOOPT: call void @test_fold_callee |
618 | // NOOPT: %{{.*}} = add nsw i64 %{{.*}}, sext (i32 ptrtoint (i32 addrspace(3)* addrspacecast (i32* null to i32 addrspace(3)*) to i32) to i64) |
619 | // NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1 |
620 | void test_fold_local(void) { |
621 | global int* glob = (test_fold_callee(), (global int*)(generic char*)0); |
622 | long x = glob - (global int*)(generic char*)0; |
623 | x = x + (int)(test_fold_callee(), (local int*)(generic char*)(global short*)0); |
624 | x = x - (int)((local int*)0 == (local int*)(generic char*)0); |
625 | } |
626 | |