blob: ddf358c1188ea03caa11b9a6bc41c6bfff4fcf2b [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
Matt Arsenault301a6da2020-06-01 10:31:05 -040022// CHECK: @private_p = local_unnamed_addr addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), 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
Matt Arsenault301a6da2020-06-01 10:31:05 -040039// CHECK: @private_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), 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
Matt Arsenault301a6da2020-06-01 10:31:05 -040060// CHECK: @fold_priv = local_unnamed_addr addrspace(1) global i16 addrspace(5)* addrspacecast (i16* null to i16 addrspace(5)*), align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000061private short *fold_priv = (private short*)(generic int*)(global void*)0;
62
Matt Arsenault301a6da2020-06-01 10:31:05 -040063// CHECK: @fold_priv_arith = local_unnamed_addr addrspace(1) global i8 addrspace(5)* inttoptr (i32 9 to i8 addrspace(5)*), align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000064private char *fold_priv_arith = (private char*)0 + 10;
65
Matt Arsenault301a6da2020-06-01 10:31:05 -040066// CHECK: @fold_local_arith = local_unnamed_addr addrspace(1) global i8 addrspace(3)* inttoptr (i32 9 to i8 addrspace(3)*), align 4
67local char *fold_local_arith = (local char*)0 + 10;
68
69// CHECK: @fold_int = local_unnamed_addr addrspace(1) global i32 13, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000070int fold_int = (int)(private void*)(generic char*)(global int*)0 + 14;
71
Matt Arsenault301a6da2020-06-01 10:31:05 -040072// CHECK: @fold_int2 = local_unnamed_addr addrspace(1) global i32 12, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000073int fold_int2 = (int) ((private void*)0 + 13);
74
Matt Arsenault301a6da2020-06-01 10:31:05 -040075// CHECK: @fold_int3 = local_unnamed_addr addrspace(1) global i32 -1, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000076int fold_int3 = (int) ((private int*)0);
77
Matt Arsenault301a6da2020-06-01 10:31:05 -040078// CHECK: @fold_int4 = local_unnamed_addr addrspace(1) global i32 7, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000079int fold_int4 = (int) &((private int*)0)[2];
80
Matt Arsenault301a6da2020-06-01 10:31:05 -040081// CHECK: @fold_int5 = local_unnamed_addr addrspace(1) global i32 3, align 4
Yaxun Liu402804b2016-12-15 08:09:08 +000082int fold_int5 = (int) &((private StructTy1*)0)->p2;
83
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +000084
85// CHECK: @fold_int_local = local_unnamed_addr addrspace(1) global i32 13, align 4
86int fold_int_local = (int)(local void*)(generic char*)(global int*)0 + 14;
87
88// CHECK: @fold_int2_local = local_unnamed_addr addrspace(1) global i32 12, align 4
89int fold_int2_local = (int) ((local void*)0 + 13);
90
91// CHECK: @fold_int3_local = local_unnamed_addr addrspace(1) global i32 -1, align 4
92int fold_int3_local = (int) ((local int*)0);
93
94// CHECK: @fold_int4_local = local_unnamed_addr addrspace(1) global i32 7, align 4
95int fold_int4_local = (int) &((local int*)0)[2];
96
97// CHECK: @fold_int5_local = local_unnamed_addr addrspace(1) global i32 3, align 4
98int fold_int5_local = (int) &((local StructTy1*)0)->p2;
99
100
Yaxun Liu402804b2016-12-15 08:09:08 +0000101// Test static variable initialization.
102
Matt Arsenault301a6da2020-06-01 10:31:05 -0400103// NOOPT: @test_static_var_private.sp1 = internal addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
104// NOOPT: @test_static_var_private.sp2 = internal addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
105// NOOPT: @test_static_var_private.sp3 = internal addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000106// NOOPT: @test_static_var_private.sp4 = internal addrspace(1) global i8 addrspace(5)* null, align 4
107// NOOPT: @test_static_var_private.sp5 = internal addrspace(1) global i8 addrspace(5)* null, align 4
Matt Arsenault301a6da2020-06-01 10:31:05 -0400108// NOOPT: @test_static_var_private.SS1 = internal addrspace(1) global %struct.StructTy1 { i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), 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 +0000109// NOOPT: @test_static_var_private.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000110
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000111void test_static_var_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000112 static private char *sp1 = 0;
113 static private char *sp2 = NULL;
114 static private char *sp3;
115 static private char *sp4 = (private char*)((void)0, 0);
116 const int x = 0;
117 static private char *sp5 = (private char*)x;
118 static StructTy1 SS1;
119 static StructTy2 SS2;
120}
121
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000122// NOOPT: @test_static_var_local.sp1 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
123// NOOPT: @test_static_var_local.sp2 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
124// 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 +0000125// NOOPT: @test_static_var_local.sp4 = internal addrspace(1) global i8 addrspace(3)* null, align 4
126// NOOPT: @test_static_var_local.sp5 = internal addrspace(1) global i8 addrspace(3)* null, align 4
Matt Arsenault301a6da2020-06-01 10:31:05 -0400127// NOOPT: @test_static_var_local.SS1 = internal addrspace(1) global %struct.StructTy1 { i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), 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 +0000128// NOOPT: @test_static_var_local.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000129void test_static_var_local(void) {
130 static local char *sp1 = 0;
131 static local char *sp2 = NULL;
132 static local char *sp3;
133 static local char *sp4 = (local char*)((void)0, 0);
134 const int x = 0;
135 static local char *sp5 = (local char*)x;
136 static StructTy1 SS1;
137 static StructTy2 SS2;
138}
139
Yaxun Liu402804b2016-12-15 08:09:08 +0000140// Test function-scope variable initialization.
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000141// NOOPT-LABEL: @test_func_scope_var_private(
Matt Arsenault301a6da2020-06-01 10:31:05 -0400142// NOOPT: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)* addrspace(5)* %sp1, align 4
143// NOOPT: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)* addrspace(5)* %sp2, align 4
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000144// NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp3, align 4
145// NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp4, align 4
146// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1 addrspace(5)* %SS1 to i8 addrspace(5)*
JF Bastien3a881e62018-11-15 00:19:18 +0000147// 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 +0000148// NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2 addrspace(5)* %SS2 to i8 addrspace(5)*
149// 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 +0000150void test_func_scope_var_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000151 private char *sp1 = 0;
152 private char *sp2 = NULL;
153 private char *sp3 = (private char*)((void)0, 0);
154 const int x = 0;
155 private char *sp4 = (private char*)x;
156 StructTy1 SS1 = {0, 0, 0, 0, 0};
157 StructTy2 SS2 = {0, 0, 0};
158}
159
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000160// Test function-scope variable initialization.
161// NOOPT-LABEL: @test_func_scope_var_local(
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000162// NOOPT: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(5)* %sp1, align 4
163// NOOPT: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(5)* %sp2, align 4
164// NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)* addrspace(5)* %sp3, align 4
165// NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)* addrspace(5)* %sp4, align 4
166// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1 addrspace(5)* %SS1 to i8 addrspace(5)*
JF Bastien3a881e62018-11-15 00:19:18 +0000167// 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 +0000168// NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2 addrspace(5)* %SS2 to i8 addrspace(5)*
169// 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 +0000170void test_func_scope_var_local(void) {
171 local char *sp1 = 0;
172 local char *sp2 = NULL;
173 local char *sp3 = (local char*)((void)0, 0);
174 const int x = 0;
175 local char *sp4 = (local char*)x;
176 StructTy1 SS1 = {0, 0, 0, 0, 0};
177 StructTy2 SS2 = {0, 0, 0};
178}
179
180
Yaxun Liu402804b2016-12-15 08:09:08 +0000181// Test default initialization of pointers.
182
183// Tentative definition of global variables with non-zero initializer
184// cannot have common linkage since common linkage requires zero initialization
185// and does not have explicit section.
186
Matt Arsenault301a6da2020-06-01 10:31:05 -0400187// CHECK: @p1 = local_unnamed_addr addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
188// COMMON: @p1 = weak local_unnamed_addr addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
Yaxun Liu402804b2016-12-15 08:09:08 +0000189private char *p1;
190
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000191// CHECK: @p2 = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
192// 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 +0000193local char *p2;
194
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000195// CHECK: @p3 = local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
196// COMMON: @p3 = common local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000197constant char *p3;
198
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000199// CHECK: @p4 = local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
200// COMMON: @p4 = common local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000201global char *p4;
202
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000203// CHECK: @p5 = local_unnamed_addr addrspace(1) global i8* null, align 8
204// COMMON: @p5 = common local_unnamed_addr addrspace(1) global i8* null, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000205generic char *p5;
206
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +0000207// Test default initialization of structure.
Yaxun Liu402804b2016-12-15 08:09:08 +0000208
Matt Arsenault301a6da2020-06-01 10:31:05 -0400209// CHECK: @S1 = local_unnamed_addr addrspace(1) global %struct.StructTy1 { i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), 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 +0000210StructTy1 S1;
211
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000212// CHECK: @S2 = local_unnamed_addr addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000213StructTy2 S2;
214
215// Test default initialization of array.
Matt Arsenault301a6da2020-06-01 10:31:05 -0400216// CHECK: @A1 = local_unnamed_addr addrspace(1) global [2 x %struct.StructTy1] [%struct.StructTy1 { i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), 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)* addrspacecast (i8* null to i8 addrspace(5)*), 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 +0000217StructTy1 A1[2];
218
Sjoerd Meijer3d9a0442020-03-09 19:25:24 +0000219// CHECK: @A2 = local_unnamed_addr addrspace(1) global [2 x %struct.StructTy2] zeroinitializer, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000220StructTy2 A2[2];
221
222// Test comparison with 0.
223
224// CHECK-LABEL: cmp_private
Matt Arsenault301a6da2020-06-01 10:31:05 -0400225// CHECK: icmp eq i8 addrspace(5)* %p, addrspacecast (i8* null to i8 addrspace(5)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000226void cmp_private(private char* p) {
227 if (p != 0)
228 *p = 0;
229}
230
231// CHECK-LABEL: cmp_local
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000232// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000233void cmp_local(local char* p) {
234 if (p != 0)
235 *p = 0;
236}
237
238// CHECK-LABEL: cmp_global
239// CHECK: icmp eq i8 addrspace(1)* %p, null
240void cmp_global(global char* p) {
241 if (p != 0)
242 *p = 0;
243}
244
245// CHECK-LABEL: cmp_constant
Yaxun Liu651bd732018-02-13 18:01:21 +0000246// CHECK: icmp eq i8 addrspace(4)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000247char cmp_constant(constant char* p) {
248 if (p != 0)
249 return *p;
250 else
251 return 0;
252}
253
254// CHECK-LABEL: cmp_generic
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000255// CHECK: icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000256void cmp_generic(generic char* p) {
257 if (p != 0)
258 *p = 0;
259}
260
261// Test comparison with NULL.
262
263// CHECK-LABEL: cmp_NULL_private
Matt Arsenault301a6da2020-06-01 10:31:05 -0400264// CHECK: icmp eq i8 addrspace(5)* %p, addrspacecast (i8* null to i8 addrspace(5)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000265void cmp_NULL_private(private char* p) {
266 if (p != NULL)
267 *p = 0;
268}
269
270// CHECK-LABEL: cmp_NULL_local
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000271// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000272void cmp_NULL_local(local char* p) {
273 if (p != NULL)
274 *p = 0;
275}
276
277// CHECK-LABEL: cmp_NULL_global
278// CHECK: icmp eq i8 addrspace(1)* %p, null
279void cmp_NULL_global(global char* p) {
280 if (p != NULL)
281 *p = 0;
282}
283
284// CHECK-LABEL: cmp_NULL_constant
Yaxun Liu651bd732018-02-13 18:01:21 +0000285// CHECK: icmp eq i8 addrspace(4)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000286char cmp_NULL_constant(constant char* p) {
287 if (p != NULL)
288 return *p;
289 else
290 return 0;
291}
292
293// CHECK-LABEL: cmp_NULL_generic
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000294// CHECK: icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000295void cmp_NULL_generic(generic char* p) {
296 if (p != NULL)
297 *p = 0;
298}
299
300// Test storage 0 as null pointer.
301// CHECK-LABEL: test_storage_null_pointer
Matt Arsenault301a6da2020-06-01 10:31:05 -0400302// CHECK: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)** %arg_private
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000303// CHECK: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)** %arg_local
304// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)** %arg_global
Yaxun Liu651bd732018-02-13 18:01:21 +0000305// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)** %arg_constant
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000306// CHECK: store i8* null, i8** %arg_generic
Yaxun Liu402804b2016-12-15 08:09:08 +0000307void test_storage_null_pointer(private char** arg_private,
308 local char** arg_local,
309 global char** arg_global,
310 constant char** arg_constant,
311 generic char** arg_generic) {
312 *arg_private = 0;
313 *arg_local = 0;
314 *arg_global = 0;
315 *arg_constant = 0;
316 *arg_generic = 0;
317}
318
319// Test storage NULL as null pointer.
320// CHECK-LABEL: test_storage_null_pointer_NULL
Matt Arsenault301a6da2020-06-01 10:31:05 -0400321// CHECK: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)** %arg_private
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000322// CHECK: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)** %arg_local
323// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)** %arg_global
Yaxun Liu651bd732018-02-13 18:01:21 +0000324// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)** %arg_constant
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000325// CHECK: store i8* null, i8** %arg_generic
Yaxun Liu402804b2016-12-15 08:09:08 +0000326void test_storage_null_pointer_NULL(private char** arg_private,
327 local char** arg_local,
328 global char** arg_global,
329 constant char** arg_constant,
330 generic char** arg_generic) {
331 *arg_private = NULL;
332 *arg_local = NULL;
333 *arg_global = NULL;
334 *arg_constant = NULL;
335 *arg_generic = NULL;
336}
337
338// Test pass null pointer to function as argument.
339void test_pass_null_pointer_arg_calee(private char* arg_private,
340 local char* arg_local,
341 global char* arg_global,
342 constant char* arg_constant,
343 generic char* arg_generic);
344
345// CHECK-LABEL: test_pass_null_pointer_arg
Matt Arsenault301a6da2020-06-01 10:31:05 -0400346// CHECK: call void @test_pass_null_pointer_arg_calee(i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(4)* null, i8* null)
347// CHECK: call void @test_pass_null_pointer_arg_calee(i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), 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 +0000348void test_pass_null_pointer_arg(void) {
349 test_pass_null_pointer_arg_calee(0, 0, 0, 0, 0);
350 test_pass_null_pointer_arg_calee(NULL, NULL, NULL, NULL, NULL);
351}
352
353// Test cast null pointer to size_t.
354void test_cast_null_pointer_to_sizet_calee(size_t arg_private,
355 size_t arg_local,
356 size_t arg_global,
357 size_t arg_constant,
358 size_t arg_generic);
359
360// CHECK-LABEL: test_cast_null_pointer_to_sizet
Douglas Yung086be9f2020-06-02 20:14:09 +0000361// CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 ptrtoint (i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*) to i64), i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0)
362// CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 ptrtoint (i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*) to i64), 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 +0000363void test_cast_null_pointer_to_sizet(void) {
364 test_cast_null_pointer_to_sizet_calee((size_t)((private char*)0),
365 (size_t)((local char*)0),
366 (size_t)((global char*)0),
367 (size_t)((constant char*)0),
368 (size_t)((generic char*)0));
369 test_cast_null_pointer_to_sizet_calee((size_t)((private char*)NULL),
370 (size_t)((local char*)NULL),
371 (size_t)((global char*)NULL),
372 (size_t)((constant char*)0), // NULL cannot be casted to constant pointer since it is defined as a generic pointer
373 (size_t)((generic char*)NULL));
374}
375
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +0000376// Test comparison between null pointers.
Yaxun Liu402804b2016-12-15 08:09:08 +0000377#define TEST_EQ00(addr1, addr2) int test_eq00_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)0; }
378#define TEST_EQ0N(addr1, addr2) int test_eq0N_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; }
379#define TEST_EQN0(addr1, addr2) int test_eqN0_##addr1##_##addr2(void) { return (addr1 char*)NULL == (addr2 char*)0; }
380#define TEST_EQNN(addr1, addr2) int test_eqNN_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; }
381#define TEST_NE00(addr1, addr2) int test_ne00_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)0; }
382#define TEST_NE0N(addr1, addr2) int test_ne0N_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; }
383#define TEST_NEN0(addr1, addr2) int test_neN0_##addr1##_##addr2(void) { return (addr1 char*)NULL != (addr2 char*)0; }
384#define TEST_NENN(addr1, addr2) int test_neNN_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; }
385#define TEST(addr1, addr2) \
386 TEST_EQ00(addr1, addr2) \
387 TEST_EQ0N(addr1, addr2) \
388 TEST_EQN0(addr1, addr2) \
389 TEST_EQNN(addr1, addr2) \
390 TEST_NE00(addr1, addr2) \
391 TEST_NE0N(addr1, addr2) \
392 TEST_NEN0(addr1, addr2) \
393 TEST_NENN(addr1, addr2)
394
395// CHECK-LABEL: test_eq00_generic_private
396// CHECK: ret i32 1
397// CHECK-LABEL: test_eq0N_generic_private
398// CHECK: ret i32 1
399// CHECK-LABEL: test_eqN0_generic_private
400// CHECK: ret i32 1
401// CHECK-LABEL: test_eqNN_generic_private
402// CHECK: ret i32 1
403// CHECK-LABEL: test_ne00_generic_private
404// CHECK: ret i32 0
405// CHECK-LABEL: test_ne0N_generic_private
406// CHECK: ret i32 0
407// CHECK-LABEL: test_neN0_generic_private
408// CHECK: ret i32 0
409// CHECK-LABEL: test_neNN_generic_private
410// CHECK: ret i32 0
411TEST(generic, private)
412
413// CHECK-LABEL: test_eq00_generic_local
414// CHECK: ret i32 1
415// CHECK-LABEL: test_eq0N_generic_local
416// CHECK: ret i32 1
417// CHECK-LABEL: test_eqN0_generic_local
418// CHECK: ret i32 1
419// CHECK-LABEL: test_eqNN_generic_local
420// CHECK: ret i32 1
421// CHECK-LABEL: test_ne00_generic_local
422// CHECK: ret i32 0
423// CHECK-LABEL: test_ne0N_generic_local
424// CHECK: ret i32 0
425// CHECK-LABEL: test_neN0_generic_local
426// CHECK: ret i32 0
427// CHECK-LABEL: test_neNN_generic_local
428// CHECK: ret i32 0
429TEST(generic, local)
430
431// CHECK-LABEL: test_eq00_generic_global
432// CHECK: ret i32 1
433// CHECK-LABEL: test_eq0N_generic_global
434// CHECK: ret i32 1
435// CHECK-LABEL: test_eqN0_generic_global
436// CHECK: ret i32 1
437// CHECK-LABEL: test_eqNN_generic_global
438// CHECK: ret i32 1
439// CHECK-LABEL: test_ne00_generic_global
440// CHECK: ret i32 0
441// CHECK-LABEL: test_ne0N_generic_global
442// CHECK: ret i32 0
443// CHECK-LABEL: test_neN0_generic_global
444// CHECK: ret i32 0
445// CHECK-LABEL: test_neNN_generic_global
446// CHECK: ret i32 0
447TEST(generic, global)
448
449// CHECK-LABEL: test_eq00_generic_generic
450// CHECK: ret i32 1
451// CHECK-LABEL: test_eq0N_generic_generic
452// CHECK: ret i32 1
453// CHECK-LABEL: test_eqN0_generic_generic
454// CHECK: ret i32 1
455// CHECK-LABEL: test_eqNN_generic_generic
456// CHECK: ret i32 1
457// CHECK-LABEL: test_ne00_generic_generic
458// CHECK: ret i32 0
459// CHECK-LABEL: test_ne0N_generic_generic
460// CHECK: ret i32 0
461// CHECK-LABEL: test_neN0_generic_generic
462// CHECK: ret i32 0
463// CHECK-LABEL: test_neNN_generic_generic
464// CHECK: ret i32 0
465TEST(generic, generic)
466
467// CHECK-LABEL: test_eq00_constant_constant
468// CHECK: ret i32 1
469TEST_EQ00(constant, constant)
470
471// Test cast to bool.
472
473// CHECK-LABEL: cast_bool_private
Matt Arsenault301a6da2020-06-01 10:31:05 -0400474// CHECK: icmp eq i8 addrspace(5)* %p, addrspacecast (i8* null to i8 addrspace(5)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000475void cast_bool_private(private char* p) {
476 if (p)
477 *p = 0;
478}
479
480// CHECK-LABEL: cast_bool_local
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000481// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000482void cast_bool_local(local char* p) {
483 if (p)
484 *p = 0;
485}
486
487// CHECK-LABEL: cast_bool_global
488// CHECK: icmp eq i8 addrspace(1)* %p, null
489void cast_bool_global(global char* p) {
490 if (p)
491 *p = 0;
492}
493
494// CHECK-LABEL: cast_bool_constant
Yaxun Liu651bd732018-02-13 18:01:21 +0000495// CHECK: icmp eq i8 addrspace(4)* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000496char cast_bool_constant(constant char* p) {
497 if (p)
498 return *p;
499 else
500 return 0;
501}
502
503// CHECK-LABEL: cast_bool_generic
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000504// CHECK: icmp eq i8* %p, null
Yaxun Liu402804b2016-12-15 08:09:08 +0000505void cast_bool_generic(generic char* p) {
506 if (p)
507 *p = 0;
508}
509
510// Test initialize a struct using memset.
511// For large structures which is mostly zero, clang generats llvm.memset for
512// the zero part and store for non-zero members.
513typedef struct {
514 long a, b, c, d;
515 private char *p;
516} StructTy3;
517
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000518// CHECK-LABEL: test_memset_private
Matt Arsenault301a6da2020-06-01 10:31:05 -0400519// CHECK: call void @llvm.memset.p5i8.i64(i8 addrspace(5)* align 8 {{.*}}, i8 0, i64 32, i1 false)
520// CHECK: [[GEP:%.*]] = getelementptr inbounds %struct.StructTy3, %struct.StructTy3 addrspace(5)* %ptr, i32 0, i32 4
521// CHECK: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)* addrspace(5)* [[GEP]]
522// CHECK: [[GEP1:%.*]] = getelementptr inbounds i8, i8 addrspace(5)* {{.*}}, i32 36
523// CHECK: [[GEP1_CAST:%.*]] = bitcast i8 addrspace(5)* [[GEP1]] to i32 addrspace(5)*
524// CHECK: store i32 0, i32 addrspace(5)* [[GEP1_CAST]], align 4
Matt Arsenault3fe73952017-08-09 21:44:58 +0000525void test_memset_private(private StructTy3 *ptr) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000526 StructTy3 S3 = {0, 0, 0, 0, 0};
Matt Arsenault3fe73952017-08-09 21:44:58 +0000527 *ptr = S3;
Yaxun Liu402804b2016-12-15 08:09:08 +0000528}
529
530// Test casting literal 0 to pointer.
531// A 0 literal casted to pointer should become a null pointer.
532
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000533// CHECK-LABEL: test_cast_0_to_local_ptr
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000534// CHECK: ret i32 addrspace(3)* addrspacecast (i32* null to i32 addrspace(3)*)
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000535local int* test_cast_0_to_local_ptr(void) {
536 return (local int*)0;
537}
538
539// CHECK-LABEL: test_cast_0_to_private_ptr
Matt Arsenault301a6da2020-06-01 10:31:05 -0400540// CHECK: ret i32 addrspace(5)* addrspacecast (i32* null to i32 addrspace(5)*)
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000541private int* test_cast_0_to_private_ptr(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000542 return (private int*)0;
543}
544
545// Test casting non-literal integer with 0 value to pointer.
546// A non-literal integer expression with 0 value is casted to a pointer with
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000547// zero value.
Yaxun Liu402804b2016-12-15 08:09:08 +0000548
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000549// CHECK-LABEL: test_cast_int_to_ptr1_private
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000550// CHECK: ret i32 addrspace(5)* null
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000551private int* test_cast_int_to_ptr1_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000552 return (private int*)((void)0, 0);
553}
554
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000555// CHECK-LABEL: test_cast_int_to_ptr1_local
556 // CHECK: ret i32 addrspace(3)* null
557local int* test_cast_int_to_ptr1_local(void) {
558 return (local int*)((void)0, 0);
559}
560
Yaxun Liu402804b2016-12-15 08:09:08 +0000561// CHECK-LABEL: test_cast_int_to_ptr2
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000562// CHECK: ret i32 addrspace(5)* null
Yaxun Liu402804b2016-12-15 08:09:08 +0000563private int* test_cast_int_to_ptr2(void) {
564 int x = 0;
565 return (private int*)x;
566}
567
568// Test logical operations.
569// CHECK-LABEL: test_not_nullptr
570// CHECK: ret i32 1
571int test_not_nullptr(void) {
572 return !(private char*)NULL;
573}
574
575// CHECK-LABEL: test_and_nullptr
576// CHECK: ret i32 0
577int test_and_nullptr(int a) {
578 return a && ((private char*)NULL);
579}
580
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000581// CHECK-LABEL: test_not_private_ptr
Matt Arsenault301a6da2020-06-01 10:31:05 -0400582// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(5)* %p, addrspacecast (i8* null to i8 addrspace(5)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000583// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
584// CHECK: ret i32 %[[lnot_ext]]
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000585int test_not_private_ptr(private char* p) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000586 return !p;
587}
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000588
589// CHECK-LABEL: test_not_local_ptr
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000590// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000591// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
592// CHECK: ret i32 %[[lnot_ext]]
593int test_not_local_ptr(local char* p) {
594 return !p;
595}
596
597
Yaxun Liu402804b2016-12-15 08:09:08 +0000598// CHECK-LABEL: test_and_ptr
Matt Arsenault301a6da2020-06-01 10:31:05 -0400599// CHECK: %[[tobool:.*]] = icmp ne i8 addrspace(5)* %p1, addrspacecast (i8* null to i8 addrspace(5)*)
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000600// CHECK: %[[tobool1:.*]] = icmp ne i8 addrspace(3)* %p2, addrspacecast (i8* null to i8 addrspace(3)*)
Yaxun Liu402804b2016-12-15 08:09:08 +0000601// CHECK: %[[res:.*]] = and i1 %[[tobool]], %[[tobool1]]
602// CHECK: %[[land_ext:.*]] = zext i1 %[[res]] to i32
603// CHECK: ret i32 %[[land_ext]]
604int test_and_ptr(private char* p1, local char* p2) {
605 return p1 && p2;
606}
607
608// Test folding of null pointer in function scope.
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000609// NOOPT-LABEL: test_fold_private
Yaxun Liu402804b2016-12-15 08:09:08 +0000610// NOOPT: call void @test_fold_callee
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000611// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)* addrspace(5)* %glob, align 8
Yaxun Liu402804b2016-12-15 08:09:08 +0000612// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
613// NOOPT: call void @test_fold_callee
Matt Arsenault301a6da2020-06-01 10:31:05 -0400614// NOOPT: %{{.*}} = add nsw i64 %1, sext (i32 ptrtoint (i32 addrspace(5)* addrspacecast (i32* null to i32 addrspace(5)*) to i32) to i64)
Yaxun Liu402804b2016-12-15 08:09:08 +0000615// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
616void test_fold_callee(void);
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000617void test_fold_private(void) {
Yaxun Liu402804b2016-12-15 08:09:08 +0000618 global int* glob = (test_fold_callee(), (global int*)(generic char*)0);
619 long x = glob - (global int*)(generic char*)0;
620 x = x + (int)(test_fold_callee(), (private int*)(generic char*)(global short*)0);
621 x = x - (int)((private int*)0 == (private int*)(generic char*)0);
622}
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000623
624// NOOPT-LABEL: test_fold_local
625// NOOPT: call void @test_fold_callee
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000626// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)* addrspace(5)* %glob, align 8
Matt Arsenaultbf5e3e42017-03-13 19:47:53 +0000627// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
628// NOOPT: call void @test_fold_callee
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000629// 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 +0000630// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
631void test_fold_local(void) {
632 global int* glob = (test_fold_callee(), (global int*)(generic char*)0);
633 long x = glob - (global int*)(generic char*)0;
634 x = x + (int)(test_fold_callee(), (local int*)(generic char*)(global short*)0);
635 x = x - (int)((local int*)0 == (local int*)(generic char*)0);
636}