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