blob: ba34d168bf790586a092499de22d2b88b184866a [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
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +00004// RUN: %clang_cc1 %s -cl-std=CL2.0 -include opencl-c.h -triple amdgcn -fcommon -emit-llvm -o - | FileCheck %s --check-prefix=COMMON
Yaxun Liu402804b2016-12-15 08:09:08 +00005
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
Yaxun Liu402804b2016-12-15 08:09:08 +000020// Test 0 as initializer.
21
Yaxun Liuf5f45e52018-02-02 16:08:24 +000022// CHECK: @private_p = local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000023private char *private_p = 0;
24
Yaxun Liuf5f45e52018-02-02 16:08:24 +000025// 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 +000026local char *local_p = 0;
27
Yaxun Liu25d1b432017-07-05 04:58:24 +000028// CHECK: @global_p = local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000029global char *global_p = 0;
30
Yaxun Liu651bd732018-02-13 18:01:21 +000031// CHECK: @constant_p = local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000032constant char *constant_p = 0;
33
Yaxun Liuf5f45e52018-02-02 16:08:24 +000034// CHECK: @generic_p = local_unnamed_addr addrspace(1) global i8* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000035generic char *generic_p = 0;
36
37// Test NULL as initializer.
38
Yaxun Liuf5f45e52018-02-02 16:08:24 +000039// CHECK: @private_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000040private char *private_p_NULL = NULL;
41
Yaxun Liuf5f45e52018-02-02 16:08:24 +000042// 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 +000043local char *local_p_NULL = NULL;
44
Yaxun Liu25d1b432017-07-05 04:58:24 +000045// CHECK: @global_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000046global char *global_p_NULL = NULL;
47
Yaxun Liu651bd732018-02-13 18:01:21 +000048// CHECK: @constant_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000049constant char *constant_p_NULL = NULL;
50
Yaxun Liuf5f45e52018-02-02 16:08:24 +000051// CHECK: @generic_p_NULL = local_unnamed_addr addrspace(1) global i8* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000052generic 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
Yaxun Liuf5f45e52018-02-02 16:08:24 +000057// CHECK: @fold_generic = local_unnamed_addr addrspace(1) global i32* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +000058generic int *fold_generic = (global int*)(generic float*)(private char*)0;
59
Yaxun Liuf5f45e52018-02-02 16:08:24 +000060// CHECK: @fold_priv = local_unnamed_addr addrspace(1) global i16 addrspace(5)* null, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000061private short *fold_priv = (private short*)(generic int*)(global void*)0;
62
Yaxun Liuf5f45e52018-02-02 16:08:24 +000063// 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 +000064private char *fold_priv_arith = (private char*)0 + 10;
65
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000066// CHECK: @fold_int = local_unnamed_addr addrspace(1) global i32 14, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000067int fold_int = (int)(private void*)(generic char*)(global int*)0 + 14;
68
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000069// CHECK: @fold_int2 = local_unnamed_addr addrspace(1) global i32 13, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000070int fold_int2 = (int) ((private void*)0 + 13);
71
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000072// CHECK: @fold_int3 = local_unnamed_addr addrspace(1) global i32 0, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000073int fold_int3 = (int) ((private int*)0);
74
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000075// CHECK: @fold_int4 = local_unnamed_addr addrspace(1) global i32 8, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000076int fold_int4 = (int) &((private int*)0)[2];
77
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000078// CHECK: @fold_int5 = local_unnamed_addr addrspace(1) global i32 4, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000079int fold_int5 = (int) &((private StructTy1*)0)->p2;
80
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000081
82// CHECK: @fold_int_local = local_unnamed_addr addrspace(1) global i32 13, align 4
83int fold_int_local = (int)(local void*)(generic char*)(global int*)0 + 14;
84
85// CHECK: @fold_int2_local = local_unnamed_addr addrspace(1) global i32 12, align 4
86int fold_int2_local = (int) ((local void*)0 + 13);
87
88// CHECK: @fold_int3_local = local_unnamed_addr addrspace(1) global i32 -1, align 4
89int fold_int3_local = (int) ((local int*)0);
90
91// CHECK: @fold_int4_local = local_unnamed_addr addrspace(1) global i32 7, align 4
92int fold_int4_local = (int) &((local int*)0)[2];
93
94// CHECK: @fold_int5_local = local_unnamed_addr addrspace(1) global i32 3, align 4
95int fold_int5_local = (int) &((local StructTy1*)0)->p2;
96
97
Yaxun Liu402804b2016-12-15 08:09:08 +000098// Test static variable initialization.
99
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000100// NOOPT: @test_static_var_private.sp1 = internal addrspace(1) global i8 addrspace(5)* null, align 4
101// NOOPT: @test_static_var_private.sp2 = internal addrspace(1) global i8 addrspace(5)* null, align 4
102// NOOPT: @test_static_var_private.sp3 = internal addrspace(1) global i8 addrspace(5)* null, align 4
103// NOOPT: @test_static_var_private.sp4 = internal addrspace(1) global i8 addrspace(5)* null, align 4
104// NOOPT: @test_static_var_private.sp5 = internal addrspace(1) global i8 addrspace(5)* null, align 4
Yaxun Liu651bd732018-02-13 18:01:21 +0000105// 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 +0000106// NOOPT: @test_static_var_private.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000107
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000108void test_static_var_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000109 static private char *sp1 = 0;
110 static private char *sp2 = NULL;
111 static private char *sp3;
112 static private char *sp4 = (private char*)((void)0, 0);
113 const int x = 0;
114 static private char *sp5 = (private char*)x;
115 static StructTy1 SS1;
116 static StructTy2 SS2;
117}
118
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000119// NOOPT: @test_static_var_local.sp1 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
120// NOOPT: @test_static_var_local.sp2 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
121// 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 +0000122// NOOPT: @test_static_var_local.sp4 = internal addrspace(1) global i8 addrspace(3)* null, align 4
123// NOOPT: @test_static_var_local.sp5 = internal addrspace(1) global i8 addrspace(3)* null, align 4
Yaxun Liu651bd732018-02-13 18:01:21 +0000124// 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 +0000125// NOOPT: @test_static_var_local.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000126void test_static_var_local(void) {
127 static local char *sp1 = 0;
128 static local char *sp2 = NULL;
129 static local char *sp3;
130 static local char *sp4 = (local char*)((void)0, 0);
131 const int x = 0;
132 static local char *sp5 = (local char*)x;
133 static StructTy1 SS1;
134 static StructTy2 SS2;
135}
136
Yaxun Liu402804b2016-12-15 08:09:08 +0000137// Test function-scope variable initialization.
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000138// NOOPT-LABEL: @test_func_scope_var_private(
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000139// NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp1, align 4
140// NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp2, align 4
141// NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp3, align 4
142// NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp4, align 4
143// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1 addrspace(5)* %SS1 to i8 addrspace(5)*
JF Bastien3a881e62018-11-15 00:19:18 +0000144// 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 +0000145// NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2 addrspace(5)* %SS2 to i8 addrspace(5)*
146// 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 +0000147void test_func_scope_var_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000148 private char *sp1 = 0;
149 private char *sp2 = NULL;
150 private char *sp3 = (private char*)((void)0, 0);
151 const int x = 0;
152 private char *sp4 = (private char*)x;
153 StructTy1 SS1 = {0, 0, 0, 0, 0};
154 StructTy2 SS2 = {0, 0, 0};
155}
156
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000157// Test function-scope variable initialization.
158// NOOPT-LABEL: @test_func_scope_var_local(
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000159// NOOPT: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(5)* %sp1, align 4
160// NOOPT: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(5)* %sp2, align 4
161// NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)* addrspace(5)* %sp3, align 4
162// NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)* addrspace(5)* %sp4, align 4
163// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1 addrspace(5)* %SS1 to i8 addrspace(5)*
JF Bastien3a881e62018-11-15 00:19:18 +0000164// 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 +0000165// NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2 addrspace(5)* %SS2 to i8 addrspace(5)*
166// 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 +0000167void test_func_scope_var_local(void) {
168 local char *sp1 = 0;
169 local char *sp2 = NULL;
170 local char *sp3 = (local char*)((void)0, 0);
171 const int x = 0;
172 local char *sp4 = (local char*)x;
173 StructTy1 SS1 = {0, 0, 0, 0, 0};
174 StructTy2 SS2 = {0, 0, 0};
175}
176
177
Yaxun Liu402804b2016-12-15 08:09:08 +0000178// Test default initialization of pointers.
179
180// Tentative definition of global variables with non-zero initializer
181// cannot have common linkage since common linkage requires zero initialization
182// and does not have explicit section.
183
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000184// CHECK: @p1 = local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4
185// COMMON: @p1 = common local_unnamed_addr addrspace(1) global i8 addrspace(5)* null, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +0000186private char *p1;
187
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000188// CHECK: @p2 = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
189// COMMON: @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
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000192// CHECK: @p3 = local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
193// COMMON: @p3 = common local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000194constant char *p3;
195
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000196// CHECK: @p4 = local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
197// COMMON: @p4 = common local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000198global char *p4;
199
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000200// CHECK: @p5 = local_unnamed_addr addrspace(1) global i8* null, align 8
201// COMMON: @p5 = common local_unnamed_addr addrspace(1) global i8* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000202generic char *p5;
203
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +0000204// Test default initialization of structure.
Yaxun Liu402804b2016-12-15 08:09:08 +0000205
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000206// CHECK: @S1 = 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 +0000207StructTy1 S1;
208
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000209// CHECK: @S2 = local_unnamed_addr addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000210StructTy2 S2;
211
212// Test default initialization of array.
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000213// CHECK: @A1 = 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 +0000214StructTy1 A1[2];
215
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000216// CHECK: @A2 = local_unnamed_addr addrspace(1) global [2 x %struct.StructTy2] zeroinitializer, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000217StructTy2 A2[2];
218
219// Test comparison with 0.
220
221// CHECK-LABEL: cmp_private
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000222// CHECK: icmp eq i8 addrspace(5)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000223void cmp_private(private char* p) {
224 if (p != 0)
225 *p = 0;
226}
227
228// CHECK-LABEL: cmp_local
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000229// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000230void cmp_local(local char* p) {
231 if (p != 0)
232 *p = 0;
233}
234
235// CHECK-LABEL: cmp_global
236// CHECK: icmp eq i8 addrspace(1)* %p, null
237void cmp_global(global char* p) {
238 if (p != 0)
239 *p = 0;
240}
241
242// CHECK-LABEL: cmp_constant
Yaxun Liu651bd732018-02-13 18:01:21 +0000243// CHECK: icmp eq i8 addrspace(4)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000244char cmp_constant(constant char* p) {
245 if (p != 0)
246 return *p;
247 else
248 return 0;
249}
250
251// CHECK-LABEL: cmp_generic
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000252// CHECK: icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000253void cmp_generic(generic char* p) {
254 if (p != 0)
255 *p = 0;
256}
257
258// Test comparison with NULL.
259
260// CHECK-LABEL: cmp_NULL_private
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000261// CHECK: icmp eq i8 addrspace(5)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000262void cmp_NULL_private(private char* p) {
263 if (p != NULL)
264 *p = 0;
265}
266
267// CHECK-LABEL: cmp_NULL_local
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000268// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000269void cmp_NULL_local(local char* p) {
270 if (p != NULL)
271 *p = 0;
272}
273
274// CHECK-LABEL: cmp_NULL_global
275// CHECK: icmp eq i8 addrspace(1)* %p, null
276void cmp_NULL_global(global char* p) {
277 if (p != NULL)
278 *p = 0;
279}
280
281// CHECK-LABEL: cmp_NULL_constant
Yaxun Liu651bd732018-02-13 18:01:21 +0000282// CHECK: icmp eq i8 addrspace(4)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000283char cmp_NULL_constant(constant char* p) {
284 if (p != NULL)
285 return *p;
286 else
287 return 0;
288}
289
290// CHECK-LABEL: cmp_NULL_generic
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000291// CHECK: icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000292void cmp_NULL_generic(generic char* p) {
293 if (p != NULL)
294 *p = 0;
295}
296
297// Test storage 0 as null pointer.
298// CHECK-LABEL: test_storage_null_pointer
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000299// CHECK: store i8 addrspace(5)* null, i8 addrspace(5)** %arg_private
300// CHECK: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)** %arg_local
301// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)** %arg_global
Yaxun Liu651bd732018-02-13 18:01:21 +0000302// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)** %arg_constant
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000303// CHECK: store i8* null, i8** %arg_generic
Yaxun Liu402804b2016-12-15 08:09:08 +0000304void test_storage_null_pointer(private char** arg_private,
305 local char** arg_local,
306 global char** arg_global,
307 constant char** arg_constant,
308 generic char** arg_generic) {
309 *arg_private = 0;
310 *arg_local = 0;
311 *arg_global = 0;
312 *arg_constant = 0;
313 *arg_generic = 0;
314}
315
316// Test storage NULL as null pointer.
317// CHECK-LABEL: test_storage_null_pointer_NULL
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000318// CHECK: store i8 addrspace(5)* null, i8 addrspace(5)** %arg_private
319// CHECK: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)** %arg_local
320// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)** %arg_global
Yaxun Liu651bd732018-02-13 18:01:21 +0000321// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)** %arg_constant
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000322// CHECK: store i8* null, i8** %arg_generic
Yaxun Liu402804b2016-12-15 08:09:08 +0000323void test_storage_null_pointer_NULL(private char** arg_private,
324 local char** arg_local,
325 global char** arg_global,
326 constant char** arg_constant,
327 generic char** arg_generic) {
328 *arg_private = NULL;
329 *arg_local = NULL;
330 *arg_global = NULL;
331 *arg_constant = NULL;
332 *arg_generic = NULL;
333}
334
335// Test pass null pointer to function as argument.
336void test_pass_null_pointer_arg_calee(private char* arg_private,
337 local char* arg_local,
338 global char* arg_global,
339 constant char* arg_constant,
340 generic char* arg_generic);
341
342// CHECK-LABEL: test_pass_null_pointer_arg
Yaxun Liu651bd732018-02-13 18:01:21 +0000343// 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)
344// 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 +0000345void test_pass_null_pointer_arg(void) {
346 test_pass_null_pointer_arg_calee(0, 0, 0, 0, 0);
347 test_pass_null_pointer_arg_calee(NULL, NULL, NULL, NULL, NULL);
348}
349
350// Test cast null pointer to size_t.
351void test_cast_null_pointer_to_sizet_calee(size_t arg_private,
352 size_t arg_local,
353 size_t arg_global,
354 size_t arg_constant,
355 size_t arg_generic);
356
357// CHECK-LABEL: test_cast_null_pointer_to_sizet
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000358// 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)
359// 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 +0000360void test_cast_null_pointer_to_sizet(void) {
361 test_cast_null_pointer_to_sizet_calee((size_t)((private char*)0),
362 (size_t)((local char*)0),
363 (size_t)((global char*)0),
364 (size_t)((constant char*)0),
365 (size_t)((generic char*)0));
366 test_cast_null_pointer_to_sizet_calee((size_t)((private char*)NULL),
367 (size_t)((local char*)NULL),
368 (size_t)((global char*)NULL),
369 (size_t)((constant char*)0), // NULL cannot be casted to constant pointer since it is defined as a generic pointer
370 (size_t)((generic char*)NULL));
371}
372
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +0000373// Test comparison between null pointers.
Yaxun Liu402804b2016-12-15 08:09:08 +0000374#define TEST_EQ00(addr1, addr2) int test_eq00_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)0; }
375#define TEST_EQ0N(addr1, addr2) int test_eq0N_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; }
376#define TEST_EQN0(addr1, addr2) int test_eqN0_##addr1##_##addr2(void) { return (addr1 char*)NULL == (addr2 char*)0; }
377#define TEST_EQNN(addr1, addr2) int test_eqNN_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; }
378#define TEST_NE00(addr1, addr2) int test_ne00_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)0; }
379#define TEST_NE0N(addr1, addr2) int test_ne0N_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; }
380#define TEST_NEN0(addr1, addr2) int test_neN0_##addr1##_##addr2(void) { return (addr1 char*)NULL != (addr2 char*)0; }
381#define TEST_NENN(addr1, addr2) int test_neNN_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; }
382#define TEST(addr1, addr2) \
383 TEST_EQ00(addr1, addr2) \
384 TEST_EQ0N(addr1, addr2) \
385 TEST_EQN0(addr1, addr2) \
386 TEST_EQNN(addr1, addr2) \
387 TEST_NE00(addr1, addr2) \
388 TEST_NE0N(addr1, addr2) \
389 TEST_NEN0(addr1, addr2) \
390 TEST_NENN(addr1, addr2)
391
392// CHECK-LABEL: test_eq00_generic_private
393// CHECK: ret i32 1
394// CHECK-LABEL: test_eq0N_generic_private
395// CHECK: ret i32 1
396// CHECK-LABEL: test_eqN0_generic_private
397// CHECK: ret i32 1
398// CHECK-LABEL: test_eqNN_generic_private
399// CHECK: ret i32 1
400// CHECK-LABEL: test_ne00_generic_private
401// CHECK: ret i32 0
402// CHECK-LABEL: test_ne0N_generic_private
403// CHECK: ret i32 0
404// CHECK-LABEL: test_neN0_generic_private
405// CHECK: ret i32 0
406// CHECK-LABEL: test_neNN_generic_private
407// CHECK: ret i32 0
408TEST(generic, private)
409
410// CHECK-LABEL: test_eq00_generic_local
411// CHECK: ret i32 1
412// CHECK-LABEL: test_eq0N_generic_local
413// CHECK: ret i32 1
414// CHECK-LABEL: test_eqN0_generic_local
415// CHECK: ret i32 1
416// CHECK-LABEL: test_eqNN_generic_local
417// CHECK: ret i32 1
418// CHECK-LABEL: test_ne00_generic_local
419// CHECK: ret i32 0
420// CHECK-LABEL: test_ne0N_generic_local
421// CHECK: ret i32 0
422// CHECK-LABEL: test_neN0_generic_local
423// CHECK: ret i32 0
424// CHECK-LABEL: test_neNN_generic_local
425// CHECK: ret i32 0
426TEST(generic, local)
427
428// CHECK-LABEL: test_eq00_generic_global
429// CHECK: ret i32 1
430// CHECK-LABEL: test_eq0N_generic_global
431// CHECK: ret i32 1
432// CHECK-LABEL: test_eqN0_generic_global
433// CHECK: ret i32 1
434// CHECK-LABEL: test_eqNN_generic_global
435// CHECK: ret i32 1
436// CHECK-LABEL: test_ne00_generic_global
437// CHECK: ret i32 0
438// CHECK-LABEL: test_ne0N_generic_global
439// CHECK: ret i32 0
440// CHECK-LABEL: test_neN0_generic_global
441// CHECK: ret i32 0
442// CHECK-LABEL: test_neNN_generic_global
443// CHECK: ret i32 0
444TEST(generic, global)
445
446// CHECK-LABEL: test_eq00_generic_generic
447// CHECK: ret i32 1
448// CHECK-LABEL: test_eq0N_generic_generic
449// CHECK: ret i32 1
450// CHECK-LABEL: test_eqN0_generic_generic
451// CHECK: ret i32 1
452// CHECK-LABEL: test_eqNN_generic_generic
453// CHECK: ret i32 1
454// CHECK-LABEL: test_ne00_generic_generic
455// CHECK: ret i32 0
456// CHECK-LABEL: test_ne0N_generic_generic
457// CHECK: ret i32 0
458// CHECK-LABEL: test_neN0_generic_generic
459// CHECK: ret i32 0
460// CHECK-LABEL: test_neNN_generic_generic
461// CHECK: ret i32 0
462TEST(generic, generic)
463
464// CHECK-LABEL: test_eq00_constant_constant
465// CHECK: ret i32 1
466TEST_EQ00(constant, constant)
467
468// Test cast to bool.
469
470// CHECK-LABEL: cast_bool_private
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000471// CHECK: icmp eq i8 addrspace(5)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000472void cast_bool_private(private char* p) {
473 if (p)
474 *p = 0;
475}
476
477// CHECK-LABEL: cast_bool_local
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000478// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000479void cast_bool_local(local char* p) {
480 if (p)
481 *p = 0;
482}
483
484// CHECK-LABEL: cast_bool_global
485// CHECK: icmp eq i8 addrspace(1)* %p, null
486void cast_bool_global(global char* p) {
487 if (p)
488 *p = 0;
489}
490
491// CHECK-LABEL: cast_bool_constant
Yaxun Liu651bd732018-02-13 18:01:21 +0000492// CHECK: icmp eq i8 addrspace(4)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000493char cast_bool_constant(constant char* p) {
494 if (p)
495 return *p;
496 else
497 return 0;
498}
499
500// CHECK-LABEL: cast_bool_generic
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000501// CHECK: icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000502void cast_bool_generic(generic char* p) {
503 if (p)
504 *p = 0;
505}
506
507// Test initialize a struct using memset.
508// For large structures which is mostly zero, clang generats llvm.memset for
509// the zero part and store for non-zero members.
510typedef struct {
511 long a, b, c, d;
512 private char *p;
513} StructTy3;
514
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000515// CHECK-LABEL: test_memset_private
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000516// 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 +0000517void test_memset_private(private StructTy3 *ptr) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000518 StructTy3 S3 = {0, 0, 0, 0, 0};
Matt Arsenault3fe73952017-08-09 21:44:58 +0000519 *ptr = S3;
Yaxun Liu402804b2016-12-15 08:09:08 +0000520}
521
522// Test casting literal 0 to pointer.
523// A 0 literal casted to pointer should become a null pointer.
524
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000525// CHECK-LABEL: test_cast_0_to_local_ptr
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000526// CHECK: ret i32 addrspace(3)* addrspacecast (i32* null to i32 addrspace(3)*)
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000527local int* test_cast_0_to_local_ptr(void) {
528 return (local int*)0;
529}
530
531// CHECK-LABEL: test_cast_0_to_private_ptr
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000532// CHECK: ret i32 addrspace(5)* null
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000533private int* test_cast_0_to_private_ptr(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000534 return (private int*)0;
535}
536
537// Test casting non-literal integer with 0 value to pointer.
538// A non-literal integer expression with 0 value is casted to a pointer with
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000539// zero value.
Yaxun Liu402804b2016-12-15 08:09:08 +0000540
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000541// CHECK-LABEL: test_cast_int_to_ptr1_private
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000542// CHECK: ret i32 addrspace(5)* null
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000543private int* test_cast_int_to_ptr1_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000544 return (private int*)((void)0, 0);
545}
546
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000547// CHECK-LABEL: test_cast_int_to_ptr1_local
548 // CHECK: ret i32 addrspace(3)* null
549local int* test_cast_int_to_ptr1_local(void) {
550 return (local int*)((void)0, 0);
551}
552
Yaxun Liu402804b2016-12-15 08:09:08 +0000553// CHECK-LABEL: test_cast_int_to_ptr2
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000554// CHECK: ret i32 addrspace(5)* null
Yaxun Liu402804b2016-12-15 08:09:08 +0000555private int* test_cast_int_to_ptr2(void) {
556 int x = 0;
557 return (private int*)x;
558}
559
560// Test logical operations.
561// CHECK-LABEL: test_not_nullptr
562// CHECK: ret i32 1
563int test_not_nullptr(void) {
564 return !(private char*)NULL;
565}
566
567// CHECK-LABEL: test_and_nullptr
568// CHECK: ret i32 0
569int test_and_nullptr(int a) {
570 return a && ((private char*)NULL);
571}
572
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000573// CHECK-LABEL: test_not_private_ptr
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000574// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(5)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000575// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
576// CHECK: ret i32 %[[lnot_ext]]
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000577int test_not_private_ptr(private char* p) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000578 return !p;
579}
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000580
581// CHECK-LABEL: test_not_local_ptr
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000582// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000583// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
584// CHECK: ret i32 %[[lnot_ext]]
585int test_not_local_ptr(local char* p) {
586 return !p;
587}
588
589
Yaxun Liu402804b2016-12-15 08:09:08 +0000590// CHECK-LABEL: test_and_ptr
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000591// CHECK: %[[tobool:.*]] = icmp ne i8 addrspace(5)* %p1, null
592// CHECK: %[[tobool1:.*]] = icmp ne i8 addrspace(3)* %p2, addrspacecast (i8* null to i8 addrspace(3)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000593// CHECK: %[[res:.*]] = and i1 %[[tobool]], %[[tobool1]]
594// CHECK: %[[land_ext:.*]] = zext i1 %[[res]] to i32
595// CHECK: ret i32 %[[land_ext]]
596int test_and_ptr(private char* p1, local char* p2) {
597 return p1 && p2;
598}
599
600// Test folding of null pointer in function scope.
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000601// NOOPT-LABEL: test_fold_private
Yaxun Liu402804b2016-12-15 08:09:08 +0000602// NOOPT: call void @test_fold_callee
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000603// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)* addrspace(5)* %glob, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000604// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
605// NOOPT: call void @test_fold_callee
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000606// NOOPT: %{{.*}} = add nsw i64 %{{.*}}, 0
Yaxun Liu402804b2016-12-15 08:09:08 +0000607// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
608void test_fold_callee(void);
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000609void test_fold_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000610 global int* glob = (test_fold_callee(), (global int*)(generic char*)0);
611 long x = glob - (global int*)(generic char*)0;
612 x = x + (int)(test_fold_callee(), (private int*)(generic char*)(global short*)0);
613 x = x - (int)((private int*)0 == (private int*)(generic char*)0);
614}
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000615
616// NOOPT-LABEL: test_fold_local
617// NOOPT: call void @test_fold_callee
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000618// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)* addrspace(5)* %glob, align 8
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000619// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
620// NOOPT: call void @test_fold_callee
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000621// 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 +0000622// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
623void test_fold_local(void) {
624 global int* glob = (test_fold_callee(), (global int*)(generic char*)0);
625 long x = glob - (global int*)(generic char*)0;
626 x = x + (int)(test_fold_callee(), (local int*)(generic char*)(global short*)0);
627 x = x - (int)((local int*)0 == (local int*)(generic char*)0);
628}