blob: 3e54cd5c34a0d9d039c70aa6948cc4338e11daeb [file] [log] [blame]
Yaxun Liu6d96f1632017-05-18 18:51:09 +00001// RUN: %clang_cc1 %s -cl-std=CL2.0 -include opencl-c.h -triple amdgcn---opencl -emit-llvm -o - | FileCheck %s
2// RUN: %clang_cc1 %s -O0 -cl-std=CL2.0 -include opencl-c.h -triple amdgcn---opencl -emit-llvm -o - | FileCheck --check-prefix=NOOPT %s
Yaxun Liu402804b2016-12-15 08:09:08 +00003
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
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000023// CHECK: @private_p = local_unnamed_addr addrspace(1) global i8* null, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000024private 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
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000040// CHECK: @private_p_NULL = local_unnamed_addr addrspace(1) global i8* null, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000041private 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
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000061// CHECK: @fold_priv = local_unnamed_addr addrspace(1) global i16* null, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000062private short *fold_priv = (private short*)(generic int*)(global void*)0;
63
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000064// CHECK: @fold_priv_arith = local_unnamed_addr addrspace(1) global i8* inttoptr (i32 10 to i8*), align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000065private char *fold_priv_arith = (private char*)0 + 10;
66
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000067// CHECK: @fold_int = local_unnamed_addr addrspace(1) global i32 14, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000068int fold_int = (int)(private void*)(generic char*)(global int*)0 + 14;
69
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000070// CHECK: @fold_int2 = local_unnamed_addr addrspace(1) global i32 13, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000071int fold_int2 = (int) ((private void*)0 + 13);
72
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000073// CHECK: @fold_int3 = local_unnamed_addr addrspace(1) global i32 0, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000074int fold_int3 = (int) ((private int*)0);
75
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000076// CHECK: @fold_int4 = local_unnamed_addr addrspace(1) global i32 8, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000077int fold_int4 = (int) &((private int*)0)[2];
78
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000079// CHECK: @fold_int5 = local_unnamed_addr addrspace(1) global i32 4, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000080int fold_int5 = (int) &((private StructTy1*)0)->p2;
81
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000082
83// CHECK: @fold_int_local = local_unnamed_addr addrspace(1) global i32 13, align 4
84int fold_int_local = (int)(local void*)(generic char*)(global int*)0 + 14;
85
86// CHECK: @fold_int2_local = local_unnamed_addr addrspace(1) global i32 12, align 4
87int fold_int2_local = (int) ((local void*)0 + 13);
88
89// CHECK: @fold_int3_local = local_unnamed_addr addrspace(1) global i32 -1, align 4
90int fold_int3_local = (int) ((local int*)0);
91
92// CHECK: @fold_int4_local = local_unnamed_addr addrspace(1) global i32 7, align 4
93int fold_int4_local = (int) &((local int*)0)[2];
94
95// CHECK: @fold_int5_local = local_unnamed_addr addrspace(1) global i32 3, align 4
96int fold_int5_local = (int) &((local StructTy1*)0)->p2;
97
98
Yaxun Liu402804b2016-12-15 08:09:08 +000099// Test static variable initialization.
100
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000101// NOOPT: @test_static_var_private.sp1 = internal addrspace(1) global i8* null, align 4
102// NOOPT: @test_static_var_private.sp2 = internal addrspace(1) global i8* null, align 4
103// NOOPT: @test_static_var_private.sp3 = internal addrspace(1) global i8* null, align 4
104// NOOPT: @test_static_var_private.sp4 = internal addrspace(1) global i8* null, align 4
105// NOOPT: @test_static_var_private.sp5 = internal addrspace(1) global i8* null, align 4
106// NOOPT: @test_static_var_private.SS1 = internal addrspace(1) global %struct.StructTy1 { i8* null, 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
107// NOOPT: @test_static_var_private.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +0000108
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000109void test_static_var_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000110 static private char *sp1 = 0;
111 static private char *sp2 = NULL;
112 static private char *sp3;
113 static private char *sp4 = (private char*)((void)0, 0);
114 const int x = 0;
115 static private char *sp5 = (private char*)x;
116 static StructTy1 SS1;
117 static StructTy2 SS2;
118}
119
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000120// NOOPT: @test_static_var_local.sp1 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4
121// NOOPT: @test_static_var_local.sp2 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4
122// NOOPT: @test_static_var_local.sp3 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4
123// NOOPT: @test_static_var_local.sp4 = internal addrspace(1) global i8 addrspace(3)* null, align 4
124// NOOPT: @test_static_var_local.sp5 = internal addrspace(1) global i8 addrspace(3)* null, align 4
125// NOOPT: @test_static_var_local.SS1 = internal addrspace(1) global %struct.StructTy1 { i8* null, 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
126// NOOPT: @test_static_var_local.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 4
127void test_static_var_local(void) {
128 static local char *sp1 = 0;
129 static local char *sp2 = NULL;
130 static local char *sp3;
131 static local char *sp4 = (local char*)((void)0, 0);
132 const int x = 0;
133 static local char *sp5 = (local char*)x;
134 static StructTy1 SS1;
135 static StructTy2 SS2;
136}
137
Yaxun Liu402804b2016-12-15 08:09:08 +0000138// Test function-scope variable initialization.
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000139// NOOPT-LABEL: @test_func_scope_var_private(
140// NOOPT: store i8* null, i8** %sp1, align 4
141// NOOPT: store i8* null, i8** %sp2, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +0000142// NOOPT: store i8* null, i8** %sp3, align 4
143// NOOPT: store i8* null, i8** %sp4, align 4
144// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1* %SS1 to i8*
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000145// NOOPT: call void @llvm.memcpy.p0i8.p2i8.i64(i8* %[[SS1]], i8 addrspace(2)* bitcast (%struct.StructTy1 addrspace(2)* @test_func_scope_var_private.SS1 to i8 addrspace(2)*), i64 32, i32 4, i1 false)
Yaxun Liu402804b2016-12-15 08:09:08 +0000146// NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2* %SS2 to i8*
147// NOOPT: call void @llvm.memset.p0i8.i64(i8* %[[SS2]], i8 0, i64 24, i32 4, i1 false)
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000148void test_func_scope_var_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000149 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
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000158// Test function-scope variable initialization.
159// NOOPT-LABEL: @test_func_scope_var_local(
160// NOOPT: store i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(3)** %sp1, align 4
161// NOOPT: store i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(3)** %sp2, align 4
162// NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)** %sp3, align 4
163// NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)** %sp4, align 4
164// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1* %SS1 to i8*
165// NOOPT: call void @llvm.memcpy.p0i8.p2i8.i64(i8* %[[SS1]], i8 addrspace(2)* bitcast (%struct.StructTy1 addrspace(2)* @test_func_scope_var_local.SS1 to i8 addrspace(2)*), i64 32, i32 4, i1 false)
166// NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2* %SS2 to i8*
167// NOOPT: call void @llvm.memset.p0i8.i64(i8* %[[SS2]], i8 0, i64 24, i32 4, i1 false)
168void test_func_scope_var_local(void) {
169 local char *sp1 = 0;
170 local char *sp2 = NULL;
171 local char *sp3 = (local char*)((void)0, 0);
172 const int x = 0;
173 local char *sp4 = (local char*)x;
174 StructTy1 SS1 = {0, 0, 0, 0, 0};
175 StructTy2 SS2 = {0, 0, 0};
176}
177
178
Yaxun Liu402804b2016-12-15 08:09:08 +0000179// Test default initialization of pointers.
180
181// Tentative definition of global variables with non-zero initializer
182// cannot have common linkage since common linkage requires zero initialization
183// and does not have explicit section.
184
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000185// CHECK: @p1 = common local_unnamed_addr addrspace(1) global i8* null, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +0000186private char *p1;
187
188// CHECK: @p2 = weak local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4
189local char *p2;
190
191// CHECK: @p3 = common local_unnamed_addr addrspace(1) global i8 addrspace(2)* null, align 4
192constant char *p3;
193
194// CHECK: @p4 = common local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 4
195global char *p4;
196
197// CHECK: @p5 = common local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 4
198generic char *p5;
199
200// Test default initialization of sturcture.
201
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000202// CHECK: @S1 = weak local_unnamed_addr addrspace(1) global %struct.StructTy1 { i8* null, 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
Yaxun Liu402804b2016-12-15 08:09:08 +0000203StructTy1 S1;
204
205// CHECK: @S2 = common local_unnamed_addr addrspace(1) global %struct.StructTy2 zeroinitializer, align 4
206StructTy2 S2;
207
208// Test default initialization of array.
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000209// CHECK: @A1 = weak local_unnamed_addr addrspace(1) global [2 x %struct.StructTy1] [%struct.StructTy1 { i8* null, 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* null, 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
Yaxun Liu402804b2016-12-15 08:09:08 +0000210StructTy1 A1[2];
211
212// CHECK: @A2 = common local_unnamed_addr addrspace(1) global [2 x %struct.StructTy2] zeroinitializer, align 4
213StructTy2 A2[2];
214
215// Test comparison with 0.
216
217// CHECK-LABEL: cmp_private
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000218// CHECK: icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000219void cmp_private(private char* p) {
220 if (p != 0)
221 *p = 0;
222}
223
224// CHECK-LABEL: cmp_local
225// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*)
226void cmp_local(local char* p) {
227 if (p != 0)
228 *p = 0;
229}
230
231// CHECK-LABEL: cmp_global
232// CHECK: icmp eq i8 addrspace(1)* %p, null
233void cmp_global(global char* p) {
234 if (p != 0)
235 *p = 0;
236}
237
238// CHECK-LABEL: cmp_constant
239// CHECK: icmp eq i8 addrspace(2)* %p, null
240char cmp_constant(constant char* p) {
241 if (p != 0)
242 return *p;
243 else
244 return 0;
245}
246
247// CHECK-LABEL: cmp_generic
248// CHECK: icmp eq i8 addrspace(4)* %p, null
249void cmp_generic(generic char* p) {
250 if (p != 0)
251 *p = 0;
252}
253
254// Test comparison with NULL.
255
256// CHECK-LABEL: cmp_NULL_private
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000257// CHECK: icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000258void cmp_NULL_private(private char* p) {
259 if (p != NULL)
260 *p = 0;
261}
262
263// CHECK-LABEL: cmp_NULL_local
264// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*)
265void cmp_NULL_local(local char* p) {
266 if (p != NULL)
267 *p = 0;
268}
269
270// CHECK-LABEL: cmp_NULL_global
271// CHECK: icmp eq i8 addrspace(1)* %p, null
272void cmp_NULL_global(global char* p) {
273 if (p != NULL)
274 *p = 0;
275}
276
277// CHECK-LABEL: cmp_NULL_constant
278// CHECK: icmp eq i8 addrspace(2)* %p, null
279char cmp_NULL_constant(constant char* p) {
280 if (p != NULL)
281 return *p;
282 else
283 return 0;
284}
285
286// CHECK-LABEL: cmp_NULL_generic
287// CHECK: icmp eq i8 addrspace(4)* %p, null
288void cmp_NULL_generic(generic char* p) {
289 if (p != NULL)
290 *p = 0;
291}
292
293// Test storage 0 as null pointer.
294// CHECK-LABEL: test_storage_null_pointer
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000295// CHECK: store i8* null, i8* addrspace(4)* %arg_private
Yaxun Liu402804b2016-12-15 08:09:08 +0000296// CHECK: store i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(4)* %arg_local
297// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)* addrspace(4)* %arg_global
298// CHECK: store i8 addrspace(2)* null, i8 addrspace(2)* addrspace(4)* %arg_constant
299// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)* addrspace(4)* %arg_generic
300void test_storage_null_pointer(private char** arg_private,
301 local char** arg_local,
302 global char** arg_global,
303 constant char** arg_constant,
304 generic char** arg_generic) {
305 *arg_private = 0;
306 *arg_local = 0;
307 *arg_global = 0;
308 *arg_constant = 0;
309 *arg_generic = 0;
310}
311
312// Test storage NULL as null pointer.
313// CHECK-LABEL: test_storage_null_pointer_NULL
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000314// CHECK: store i8* null, i8* addrspace(4)* %arg_private
Yaxun Liu402804b2016-12-15 08:09:08 +0000315// CHECK: store i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(4)* %arg_local
316// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)* addrspace(4)* %arg_global
317// CHECK: store i8 addrspace(2)* null, i8 addrspace(2)* addrspace(4)* %arg_constant
318// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)* addrspace(4)* %arg_generic
319void test_storage_null_pointer_NULL(private char** arg_private,
320 local char** arg_local,
321 global char** arg_global,
322 constant char** arg_constant,
323 generic char** arg_generic) {
324 *arg_private = NULL;
325 *arg_local = NULL;
326 *arg_global = NULL;
327 *arg_constant = NULL;
328 *arg_generic = NULL;
329}
330
331// Test pass null pointer to function as argument.
332void test_pass_null_pointer_arg_calee(private char* arg_private,
333 local char* arg_local,
334 global char* arg_global,
335 constant char* arg_constant,
336 generic char* arg_generic);
337
338// CHECK-LABEL: test_pass_null_pointer_arg
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000339// CHECK: call void @test_pass_null_pointer_arg_calee(i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(2)* null, i8 addrspace(4)* null)
340// CHECK: call void @test_pass_null_pointer_arg_calee(i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(2)* null, i8 addrspace(4)* null)
Yaxun Liu402804b2016-12-15 08:09:08 +0000341void test_pass_null_pointer_arg(void) {
342 test_pass_null_pointer_arg_calee(0, 0, 0, 0, 0);
343 test_pass_null_pointer_arg_calee(NULL, NULL, NULL, NULL, NULL);
344}
345
346// Test cast null pointer to size_t.
347void test_cast_null_pointer_to_sizet_calee(size_t arg_private,
348 size_t arg_local,
349 size_t arg_global,
350 size_t arg_constant,
351 size_t arg_generic);
352
353// CHECK-LABEL: test_cast_null_pointer_to_sizet
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000354// CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 0, i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0)
355// CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 0, i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0)
Yaxun Liu402804b2016-12-15 08:09:08 +0000356void test_cast_null_pointer_to_sizet(void) {
357 test_cast_null_pointer_to_sizet_calee((size_t)((private char*)0),
358 (size_t)((local char*)0),
359 (size_t)((global char*)0),
360 (size_t)((constant char*)0),
361 (size_t)((generic char*)0));
362 test_cast_null_pointer_to_sizet_calee((size_t)((private char*)NULL),
363 (size_t)((local char*)NULL),
364 (size_t)((global char*)NULL),
365 (size_t)((constant char*)0), // NULL cannot be casted to constant pointer since it is defined as a generic pointer
366 (size_t)((generic char*)NULL));
367}
368
369// Test comparision between null pointers.
370#define TEST_EQ00(addr1, addr2) int test_eq00_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)0; }
371#define TEST_EQ0N(addr1, addr2) int test_eq0N_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; }
372#define TEST_EQN0(addr1, addr2) int test_eqN0_##addr1##_##addr2(void) { return (addr1 char*)NULL == (addr2 char*)0; }
373#define TEST_EQNN(addr1, addr2) int test_eqNN_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; }
374#define TEST_NE00(addr1, addr2) int test_ne00_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)0; }
375#define TEST_NE0N(addr1, addr2) int test_ne0N_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; }
376#define TEST_NEN0(addr1, addr2) int test_neN0_##addr1##_##addr2(void) { return (addr1 char*)NULL != (addr2 char*)0; }
377#define TEST_NENN(addr1, addr2) int test_neNN_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; }
378#define TEST(addr1, addr2) \
379 TEST_EQ00(addr1, addr2) \
380 TEST_EQ0N(addr1, addr2) \
381 TEST_EQN0(addr1, addr2) \
382 TEST_EQNN(addr1, addr2) \
383 TEST_NE00(addr1, addr2) \
384 TEST_NE0N(addr1, addr2) \
385 TEST_NEN0(addr1, addr2) \
386 TEST_NENN(addr1, addr2)
387
388// CHECK-LABEL: test_eq00_generic_private
389// CHECK: ret i32 1
390// CHECK-LABEL: test_eq0N_generic_private
391// CHECK: ret i32 1
392// CHECK-LABEL: test_eqN0_generic_private
393// CHECK: ret i32 1
394// CHECK-LABEL: test_eqNN_generic_private
395// CHECK: ret i32 1
396// CHECK-LABEL: test_ne00_generic_private
397// CHECK: ret i32 0
398// CHECK-LABEL: test_ne0N_generic_private
399// CHECK: ret i32 0
400// CHECK-LABEL: test_neN0_generic_private
401// CHECK: ret i32 0
402// CHECK-LABEL: test_neNN_generic_private
403// CHECK: ret i32 0
404TEST(generic, private)
405
406// CHECK-LABEL: test_eq00_generic_local
407// CHECK: ret i32 1
408// CHECK-LABEL: test_eq0N_generic_local
409// CHECK: ret i32 1
410// CHECK-LABEL: test_eqN0_generic_local
411// CHECK: ret i32 1
412// CHECK-LABEL: test_eqNN_generic_local
413// CHECK: ret i32 1
414// CHECK-LABEL: test_ne00_generic_local
415// CHECK: ret i32 0
416// CHECK-LABEL: test_ne0N_generic_local
417// CHECK: ret i32 0
418// CHECK-LABEL: test_neN0_generic_local
419// CHECK: ret i32 0
420// CHECK-LABEL: test_neNN_generic_local
421// CHECK: ret i32 0
422TEST(generic, local)
423
424// CHECK-LABEL: test_eq00_generic_global
425// CHECK: ret i32 1
426// CHECK-LABEL: test_eq0N_generic_global
427// CHECK: ret i32 1
428// CHECK-LABEL: test_eqN0_generic_global
429// CHECK: ret i32 1
430// CHECK-LABEL: test_eqNN_generic_global
431// CHECK: ret i32 1
432// CHECK-LABEL: test_ne00_generic_global
433// CHECK: ret i32 0
434// CHECK-LABEL: test_ne0N_generic_global
435// CHECK: ret i32 0
436// CHECK-LABEL: test_neN0_generic_global
437// CHECK: ret i32 0
438// CHECK-LABEL: test_neNN_generic_global
439// CHECK: ret i32 0
440TEST(generic, global)
441
442// CHECK-LABEL: test_eq00_generic_generic
443// CHECK: ret i32 1
444// CHECK-LABEL: test_eq0N_generic_generic
445// CHECK: ret i32 1
446// CHECK-LABEL: test_eqN0_generic_generic
447// CHECK: ret i32 1
448// CHECK-LABEL: test_eqNN_generic_generic
449// CHECK: ret i32 1
450// CHECK-LABEL: test_ne00_generic_generic
451// CHECK: ret i32 0
452// CHECK-LABEL: test_ne0N_generic_generic
453// CHECK: ret i32 0
454// CHECK-LABEL: test_neN0_generic_generic
455// CHECK: ret i32 0
456// CHECK-LABEL: test_neNN_generic_generic
457// CHECK: ret i32 0
458TEST(generic, generic)
459
460// CHECK-LABEL: test_eq00_constant_constant
461// CHECK: ret i32 1
462TEST_EQ00(constant, constant)
463
464// Test cast to bool.
465
466// CHECK-LABEL: cast_bool_private
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000467// CHECK: icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000468void cast_bool_private(private char* p) {
469 if (p)
470 *p = 0;
471}
472
473// CHECK-LABEL: cast_bool_local
474// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*)
475void cast_bool_local(local char* p) {
476 if (p)
477 *p = 0;
478}
479
480// CHECK-LABEL: cast_bool_global
481// CHECK: icmp eq i8 addrspace(1)* %p, null
482void cast_bool_global(global char* p) {
483 if (p)
484 *p = 0;
485}
486
487// CHECK-LABEL: cast_bool_constant
488// CHECK: icmp eq i8 addrspace(2)* %p, null
489char cast_bool_constant(constant char* p) {
490 if (p)
491 return *p;
492 else
493 return 0;
494}
495
496// CHECK-LABEL: cast_bool_generic
497// CHECK: icmp eq i8 addrspace(4)* %p, null
498void cast_bool_generic(generic char* p) {
499 if (p)
500 *p = 0;
501}
502
503// Test initialize a struct using memset.
504// For large structures which is mostly zero, clang generats llvm.memset for
505// the zero part and store for non-zero members.
506typedef struct {
507 long a, b, c, d;
508 private char *p;
509} StructTy3;
510
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000511// CHECK-LABEL: test_memset_private
512// CHECK: call void @llvm.memset.p0i8.i64(i8* nonnull {{.*}}, i8 0, i64 40, i32 8, i1 false)
513StructTy3 test_memset_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000514 StructTy3 S3 = {0, 0, 0, 0, 0};
515 return S3;
516}
517
518// Test casting literal 0 to pointer.
519// A 0 literal casted to pointer should become a null pointer.
520
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000521// CHECK-LABEL: test_cast_0_to_local_ptr
522// CHECK: ret i32 addrspace(3)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(3)*)
523local int* test_cast_0_to_local_ptr(void) {
524 return (local int*)0;
525}
526
527// CHECK-LABEL: test_cast_0_to_private_ptr
528// CHECK: ret i32* null
529private int* test_cast_0_to_private_ptr(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000530 return (private int*)0;
531}
532
533// Test casting non-literal integer with 0 value to pointer.
534// A non-literal integer expression with 0 value is casted to a pointer with
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000535// zero value.
Yaxun Liu402804b2016-12-15 08:09:08 +0000536
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000537// CHECK-LABEL: test_cast_int_to_ptr1_private
Yaxun Liu402804b2016-12-15 08:09:08 +0000538// CHECK: ret i32* null
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000539private int* test_cast_int_to_ptr1_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000540 return (private int*)((void)0, 0);
541}
542
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000543// CHECK-LABEL: test_cast_int_to_ptr1_local
544 // CHECK: ret i32 addrspace(3)* null
545local int* test_cast_int_to_ptr1_local(void) {
546 return (local int*)((void)0, 0);
547}
548
Yaxun Liu402804b2016-12-15 08:09:08 +0000549// CHECK-LABEL: test_cast_int_to_ptr2
550// CHECK: ret i32* null
551private int* test_cast_int_to_ptr2(void) {
552 int x = 0;
553 return (private int*)x;
554}
555
556// Test logical operations.
557// CHECK-LABEL: test_not_nullptr
558// CHECK: ret i32 1
559int test_not_nullptr(void) {
560 return !(private char*)NULL;
561}
562
563// CHECK-LABEL: test_and_nullptr
564// CHECK: ret i32 0
565int test_and_nullptr(int a) {
566 return a && ((private char*)NULL);
567}
568
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000569// CHECK-LABEL: test_not_private_ptr
570// CHECK: %[[lnot:.*]] = icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000571// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
572// CHECK: ret i32 %[[lnot_ext]]
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000573int test_not_private_ptr(private char* p) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000574 return !p;
575}
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000576
577// CHECK-LABEL: test_not_local_ptr
578// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(3)* %p, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*)
579// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
580// CHECK: ret i32 %[[lnot_ext]]
581int test_not_local_ptr(local char* p) {
582 return !p;
583}
584
585
Yaxun Liu402804b2016-12-15 08:09:08 +0000586// CHECK-LABEL: test_and_ptr
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000587// CHECK: %[[tobool:.*]] = icmp ne i8* %p1, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000588// CHECK: %[[tobool1:.*]] = icmp ne i8 addrspace(3)* %p2, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*)
589// CHECK: %[[res:.*]] = and i1 %[[tobool]], %[[tobool1]]
590// CHECK: %[[land_ext:.*]] = zext i1 %[[res]] to i32
591// CHECK: ret i32 %[[land_ext]]
592int test_and_ptr(private char* p1, local char* p2) {
593 return p1 && p2;
594}
595
596// Test folding of null pointer in function scope.
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000597// NOOPT-LABEL: test_fold_private
Yaxun Liu402804b2016-12-15 08:09:08 +0000598// NOOPT: call void @test_fold_callee
599// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)** %glob, align 4
600// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
601// NOOPT: call void @test_fold_callee
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000602// NOOPT: %{{.*}} = add nsw i64 %{{.*}}, 0
Yaxun Liu402804b2016-12-15 08:09:08 +0000603// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
604void test_fold_callee(void);
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000605void test_fold_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000606 global int* glob = (test_fold_callee(), (global int*)(generic char*)0);
607 long x = glob - (global int*)(generic char*)0;
608 x = x + (int)(test_fold_callee(), (private int*)(generic char*)(global short*)0);
609 x = x - (int)((private int*)0 == (private int*)(generic char*)0);
610}
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000611
612// NOOPT-LABEL: test_fold_local
613// NOOPT: call void @test_fold_callee
614// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)** %glob, align 4
615// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
616// NOOPT: call void @test_fold_callee
617// NOOPT: %{{.*}} = add nsw i64 %{{.*}}, sext (i32 ptrtoint (i32 addrspace(3)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(3)*) to i32) to i64)
618// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
619void test_fold_local(void) {
620 global int* glob = (test_fold_callee(), (global int*)(generic char*)0);
621 long x = glob - (global int*)(generic char*)0;
622 x = x + (int)(test_fold_callee(), (local int*)(generic char*)(global short*)0);
623 x = x - (int)((local int*)0 == (local int*)(generic char*)0);
624}