blob: c7c77920b7756c8a66b0b5c31e719fe5967e2ea7 [file] [log] [blame]
Yaxun Liuaf3d4db2017-05-23 16:15:53 +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
Yaxun Liu6d96f1632017-05-18 18:51:09 +00003// RUN: %clang_cc1 %s -cl-std=CL2.0 -include opencl-c.h -triple amdgcn---opencl -emit-llvm -o - | FileCheck %s
Yaxun Liu402804b2016-12-15 08:09:08 +00004
5typedef struct {
6 private char *p1;
7 local char *p2;
8 constant char *p3;
9 global char *p4;
10 generic char *p5;
11} StructTy1;
12
13typedef 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
Yaxun Liuf5f45e52018-02-02 16:08:24 +000024// CHECK: @private_p = local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000025private char *private_p = 0;
26
Yaxun Liuf5f45e52018-02-02 16:08:24 +000027// CHECK: @local_p = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000028local char *local_p = 0;
29
Yaxun Liu25d1b432017-07-05 04:58:24 +000030// CHECK: @global_p = local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000031global char *global_p = 0;
32
Yaxun Liu651bd732018-02-13 18:01:21 +000033// CHECK: @constant_p = local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000034constant char *constant_p = 0;
35
Yaxun Liuf5f45e52018-02-02 16:08:24 +000036// CHECK: @generic_p = local_unnamed_addr addrspace(1) global i8* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000037generic char *generic_p = 0;
38
39// Test NULL as initializer.
40
Yaxun Liuf5f45e52018-02-02 16:08:24 +000041// CHECK: @private_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000042private char *private_p_NULL = NULL;
43
Yaxun Liuf5f45e52018-02-02 16:08:24 +000044// CHECK: @local_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000045local char *local_p_NULL = NULL;
46
Yaxun Liu25d1b432017-07-05 04:58:24 +000047// CHECK: @global_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000048global char *global_p_NULL = NULL;
49
Yaxun Liu651bd732018-02-13 18:01:21 +000050// CHECK: @constant_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000051constant char *constant_p_NULL = NULL;
52
Yaxun Liuf5f45e52018-02-02 16:08:24 +000053// CHECK: @generic_p_NULL = local_unnamed_addr addrspace(1) global i8* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000054generic 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
Yaxun Liuf5f45e52018-02-02 16:08:24 +000059// CHECK: @fold_generic = local_unnamed_addr addrspace(1) global i32* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000060generic int *fold_generic = (global int*)(generic float*)(private char*)0;
61
Yaxun Liuf5f45e52018-02-02 16:08:24 +000062// CHECK: @fold_priv = local_unnamed_addr addrspace(1) global i16 addrspace(5)* null, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000063private short *fold_priv = (private short*)(generic int*)(global void*)0;
64
Yaxun Liuf5f45e52018-02-02 16:08:24 +000065// CHECK: @fold_priv_arith = local_unnamed_addr addrspace(1) global i8 addrspace(5)* inttoptr (i32 10 to i8 addrspace(5)*), align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000066private char *fold_priv_arith = (private char*)0 + 10;
67
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000068// CHECK: @fold_int = local_unnamed_addr addrspace(1) global i32 14, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000069int fold_int = (int)(private void*)(generic char*)(global int*)0 + 14;
70
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000071// CHECK: @fold_int2 = local_unnamed_addr addrspace(1) global i32 13, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000072int fold_int2 = (int) ((private void*)0 + 13);
73
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000074// CHECK: @fold_int3 = local_unnamed_addr addrspace(1) global i32 0, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000075int fold_int3 = (int) ((private int*)0);
76
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000077// CHECK: @fold_int4 = local_unnamed_addr addrspace(1) global i32 8, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000078int fold_int4 = (int) &((private int*)0)[2];
79
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000080// CHECK: @fold_int5 = local_unnamed_addr addrspace(1) global i32 4, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000081int fold_int5 = (int) &((private StructTy1*)0)->p2;
82
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000083
84// CHECK: @fold_int_local = local_unnamed_addr addrspace(1) global i32 13, align 4
85int 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
88int fold_int2_local = (int) ((local void*)0 + 13);
89
90// CHECK: @fold_int3_local = local_unnamed_addr addrspace(1) global i32 -1, align 4
91int fold_int3_local = (int) ((local int*)0);
92
93// CHECK: @fold_int4_local = local_unnamed_addr addrspace(1) global i32 7, align 4
94int fold_int4_local = (int) &((local int*)0)[2];
95
96// CHECK: @fold_int5_local = local_unnamed_addr addrspace(1) global i32 3, align 4
97int fold_int5_local = (int) &((local StructTy1*)0)->p2;
98
99
Yaxun Liu402804b2016-12-15 08:09:08 +0000100// Test static variable initialization.
101
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000102// 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
Yaxun Liu651bd732018-02-13 18:01:21 +0000107// 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
Yaxun Liu25d1b432017-07-05 04:58:24 +0000108// NOOPT: @test_static_var_private.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000109
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000110void test_static_var_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000111 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
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000121// 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
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000124// 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
Yaxun Liu651bd732018-02-13 18:01:21 +0000126// 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
Yaxun Liu25d1b432017-07-05 04:58:24 +0000127// NOOPT: @test_static_var_local.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000128void 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
Yaxun Liu402804b2016-12-15 08:09:08 +0000139// Test function-scope variable initialization.
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000140// NOOPT-LABEL: @test_func_scope_var_private(
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000141// 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)*
JF Bastien3a881e62018-11-15 00:19:18 +0000146// 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)
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000147// 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)
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000149void test_func_scope_var_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000150 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
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000159// Test function-scope variable initialization.
160// NOOPT-LABEL: @test_func_scope_var_local(
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000161// 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)*
JF Bastien3a881e62018-11-15 00:19:18 +0000166// 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)
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000167// 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)
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000169void 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
Yaxun Liu402804b2016-12-15 08:09:08 +0000180// 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
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000186// CHECK: @p1 = common local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +0000187private char *p1;
188
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000189// CHECK: @p2 = weak local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
Yaxun Liu402804b2016-12-15 08:09:08 +0000190local char *p2;
191
Yaxun Liu651bd732018-02-13 18:01:21 +0000192// CHECK: @p3 = common local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000193constant char *p3;
194
Yaxun Liu25d1b432017-07-05 04:58:24 +0000195// CHECK: @p4 = common local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000196global char *p4;
197
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000198// CHECK: @p5 = common local_unnamed_addr addrspace(1) global i8* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000199generic char *p5;
200
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +0000201// Test default initialization of structure.
Yaxun Liu402804b2016-12-15 08:09:08 +0000202
Yaxun Liu651bd732018-02-13 18:01:21 +0000203// 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
Yaxun Liu402804b2016-12-15 08:09:08 +0000204StructTy1 S1;
205
Yaxun Liu25d1b432017-07-05 04:58:24 +0000206// CHECK: @S2 = common local_unnamed_addr addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000207StructTy2 S2;
208
209// Test default initialization of array.
Yaxun Liu651bd732018-02-13 18:01:21 +0000210// 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
Yaxun Liu402804b2016-12-15 08:09:08 +0000211StructTy1 A1[2];
212
Yaxun Liu25d1b432017-07-05 04:58:24 +0000213// CHECK: @A2 = common local_unnamed_addr addrspace(1) global [2 x %struct.StructTy2] zeroinitializer, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000214StructTy2 A2[2];
215
216// Test comparison with 0.
217
218// CHECK-LABEL: cmp_private
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000219// CHECK: icmp eq i8 addrspace(5)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000220void cmp_private(private char* p) {
221 if (p != 0)
222 *p = 0;
223}
224
225// CHECK-LABEL: cmp_local
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000226// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000227void 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
234void cmp_global(global char* p) {
235 if (p != 0)
236 *p = 0;
237}
238
239// CHECK-LABEL: cmp_constant
Yaxun Liu651bd732018-02-13 18:01:21 +0000240// CHECK: icmp eq i8 addrspace(4)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000241char cmp_constant(constant char* p) {
242 if (p != 0)
243 return *p;
244 else
245 return 0;
246}
247
248// CHECK-LABEL: cmp_generic
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000249// CHECK: icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000250void 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
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000258// CHECK: icmp eq i8 addrspace(5)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000259void cmp_NULL_private(private char* p) {
260 if (p != NULL)
261 *p = 0;
262}
263
264// CHECK-LABEL: cmp_NULL_local
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000265// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000266void 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
273void cmp_NULL_global(global char* p) {
274 if (p != NULL)
275 *p = 0;
276}
277
278// CHECK-LABEL: cmp_NULL_constant
Yaxun Liu651bd732018-02-13 18:01:21 +0000279// CHECK: icmp eq i8 addrspace(4)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000280char 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
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000288// CHECK: icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000289void 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
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000296// 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
Yaxun Liu651bd732018-02-13 18:01:21 +0000299// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)** %arg_constant
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000300// CHECK: store i8* null, i8** %arg_generic
Yaxun Liu402804b2016-12-15 08:09:08 +0000301void 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
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000315// 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
Yaxun Liu651bd732018-02-13 18:01:21 +0000318// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)** %arg_constant
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000319// CHECK: store i8* null, i8** %arg_generic
Yaxun Liu402804b2016-12-15 08:09:08 +0000320void 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.
333void 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
Yaxun Liu651bd732018-02-13 18:01:21 +0000340// 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)
Yaxun Liu402804b2016-12-15 08:09:08 +0000342void 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.
348void 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
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000355// 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)
Yaxun Liu402804b2016-12-15 08:09:08 +0000357void 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
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +0000370// Test comparison between null pointers.
Yaxun Liu402804b2016-12-15 08:09:08 +0000371#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
405TEST(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
423TEST(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
441TEST(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
459TEST(generic, generic)
460
461// CHECK-LABEL: test_eq00_constant_constant
462// CHECK: ret i32 1
463TEST_EQ00(constant, constant)
464
465// Test cast to bool.
466
467// CHECK-LABEL: cast_bool_private
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000468// CHECK: icmp eq i8 addrspace(5)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000469void cast_bool_private(private char* p) {
470 if (p)
471 *p = 0;
472}
473
474// CHECK-LABEL: cast_bool_local
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000475// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000476void 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
483void cast_bool_global(global char* p) {
484 if (p)
485 *p = 0;
486}
487
488// CHECK-LABEL: cast_bool_constant
Yaxun Liu651bd732018-02-13 18:01:21 +0000489// CHECK: icmp eq i8 addrspace(4)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000490char 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
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000498// CHECK: icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000499void 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.
507typedef struct {
508 long a, b, c, d;
509 private char *p;
510} StructTy3;
511
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000512// CHECK-LABEL: test_memset_private
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000513// CHECK: call void @llvm.memset.p5i8.i64(i8 addrspace(5)* align 8 {{.*}}, i8 0, i64 40, i1 false)
Matt Arsenault3fe73952017-08-09 21:44:58 +0000514void test_memset_private(private StructTy3 *ptr) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000515 StructTy3 S3 = {0, 0, 0, 0, 0};
Matt Arsenault3fe73952017-08-09 21:44:58 +0000516 *ptr = S3;
Yaxun Liu402804b2016-12-15 08:09:08 +0000517}
518
519// Test casting literal 0 to pointer.
520// A 0 literal casted to pointer should become a null pointer.
521
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000522// CHECK-LABEL: test_cast_0_to_local_ptr
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000523// CHECK: ret i32 addrspace(3)* addrspacecast (i32* null to i32 addrspace(3)*)
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000524local int* test_cast_0_to_local_ptr(void) {
525 return (local int*)0;
526}
527
528// CHECK-LABEL: test_cast_0_to_private_ptr
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000529// CHECK: ret i32 addrspace(5)* null
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000530private int* test_cast_0_to_private_ptr(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000531 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
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000536// zero value.
Yaxun Liu402804b2016-12-15 08:09:08 +0000537
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000538// CHECK-LABEL: test_cast_int_to_ptr1_private
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000539// CHECK: ret i32 addrspace(5)* null
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000540private int* test_cast_int_to_ptr1_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000541 return (private int*)((void)0, 0);
542}
543
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000544// CHECK-LABEL: test_cast_int_to_ptr1_local
545 // CHECK: ret i32 addrspace(3)* null
546local int* test_cast_int_to_ptr1_local(void) {
547 return (local int*)((void)0, 0);
548}
549
Yaxun Liu402804b2016-12-15 08:09:08 +0000550// CHECK-LABEL: test_cast_int_to_ptr2
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000551// CHECK: ret i32 addrspace(5)* null
Yaxun Liu402804b2016-12-15 08:09:08 +0000552private 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
560int test_not_nullptr(void) {
561 return !(private char*)NULL;
562}
563
564// CHECK-LABEL: test_and_nullptr
565// CHECK: ret i32 0
566int test_and_nullptr(int a) {
567 return a && ((private char*)NULL);
568}
569
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000570// CHECK-LABEL: test_not_private_ptr
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000571// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(5)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000572// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
573// CHECK: ret i32 %[[lnot_ext]]
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000574int test_not_private_ptr(private char* p) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000575 return !p;
576}
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000577
578// CHECK-LABEL: test_not_local_ptr
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000579// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000580// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
581// CHECK: ret i32 %[[lnot_ext]]
582int test_not_local_ptr(local char* p) {
583 return !p;
584}
585
586
Yaxun Liu402804b2016-12-15 08:09:08 +0000587// CHECK-LABEL: test_and_ptr
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000588// 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)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000590// CHECK: %[[res:.*]] = and i1 %[[tobool]], %[[tobool1]]
591// CHECK: %[[land_ext:.*]] = zext i1 %[[res]] to i32
592// CHECK: ret i32 %[[land_ext]]
593int test_and_ptr(private char* p1, local char* p2) {
594 return p1 && p2;
595}
596
597// Test folding of null pointer in function scope.
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000598// NOOPT-LABEL: test_fold_private
Yaxun Liu402804b2016-12-15 08:09:08 +0000599// NOOPT: call void @test_fold_callee
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000600// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)* addrspace(5)* %glob, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000601// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
602// NOOPT: call void @test_fold_callee
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000603// NOOPT: %{{.*}} = add nsw i64 %{{.*}}, 0
Yaxun Liu402804b2016-12-15 08:09:08 +0000604// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
605void test_fold_callee(void);
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000606void test_fold_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000607 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}
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000612
613// NOOPT-LABEL: test_fold_local
614// NOOPT: call void @test_fold_callee
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000615// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)* addrspace(5)* %glob, align 8
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000616// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
617// NOOPT: call void @test_fold_callee
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000618// NOOPT: %{{.*}} = add nsw i64 %{{.*}}, sext (i32 ptrtoint (i32 addrspace(3)* addrspacecast (i32* null to i32 addrspace(3)*) to i32) to i64)
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000619// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
620void 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}