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