1*532dc62bSNikita Popov// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis %s -cl-std=CL2.0 -include opencl-c.h -triple amdgcn -emit-llvm -o - | FileCheck %s
2*532dc62bSNikita Popov// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis %s -O0 -cl-std=CL2.0 -include opencl-c.h -triple amdgcn -emit-llvm -o - | FileCheck --check-prefix=NOOPT %s
3*532dc62bSNikita Popov// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis %s -cl-std=CL2.0 -include opencl-c.h -triple amdgcn---opencl -emit-llvm -o - | FileCheck %s
4*532dc62bSNikita Popov// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis %s -cl-std=CL2.0 -include opencl-c.h -triple amdgcn -fcommon -emit-llvm -o - | FileCheck %s --check-prefix=COMMON
5402804b6SYaxun Liu
6402804b6SYaxun Liutypedef struct {
7402804b6SYaxun Liu  private char *p1;
8402804b6SYaxun Liu  local char *p2;
9402804b6SYaxun Liu  constant char *p3;
10402804b6SYaxun Liu  global char *p4;
11402804b6SYaxun Liu  generic char *p5;
12402804b6SYaxun Liu} StructTy1;
13402804b6SYaxun Liu
14402804b6SYaxun Liutypedef struct {
15402804b6SYaxun Liu  constant char *p3;
16402804b6SYaxun Liu  global char *p4;
17402804b6SYaxun Liu  generic char *p5;
18402804b6SYaxun Liu} StructTy2;
19402804b6SYaxun Liu
20402804b6SYaxun Liu// Test 0 as initializer.
21402804b6SYaxun Liu
22fd739804SFangrui Song// CHECK: @private_p ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
23402804b6SYaxun Liuprivate char *private_p = 0;
24402804b6SYaxun Liu
25fd739804SFangrui Song// CHECK: @local_p ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
26402804b6SYaxun Liulocal char *local_p = 0;
27402804b6SYaxun Liu
28fd739804SFangrui Song// CHECK: @global_p ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
29402804b6SYaxun Liuglobal char *global_p = 0;
30402804b6SYaxun Liu
31fd739804SFangrui Song// CHECK: @constant_p ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
32402804b6SYaxun Liuconstant char *constant_p = 0;
33402804b6SYaxun Liu
34fd739804SFangrui Song// CHECK: @generic_p ={{.*}} local_unnamed_addr addrspace(1) global i8* null, align 8
35402804b6SYaxun Liugeneric char *generic_p = 0;
36402804b6SYaxun Liu
37402804b6SYaxun Liu// Test NULL as initializer.
38402804b6SYaxun Liu
39fd739804SFangrui Song// CHECK: @private_p_NULL ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
40402804b6SYaxun Liuprivate char *private_p_NULL = NULL;
41402804b6SYaxun Liu
42fd739804SFangrui Song// CHECK: @local_p_NULL ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
43402804b6SYaxun Liulocal char *local_p_NULL = NULL;
44402804b6SYaxun Liu
45fd739804SFangrui Song// CHECK: @global_p_NULL ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
46402804b6SYaxun Liuglobal char *global_p_NULL = NULL;
47402804b6SYaxun Liu
48fd739804SFangrui Song// CHECK: @constant_p_NULL ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
49402804b6SYaxun Liuconstant char *constant_p_NULL = NULL;
50402804b6SYaxun Liu
51fd739804SFangrui Song// CHECK: @generic_p_NULL ={{.*}} local_unnamed_addr addrspace(1) global i8* null, align 8
52402804b6SYaxun Liugeneric char *generic_p_NULL = NULL;
53402804b6SYaxun Liu
54402804b6SYaxun Liu// Test constant folding of null pointer.
55402804b6SYaxun Liu// A null pointer should be folded to a null pointer in the target address space.
56402804b6SYaxun Liu
57fd739804SFangrui Song// CHECK: @fold_generic ={{.*}} local_unnamed_addr addrspace(1) global i32* null, align 8
58402804b6SYaxun Liugeneric int *fold_generic = (global int*)(generic float*)(private char*)0;
59402804b6SYaxun Liu
60fd739804SFangrui Song// CHECK: @fold_priv ={{.*}} local_unnamed_addr addrspace(1) global i16 addrspace(5)* addrspacecast (i16* null to i16 addrspace(5)*), align 4
61402804b6SYaxun Liuprivate short *fold_priv = (private short*)(generic int*)(global void*)0;
62402804b6SYaxun Liu
63fd739804SFangrui Song// CHECK: @fold_priv_arith ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(5)* inttoptr (i32 9 to i8 addrspace(5)*), align 4
64402804b6SYaxun Liuprivate char *fold_priv_arith = (private char*)0 + 10;
65402804b6SYaxun Liu
66fd739804SFangrui Song// CHECK: @fold_local_arith ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(3)* inttoptr (i32 9 to i8 addrspace(3)*), align 4
67301a6da8SMatt Arsenaultlocal char *fold_local_arith = (local char*)0 + 10;
68301a6da8SMatt Arsenault
69fd739804SFangrui Song// CHECK: @fold_int ={{.*}} local_unnamed_addr addrspace(1) global i32 13, align 4
70402804b6SYaxun Liuint fold_int = (int)(private void*)(generic char*)(global int*)0 + 14;
71402804b6SYaxun Liu
72fd739804SFangrui Song// CHECK: @fold_int2 ={{.*}} local_unnamed_addr addrspace(1) global i32 12, align 4
73402804b6SYaxun Liuint fold_int2 = (int) ((private void*)0 + 13);
74402804b6SYaxun Liu
75fd739804SFangrui Song// CHECK: @fold_int3 ={{.*}} local_unnamed_addr addrspace(1) global i32 -1, align 4
76402804b6SYaxun Liuint fold_int3 = (int) ((private int*)0);
77402804b6SYaxun Liu
78fd739804SFangrui Song// CHECK: @fold_int4 ={{.*}} local_unnamed_addr addrspace(1) global i32 7, align 4
79402804b6SYaxun Liuint fold_int4 = (int) &((private int*)0)[2];
80402804b6SYaxun Liu
81fd739804SFangrui Song// CHECK: @fold_int5 ={{.*}} local_unnamed_addr addrspace(1) global i32 3, align 4
82402804b6SYaxun Liuint fold_int5 = (int) &((private StructTy1*)0)->p2;
83402804b6SYaxun Liu
84bf5e3e43SMatt Arsenault
85fd739804SFangrui Song// CHECK: @fold_int_local ={{.*}} local_unnamed_addr addrspace(1) global i32 13, align 4
86bf5e3e43SMatt Arsenaultint fold_int_local = (int)(local void*)(generic char*)(global int*)0 + 14;
87bf5e3e43SMatt Arsenault
88fd739804SFangrui Song// CHECK: @fold_int2_local ={{.*}} local_unnamed_addr addrspace(1) global i32 12, align 4
89bf5e3e43SMatt Arsenaultint fold_int2_local = (int) ((local void*)0 + 13);
90bf5e3e43SMatt Arsenault
91fd739804SFangrui Song// CHECK: @fold_int3_local ={{.*}} local_unnamed_addr addrspace(1) global i32 -1, align 4
92bf5e3e43SMatt Arsenaultint fold_int3_local = (int) ((local int*)0);
93bf5e3e43SMatt Arsenault
94fd739804SFangrui Song// CHECK: @fold_int4_local ={{.*}} local_unnamed_addr addrspace(1) global i32 7, align 4
95bf5e3e43SMatt Arsenaultint fold_int4_local = (int) &((local int*)0)[2];
96bf5e3e43SMatt Arsenault
97fd739804SFangrui Song// CHECK: @fold_int5_local ={{.*}} local_unnamed_addr addrspace(1) global i32 3, align 4
98bf5e3e43SMatt Arsenaultint fold_int5_local = (int) &((local StructTy1*)0)->p2;
99bf5e3e43SMatt Arsenault
100bf5e3e43SMatt Arsenault
101402804b6SYaxun Liu// Test static variable initialization.
102402804b6SYaxun Liu
103301a6da8SMatt Arsenault// NOOPT: @test_static_var_private.sp1 = internal addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
104301a6da8SMatt Arsenault// NOOPT: @test_static_var_private.sp2 = internal addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
105301a6da8SMatt Arsenault// NOOPT: @test_static_var_private.sp3 = internal addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
106f5f45e5eSYaxun Liu// NOOPT: @test_static_var_private.sp4 = internal addrspace(1) global i8 addrspace(5)* null, align 4
1076781fee0SRichard Smith// NOOPT: @test_static_var_private.sp5 = internal addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
108301a6da8SMatt Arsenault// 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
10925d1b434SYaxun Liu// NOOPT: @test_static_var_private.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
110402804b6SYaxun Liu
111bf5e3e43SMatt Arsenaultvoid test_static_var_private(void) {
112402804b6SYaxun Liu  static private char *sp1 = 0;
113402804b6SYaxun Liu  static private char *sp2 = NULL;
114402804b6SYaxun Liu  static private char *sp3;
115402804b6SYaxun Liu  static private char *sp4 = (private char*)((void)0, 0);
116402804b6SYaxun Liu  const int x = 0;
117402804b6SYaxun Liu  static private char *sp5 = (private char*)x;
118402804b6SYaxun Liu  static StructTy1 SS1;
119402804b6SYaxun Liu  static StructTy2 SS2;
120402804b6SYaxun Liu}
121402804b6SYaxun Liu
122f5f45e5eSYaxun Liu// NOOPT: @test_static_var_local.sp1 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
123f5f45e5eSYaxun Liu// NOOPT: @test_static_var_local.sp2 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
124f5f45e5eSYaxun Liu// NOOPT: @test_static_var_local.sp3 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
125bf5e3e43SMatt Arsenault// NOOPT: @test_static_var_local.sp4 = internal addrspace(1) global i8 addrspace(3)* null, align 4
1266781fee0SRichard Smith// NOOPT: @test_static_var_local.sp5 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
127301a6da8SMatt Arsenault// 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
12825d1b434SYaxun Liu// NOOPT: @test_static_var_local.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
129bf5e3e43SMatt Arsenaultvoid test_static_var_local(void) {
130bf5e3e43SMatt Arsenault  static local char *sp1 = 0;
131bf5e3e43SMatt Arsenault  static local char *sp2 = NULL;
132bf5e3e43SMatt Arsenault  static local char *sp3;
133bf5e3e43SMatt Arsenault  static local char *sp4 = (local char*)((void)0, 0);
134bf5e3e43SMatt Arsenault  const int x = 0;
135bf5e3e43SMatt Arsenault  static local char *sp5 = (local char*)x;
136bf5e3e43SMatt Arsenault  static StructTy1 SS1;
137bf5e3e43SMatt Arsenault  static StructTy2 SS2;
138bf5e3e43SMatt Arsenault}
139bf5e3e43SMatt Arsenault
140402804b6SYaxun Liu// Test function-scope variable initialization.
141bf5e3e43SMatt Arsenault// NOOPT-LABEL: @test_func_scope_var_private(
142301a6da8SMatt Arsenault// NOOPT: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)* addrspace(5)* %sp1, align 4
143301a6da8SMatt Arsenault// NOOPT: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)* addrspace(5)* %sp2, align 4
144f5f45e5eSYaxun Liu// NOOPT: store i8 addrspace(5)* null, i8 addrspace(5)* addrspace(5)* %sp3, align 4
1456781fee0SRichard Smith// NOOPT: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)* addrspace(5)* %sp4, align 4
146f5f45e5eSYaxun Liu// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1 addrspace(5)* %SS1 to i8 addrspace(5)*
1473a881e6bSJF Bastien// 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)
148f5f45e5eSYaxun Liu// NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2 addrspace(5)* %SS2 to i8 addrspace(5)*
149f5f45e5eSYaxun Liu// NOOPT: call void @llvm.memset.p5i8.i64(i8 addrspace(5)* align 8 %[[SS2]], i8 0, i64 24, i1 false)
150bf5e3e43SMatt Arsenaultvoid test_func_scope_var_private(void) {
151402804b6SYaxun Liu  private char *sp1 = 0;
152402804b6SYaxun Liu  private char *sp2 = NULL;
153402804b6SYaxun Liu  private char *sp3 = (private char*)((void)0, 0);
154402804b6SYaxun Liu  const int x = 0;
155402804b6SYaxun Liu  private char *sp4 = (private char*)x;
156402804b6SYaxun Liu  StructTy1 SS1 = {0, 0, 0, 0, 0};
157402804b6SYaxun Liu  StructTy2 SS2 = {0, 0, 0};
158402804b6SYaxun Liu}
159402804b6SYaxun Liu
160bf5e3e43SMatt Arsenault// Test function-scope variable initialization.
161bf5e3e43SMatt Arsenault// NOOPT-LABEL: @test_func_scope_var_local(
162f5f45e5eSYaxun Liu// NOOPT: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(5)* %sp1, align 4
163f5f45e5eSYaxun Liu// NOOPT: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(5)* %sp2, align 4
164f5f45e5eSYaxun Liu// NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)* addrspace(5)* %sp3, align 4
1656781fee0SRichard Smith// NOOPT: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(5)* %sp4, align 4
166f5f45e5eSYaxun Liu// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1 addrspace(5)* %SS1 to i8 addrspace(5)*
1673a881e6bSJF Bastien// 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)
168f5f45e5eSYaxun Liu// NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2 addrspace(5)* %SS2 to i8 addrspace(5)*
169f5f45e5eSYaxun Liu// NOOPT: call void @llvm.memset.p5i8.i64(i8 addrspace(5)* align 8 %[[SS2]], i8 0, i64 24, i1 false)
170bf5e3e43SMatt Arsenaultvoid test_func_scope_var_local(void) {
171bf5e3e43SMatt Arsenault  local char *sp1 = 0;
172bf5e3e43SMatt Arsenault  local char *sp2 = NULL;
173bf5e3e43SMatt Arsenault  local char *sp3 = (local char*)((void)0, 0);
174bf5e3e43SMatt Arsenault  const int x = 0;
175bf5e3e43SMatt Arsenault  local char *sp4 = (local char*)x;
176bf5e3e43SMatt Arsenault  StructTy1 SS1 = {0, 0, 0, 0, 0};
177bf5e3e43SMatt Arsenault  StructTy2 SS2 = {0, 0, 0};
178bf5e3e43SMatt Arsenault}
179bf5e3e43SMatt Arsenault
180bf5e3e43SMatt Arsenault
181402804b6SYaxun Liu// Test default initialization of pointers.
182402804b6SYaxun Liu
183402804b6SYaxun Liu// Tentative definition of global variables with non-zero initializer
184402804b6SYaxun Liu// cannot have common linkage since common linkage requires zero initialization
185402804b6SYaxun Liu// and does not have explicit section.
186402804b6SYaxun Liu
187fd739804SFangrui Song// CHECK: @p1 ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
188301a6da8SMatt Arsenault// COMMON: @p1 = weak local_unnamed_addr addrspace(1) global i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), align 4
189402804b6SYaxun Liuprivate char *p1;
190402804b6SYaxun Liu
191fd739804SFangrui Song// CHECK: @p2 ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
1923d9a0445SSjoerd Meijer// COMMON: @p2 = weak local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), align 4
193402804b6SYaxun Liulocal char *p2;
194402804b6SYaxun Liu
195fd739804SFangrui Song// CHECK: @p3 ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
1963d9a0445SSjoerd Meijer// COMMON: @p3 = common local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 8
197402804b6SYaxun Liuconstant char *p3;
198402804b6SYaxun Liu
199fd739804SFangrui Song// CHECK: @p4 ={{.*}} local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
2003d9a0445SSjoerd Meijer// COMMON: @p4 = common local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 8
201402804b6SYaxun Liuglobal char *p4;
202402804b6SYaxun Liu
203fd739804SFangrui Song// CHECK: @p5 ={{.*}} local_unnamed_addr addrspace(1) global i8* null, align 8
2043d9a0445SSjoerd Meijer// COMMON: @p5 = common local_unnamed_addr addrspace(1) global i8* null, align 8
205402804b6SYaxun Liugeneric char *p5;
206402804b6SYaxun Liu
2072a8c18d9SAlexander Kornienko// Test default initialization of structure.
208402804b6SYaxun Liu
209fd739804SFangrui Song// 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
210402804b6SYaxun LiuStructTy1 S1;
211402804b6SYaxun Liu
212fd739804SFangrui Song// CHECK: @S2 ={{.*}} local_unnamed_addr addrspace(1) global %struct.StructTy2 zeroinitializer, align 8
213402804b6SYaxun LiuStructTy2 S2;
214402804b6SYaxun Liu
215402804b6SYaxun Liu// Test default initialization of array.
216fd739804SFangrui Song// 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
217402804b6SYaxun LiuStructTy1 A1[2];
218402804b6SYaxun Liu
219fd739804SFangrui Song// CHECK: @A2 ={{.*}} local_unnamed_addr addrspace(1) global [2 x %struct.StructTy2] zeroinitializer, align 8
220402804b6SYaxun LiuStructTy2 A2[2];
221402804b6SYaxun Liu
222402804b6SYaxun Liu// Test comparison with 0.
223402804b6SYaxun Liu
224402804b6SYaxun Liu// CHECK-LABEL: cmp_private
225301a6da8SMatt Arsenault// CHECK: icmp eq i8 addrspace(5)* %p, addrspacecast (i8* null to i8 addrspace(5)*)
226402804b6SYaxun Liuvoid cmp_private(private char* p) {
227402804b6SYaxun Liu  if (p != 0)
228402804b6SYaxun Liu    *p = 0;
229402804b6SYaxun Liu}
230402804b6SYaxun Liu
231402804b6SYaxun Liu// CHECK-LABEL: cmp_local
232f5f45e5eSYaxun Liu// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
233402804b6SYaxun Liuvoid cmp_local(local char* p) {
234402804b6SYaxun Liu  if (p != 0)
235402804b6SYaxun Liu    *p = 0;
236402804b6SYaxun Liu}
237402804b6SYaxun Liu
238402804b6SYaxun Liu// CHECK-LABEL: cmp_global
239402804b6SYaxun Liu// CHECK: icmp eq i8 addrspace(1)* %p, null
240402804b6SYaxun Liuvoid cmp_global(global char* p) {
241402804b6SYaxun Liu  if (p != 0)
242402804b6SYaxun Liu    *p = 0;
243402804b6SYaxun Liu}
244402804b6SYaxun Liu
245402804b6SYaxun Liu// CHECK-LABEL: cmp_constant
246651bd73cSYaxun Liu// CHECK: icmp eq i8 addrspace(4)* %p, null
247402804b6SYaxun Liuchar cmp_constant(constant char* p) {
248402804b6SYaxun Liu  if (p != 0)
249402804b6SYaxun Liu    return *p;
250402804b6SYaxun Liu  else
251402804b6SYaxun Liu    return 0;
252402804b6SYaxun Liu}
253402804b6SYaxun Liu
254402804b6SYaxun Liu// CHECK-LABEL: cmp_generic
255f5f45e5eSYaxun Liu// CHECK: icmp eq i8* %p, null
256402804b6SYaxun Liuvoid cmp_generic(generic char* p) {
257402804b6SYaxun Liu  if (p != 0)
258402804b6SYaxun Liu    *p = 0;
259402804b6SYaxun Liu}
260402804b6SYaxun Liu
261402804b6SYaxun Liu// Test comparison with NULL.
262402804b6SYaxun Liu
263402804b6SYaxun Liu// CHECK-LABEL: cmp_NULL_private
264301a6da8SMatt Arsenault// CHECK: icmp eq i8 addrspace(5)* %p, addrspacecast (i8* null to i8 addrspace(5)*)
265402804b6SYaxun Liuvoid cmp_NULL_private(private char* p) {
266402804b6SYaxun Liu  if (p != NULL)
267402804b6SYaxun Liu    *p = 0;
268402804b6SYaxun Liu}
269402804b6SYaxun Liu
270402804b6SYaxun Liu// CHECK-LABEL: cmp_NULL_local
271f5f45e5eSYaxun Liu// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
272402804b6SYaxun Liuvoid cmp_NULL_local(local char* p) {
273402804b6SYaxun Liu  if (p != NULL)
274402804b6SYaxun Liu    *p = 0;
275402804b6SYaxun Liu}
276402804b6SYaxun Liu
277402804b6SYaxun Liu// CHECK-LABEL: cmp_NULL_global
278402804b6SYaxun Liu// CHECK: icmp eq i8 addrspace(1)* %p, null
279402804b6SYaxun Liuvoid cmp_NULL_global(global char* p) {
280402804b6SYaxun Liu  if (p != NULL)
281402804b6SYaxun Liu    *p = 0;
282402804b6SYaxun Liu}
283402804b6SYaxun Liu
284402804b6SYaxun Liu// CHECK-LABEL: cmp_NULL_constant
285651bd73cSYaxun Liu// CHECK: icmp eq i8 addrspace(4)* %p, null
286402804b6SYaxun Liuchar cmp_NULL_constant(constant char* p) {
287402804b6SYaxun Liu  if (p != NULL)
288402804b6SYaxun Liu    return *p;
289402804b6SYaxun Liu  else
290402804b6SYaxun Liu    return 0;
291402804b6SYaxun Liu}
292402804b6SYaxun Liu
293402804b6SYaxun Liu// CHECK-LABEL: cmp_NULL_generic
294f5f45e5eSYaxun Liu// CHECK: icmp eq i8* %p, null
295402804b6SYaxun Liuvoid cmp_NULL_generic(generic char* p) {
296402804b6SYaxun Liu  if (p != NULL)
297402804b6SYaxun Liu    *p = 0;
298402804b6SYaxun Liu}
299402804b6SYaxun Liu
300402804b6SYaxun Liu// Test storage 0 as null pointer.
301402804b6SYaxun Liu// CHECK-LABEL: test_storage_null_pointer
302301a6da8SMatt Arsenault// CHECK: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)** %arg_private
303f5f45e5eSYaxun Liu// CHECK: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)** %arg_local
304f5f45e5eSYaxun Liu// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)** %arg_global
305651bd73cSYaxun Liu// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)** %arg_constant
306f5f45e5eSYaxun Liu// CHECK: store i8* null, i8** %arg_generic
307402804b6SYaxun Liuvoid test_storage_null_pointer(private char** arg_private,
308402804b6SYaxun Liu                               local char** arg_local,
309402804b6SYaxun Liu                               global char** arg_global,
310402804b6SYaxun Liu                               constant char** arg_constant,
311402804b6SYaxun Liu                               generic char** arg_generic) {
312402804b6SYaxun Liu   *arg_private = 0;
313402804b6SYaxun Liu   *arg_local = 0;
314402804b6SYaxun Liu   *arg_global = 0;
315402804b6SYaxun Liu   *arg_constant = 0;
316402804b6SYaxun Liu   *arg_generic = 0;
317402804b6SYaxun Liu}
318402804b6SYaxun Liu
319402804b6SYaxun Liu// Test storage NULL as null pointer.
320402804b6SYaxun Liu// CHECK-LABEL: test_storage_null_pointer_NULL
321301a6da8SMatt Arsenault// CHECK: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)** %arg_private
322f5f45e5eSYaxun Liu// CHECK: store i8 addrspace(3)* addrspacecast (i8* null to i8 addrspace(3)*), i8 addrspace(3)** %arg_local
323f5f45e5eSYaxun Liu// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)** %arg_global
324651bd73cSYaxun Liu// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)** %arg_constant
325f5f45e5eSYaxun Liu// CHECK: store i8* null, i8** %arg_generic
326402804b6SYaxun Liuvoid test_storage_null_pointer_NULL(private char** arg_private,
327402804b6SYaxun Liu                                    local char** arg_local,
328402804b6SYaxun Liu                                    global char** arg_global,
329402804b6SYaxun Liu                                    constant char** arg_constant,
330402804b6SYaxun Liu                                    generic char** arg_generic) {
331402804b6SYaxun Liu   *arg_private = NULL;
332402804b6SYaxun Liu   *arg_local = NULL;
333402804b6SYaxun Liu   *arg_global = NULL;
334402804b6SYaxun Liu   *arg_constant = NULL;
335402804b6SYaxun Liu   *arg_generic = NULL;
336402804b6SYaxun Liu}
337402804b6SYaxun Liu
338402804b6SYaxun Liu// Test pass null pointer to function as argument.
339402804b6SYaxun Liuvoid test_pass_null_pointer_arg_calee(private char* arg_private,
340402804b6SYaxun Liu                                      local char* arg_local,
341402804b6SYaxun Liu                                      global char* arg_global,
342402804b6SYaxun Liu                                      constant char* arg_constant,
343402804b6SYaxun Liu                                      generic char* arg_generic);
344402804b6SYaxun Liu
345402804b6SYaxun Liu// CHECK-LABEL: test_pass_null_pointer_arg
346301a6da8SMatt Arsenault// 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)
347301a6da8SMatt Arsenault// 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)
348402804b6SYaxun Liuvoid test_pass_null_pointer_arg(void) {
349402804b6SYaxun Liu  test_pass_null_pointer_arg_calee(0, 0, 0, 0, 0);
350402804b6SYaxun Liu  test_pass_null_pointer_arg_calee(NULL, NULL, NULL, NULL, NULL);
351402804b6SYaxun Liu}
352402804b6SYaxun Liu
353402804b6SYaxun Liu// Test cast null pointer to size_t.
354402804b6SYaxun Liuvoid test_cast_null_pointer_to_sizet_calee(size_t arg_private,
355402804b6SYaxun Liu                                           size_t arg_local,
356402804b6SYaxun Liu                                           size_t arg_global,
357402804b6SYaxun Liu                                           size_t arg_constant,
358402804b6SYaxun Liu                                           size_t arg_generic);
359402804b6SYaxun Liu
360402804b6SYaxun Liu// CHECK-LABEL: test_cast_null_pointer_to_sizet
361086be9fbSDouglas Yung// 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)
362086be9fbSDouglas Yung// 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)
363402804b6SYaxun Liuvoid test_cast_null_pointer_to_sizet(void) {
364402804b6SYaxun Liu  test_cast_null_pointer_to_sizet_calee((size_t)((private char*)0),
365402804b6SYaxun Liu                                        (size_t)((local char*)0),
366402804b6SYaxun Liu                                        (size_t)((global char*)0),
367402804b6SYaxun Liu                                        (size_t)((constant char*)0),
368402804b6SYaxun Liu                                        (size_t)((generic char*)0));
369402804b6SYaxun Liu  test_cast_null_pointer_to_sizet_calee((size_t)((private char*)NULL),
370402804b6SYaxun Liu                                        (size_t)((local char*)NULL),
371402804b6SYaxun Liu                                        (size_t)((global char*)NULL),
372402804b6SYaxun Liu                                        (size_t)((constant char*)0), // NULL cannot be casted to constant pointer since it is defined as a generic pointer
373402804b6SYaxun Liu                                        (size_t)((generic char*)NULL));
374402804b6SYaxun Liu}
375402804b6SYaxun Liu
3762a8c18d9SAlexander Kornienko// Test comparison between null pointers.
377402804b6SYaxun Liu#define TEST_EQ00(addr1, addr2) int test_eq00_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)0; }
378402804b6SYaxun Liu#define TEST_EQ0N(addr1, addr2) int test_eq0N_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; }
379402804b6SYaxun Liu#define TEST_EQN0(addr1, addr2) int test_eqN0_##addr1##_##addr2(void) { return (addr1 char*)NULL == (addr2 char*)0; }
380402804b6SYaxun Liu#define TEST_EQNN(addr1, addr2) int test_eqNN_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; }
381402804b6SYaxun Liu#define TEST_NE00(addr1, addr2) int test_ne00_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)0; }
382402804b6SYaxun Liu#define TEST_NE0N(addr1, addr2) int test_ne0N_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; }
383402804b6SYaxun Liu#define TEST_NEN0(addr1, addr2) int test_neN0_##addr1##_##addr2(void) { return (addr1 char*)NULL != (addr2 char*)0; }
384402804b6SYaxun Liu#define TEST_NENN(addr1, addr2) int test_neNN_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; }
385402804b6SYaxun Liu#define TEST(addr1, addr2) \
386402804b6SYaxun Liu        TEST_EQ00(addr1, addr2) \
387402804b6SYaxun Liu        TEST_EQ0N(addr1, addr2) \
388402804b6SYaxun Liu        TEST_EQN0(addr1, addr2) \
389402804b6SYaxun Liu        TEST_EQNN(addr1, addr2) \
390402804b6SYaxun Liu        TEST_NE00(addr1, addr2) \
391402804b6SYaxun Liu        TEST_NE0N(addr1, addr2) \
392402804b6SYaxun Liu        TEST_NEN0(addr1, addr2) \
393402804b6SYaxun Liu        TEST_NENN(addr1, addr2)
394402804b6SYaxun Liu
395402804b6SYaxun Liu// CHECK-LABEL: test_eq00_generic_private
396402804b6SYaxun Liu// CHECK: ret i32 1
397402804b6SYaxun Liu// CHECK-LABEL: test_eq0N_generic_private
398402804b6SYaxun Liu// CHECK: ret i32 1
399402804b6SYaxun Liu// CHECK-LABEL: test_eqN0_generic_private
400402804b6SYaxun Liu// CHECK: ret i32 1
401402804b6SYaxun Liu// CHECK-LABEL: test_eqNN_generic_private
402402804b6SYaxun Liu// CHECK: ret i32 1
403402804b6SYaxun Liu// CHECK-LABEL: test_ne00_generic_private
404402804b6SYaxun Liu// CHECK: ret i32 0
405402804b6SYaxun Liu// CHECK-LABEL: test_ne0N_generic_private
406402804b6SYaxun Liu// CHECK: ret i32 0
407402804b6SYaxun Liu// CHECK-LABEL: test_neN0_generic_private
408402804b6SYaxun Liu// CHECK: ret i32 0
409402804b6SYaxun Liu// CHECK-LABEL: test_neNN_generic_private
410402804b6SYaxun Liu// CHECK: ret i32 0
411402804b6SYaxun LiuTEST(generic, private)
412402804b6SYaxun Liu
413402804b6SYaxun Liu// CHECK-LABEL: test_eq00_generic_local
414402804b6SYaxun Liu// CHECK: ret i32 1
415402804b6SYaxun Liu// CHECK-LABEL: test_eq0N_generic_local
416402804b6SYaxun Liu// CHECK: ret i32 1
417402804b6SYaxun Liu// CHECK-LABEL: test_eqN0_generic_local
418402804b6SYaxun Liu// CHECK: ret i32 1
419402804b6SYaxun Liu// CHECK-LABEL: test_eqNN_generic_local
420402804b6SYaxun Liu// CHECK: ret i32 1
421402804b6SYaxun Liu// CHECK-LABEL: test_ne00_generic_local
422402804b6SYaxun Liu// CHECK: ret i32 0
423402804b6SYaxun Liu// CHECK-LABEL: test_ne0N_generic_local
424402804b6SYaxun Liu// CHECK: ret i32 0
425402804b6SYaxun Liu// CHECK-LABEL: test_neN0_generic_local
426402804b6SYaxun Liu// CHECK: ret i32 0
427402804b6SYaxun Liu// CHECK-LABEL: test_neNN_generic_local
428402804b6SYaxun Liu// CHECK: ret i32 0
429402804b6SYaxun LiuTEST(generic, local)
430402804b6SYaxun Liu
431402804b6SYaxun Liu// CHECK-LABEL: test_eq00_generic_global
432402804b6SYaxun Liu// CHECK: ret i32 1
433402804b6SYaxun Liu// CHECK-LABEL: test_eq0N_generic_global
434402804b6SYaxun Liu// CHECK: ret i32 1
435402804b6SYaxun Liu// CHECK-LABEL: test_eqN0_generic_global
436402804b6SYaxun Liu// CHECK: ret i32 1
437402804b6SYaxun Liu// CHECK-LABEL: test_eqNN_generic_global
438402804b6SYaxun Liu// CHECK: ret i32 1
439402804b6SYaxun Liu// CHECK-LABEL: test_ne00_generic_global
440402804b6SYaxun Liu// CHECK: ret i32 0
441402804b6SYaxun Liu// CHECK-LABEL: test_ne0N_generic_global
442402804b6SYaxun Liu// CHECK: ret i32 0
443402804b6SYaxun Liu// CHECK-LABEL: test_neN0_generic_global
444402804b6SYaxun Liu// CHECK: ret i32 0
445402804b6SYaxun Liu// CHECK-LABEL: test_neNN_generic_global
446402804b6SYaxun Liu// CHECK: ret i32 0
447402804b6SYaxun LiuTEST(generic, global)
448402804b6SYaxun Liu
449402804b6SYaxun Liu// CHECK-LABEL: test_eq00_generic_generic
450402804b6SYaxun Liu// CHECK: ret i32 1
451402804b6SYaxun Liu// CHECK-LABEL: test_eq0N_generic_generic
452402804b6SYaxun Liu// CHECK: ret i32 1
453402804b6SYaxun Liu// CHECK-LABEL: test_eqN0_generic_generic
454402804b6SYaxun Liu// CHECK: ret i32 1
455402804b6SYaxun Liu// CHECK-LABEL: test_eqNN_generic_generic
456402804b6SYaxun Liu// CHECK: ret i32 1
457402804b6SYaxun Liu// CHECK-LABEL: test_ne00_generic_generic
458402804b6SYaxun Liu// CHECK: ret i32 0
459402804b6SYaxun Liu// CHECK-LABEL: test_ne0N_generic_generic
460402804b6SYaxun Liu// CHECK: ret i32 0
461402804b6SYaxun Liu// CHECK-LABEL: test_neN0_generic_generic
462402804b6SYaxun Liu// CHECK: ret i32 0
463402804b6SYaxun Liu// CHECK-LABEL: test_neNN_generic_generic
464402804b6SYaxun Liu// CHECK: ret i32 0
465402804b6SYaxun LiuTEST(generic, generic)
466402804b6SYaxun Liu
467402804b6SYaxun Liu// CHECK-LABEL: test_eq00_constant_constant
468402804b6SYaxun Liu// CHECK: ret i32 1
469402804b6SYaxun LiuTEST_EQ00(constant, constant)
470402804b6SYaxun Liu
471402804b6SYaxun Liu// Test cast to bool.
472402804b6SYaxun Liu
473402804b6SYaxun Liu// CHECK-LABEL: cast_bool_private
474301a6da8SMatt Arsenault// CHECK: icmp eq i8 addrspace(5)* %p, addrspacecast (i8* null to i8 addrspace(5)*)
475402804b6SYaxun Liuvoid cast_bool_private(private char* p) {
476402804b6SYaxun Liu  if (p)
477402804b6SYaxun Liu    *p = 0;
478402804b6SYaxun Liu}
479402804b6SYaxun Liu
480402804b6SYaxun Liu// CHECK-LABEL: cast_bool_local
481f5f45e5eSYaxun Liu// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
482402804b6SYaxun Liuvoid cast_bool_local(local char* p) {
483402804b6SYaxun Liu  if (p)
484402804b6SYaxun Liu    *p = 0;
485402804b6SYaxun Liu}
486402804b6SYaxun Liu
487402804b6SYaxun Liu// CHECK-LABEL: cast_bool_global
488402804b6SYaxun Liu// CHECK: icmp eq i8 addrspace(1)* %p, null
489402804b6SYaxun Liuvoid cast_bool_global(global char* p) {
490402804b6SYaxun Liu  if (p)
491402804b6SYaxun Liu    *p = 0;
492402804b6SYaxun Liu}
493402804b6SYaxun Liu
494402804b6SYaxun Liu// CHECK-LABEL: cast_bool_constant
495651bd73cSYaxun Liu// CHECK: icmp eq i8 addrspace(4)* %p, null
496402804b6SYaxun Liuchar cast_bool_constant(constant char* p) {
497402804b6SYaxun Liu  if (p)
498402804b6SYaxun Liu    return *p;
499402804b6SYaxun Liu  else
500402804b6SYaxun Liu    return 0;
501402804b6SYaxun Liu}
502402804b6SYaxun Liu
503402804b6SYaxun Liu// CHECK-LABEL: cast_bool_generic
504f5f45e5eSYaxun Liu// CHECK: icmp eq i8* %p, null
505402804b6SYaxun Liuvoid cast_bool_generic(generic char* p) {
506402804b6SYaxun Liu  if (p)
507402804b6SYaxun Liu    *p = 0;
508402804b6SYaxun Liu}
509402804b6SYaxun Liu
510402804b6SYaxun Liu// Test initialize a struct using memset.
511402804b6SYaxun Liu// For large structures which is mostly zero, clang generats llvm.memset for
512402804b6SYaxun Liu// the zero part and store for non-zero members.
513402804b6SYaxun Liutypedef struct {
514402804b6SYaxun Liu  long a, b, c, d;
515402804b6SYaxun Liu  private char *p;
516402804b6SYaxun Liu} StructTy3;
517402804b6SYaxun Liu
518bf5e3e43SMatt Arsenault// CHECK-LABEL: test_memset_private
519cd54c579SDávid Bolvanský// CHECK: call void @llvm.memset.p5i8.i64(i8 addrspace(5)* noundef align 8 {{.*}}, i8 0, i64 32, i1 false)
520301a6da8SMatt Arsenault// CHECK: [[GEP:%.*]] = getelementptr inbounds %struct.StructTy3, %struct.StructTy3 addrspace(5)* %ptr, i32 0, i32 4
521301a6da8SMatt Arsenault// CHECK: store i8 addrspace(5)* addrspacecast (i8* null to i8 addrspace(5)*), i8 addrspace(5)* addrspace(5)* [[GEP]]
522301a6da8SMatt Arsenault// CHECK: [[GEP1:%.*]] = getelementptr inbounds i8, i8 addrspace(5)* {{.*}}, i32 36
523301a6da8SMatt Arsenault// CHECK: [[GEP1_CAST:%.*]] = bitcast i8 addrspace(5)* [[GEP1]] to i32 addrspace(5)*
524301a6da8SMatt Arsenault// CHECK: store i32 0, i32 addrspace(5)* [[GEP1_CAST]], align 4
5253fe7395fSMatt Arsenaultvoid test_memset_private(private StructTy3 *ptr) {
526402804b6SYaxun Liu  StructTy3 S3 = {0, 0, 0, 0, 0};
5273fe7395fSMatt Arsenault  *ptr = S3;
528402804b6SYaxun Liu}
529402804b6SYaxun Liu
530402804b6SYaxun Liu// Test casting literal 0 to pointer.
531402804b6SYaxun Liu// A 0 literal casted to pointer should become a null pointer.
532402804b6SYaxun Liu
533bf5e3e43SMatt Arsenault// CHECK-LABEL: test_cast_0_to_local_ptr
534f5f45e5eSYaxun Liu// CHECK: ret i32 addrspace(3)* addrspacecast (i32* null to i32 addrspace(3)*)
535bf5e3e43SMatt Arsenaultlocal int* test_cast_0_to_local_ptr(void) {
536bf5e3e43SMatt Arsenault  return (local int*)0;
537bf5e3e43SMatt Arsenault}
538bf5e3e43SMatt Arsenault
539bf5e3e43SMatt Arsenault// CHECK-LABEL: test_cast_0_to_private_ptr
540301a6da8SMatt Arsenault// CHECK: ret i32 addrspace(5)* addrspacecast (i32* null to i32 addrspace(5)*)
541bf5e3e43SMatt Arsenaultprivate int* test_cast_0_to_private_ptr(void) {
542402804b6SYaxun Liu  return (private int*)0;
543402804b6SYaxun Liu}
544402804b6SYaxun Liu
545402804b6SYaxun Liu// Test casting non-literal integer with 0 value to pointer.
546402804b6SYaxun Liu// A non-literal integer expression with 0 value is casted to a pointer with
547402804b6SYaxun Liu// zero value.
548402804b6SYaxun Liu
549bf5e3e43SMatt Arsenault// CHECK-LABEL: test_cast_int_to_ptr1_private
550f5f45e5eSYaxun Liu// CHECK: ret i32 addrspace(5)* null
551bf5e3e43SMatt Arsenaultprivate int* test_cast_int_to_ptr1_private(void) {
552402804b6SYaxun Liu  return (private int*)((void)0, 0);
553402804b6SYaxun Liu}
554402804b6SYaxun Liu
555bf5e3e43SMatt Arsenault// CHECK-LABEL: test_cast_int_to_ptr1_local
556bf5e3e43SMatt Arsenault // CHECK: ret i32 addrspace(3)* null
557bf5e3e43SMatt Arsenaultlocal int* test_cast_int_to_ptr1_local(void) {
558bf5e3e43SMatt Arsenault  return (local int*)((void)0, 0);
559bf5e3e43SMatt Arsenault}
560bf5e3e43SMatt Arsenault
561402804b6SYaxun Liu// CHECK-LABEL: test_cast_int_to_ptr2
562f5f45e5eSYaxun Liu// CHECK: ret i32 addrspace(5)* null
563402804b6SYaxun Liuprivate int* test_cast_int_to_ptr2(void) {
564402804b6SYaxun Liu  int x = 0;
565402804b6SYaxun Liu  return (private int*)x;
566402804b6SYaxun Liu}
567402804b6SYaxun Liu
568402804b6SYaxun Liu// Test logical operations.
569402804b6SYaxun Liu// CHECK-LABEL: test_not_nullptr
570402804b6SYaxun Liu// CHECK: ret i32 1
571402804b6SYaxun Liuint test_not_nullptr(void) {
572402804b6SYaxun Liu  return !(private char*)NULL;
573402804b6SYaxun Liu}
574402804b6SYaxun Liu
575402804b6SYaxun Liu// CHECK-LABEL: test_and_nullptr
576402804b6SYaxun Liu// CHECK: ret i32 0
577402804b6SYaxun Liuint test_and_nullptr(int a) {
578402804b6SYaxun Liu  return a && ((private char*)NULL);
579402804b6SYaxun Liu}
580402804b6SYaxun Liu
581bf5e3e43SMatt Arsenault// CHECK-LABEL: test_not_private_ptr
582301a6da8SMatt Arsenault// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(5)* %p, addrspacecast (i8* null to i8 addrspace(5)*)
583402804b6SYaxun Liu// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
584402804b6SYaxun Liu// CHECK: ret i32 %[[lnot_ext]]
585bf5e3e43SMatt Arsenaultint test_not_private_ptr(private char* p) {
586402804b6SYaxun Liu  return !p;
587402804b6SYaxun Liu}
588bf5e3e43SMatt Arsenault
589bf5e3e43SMatt Arsenault// CHECK-LABEL: test_not_local_ptr
590f5f45e5eSYaxun Liu// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(3)* %p, addrspacecast (i8* null to i8 addrspace(3)*)
591bf5e3e43SMatt Arsenault// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32
592bf5e3e43SMatt Arsenault// CHECK: ret i32 %[[lnot_ext]]
593bf5e3e43SMatt Arsenaultint test_not_local_ptr(local char* p) {
594bf5e3e43SMatt Arsenault  return !p;
595bf5e3e43SMatt Arsenault}
596bf5e3e43SMatt Arsenault
597bf5e3e43SMatt Arsenault
598402804b6SYaxun Liu// CHECK-LABEL: test_and_ptr
599301a6da8SMatt Arsenault// CHECK: %[[tobool:.*]] = icmp ne i8 addrspace(5)* %p1, addrspacecast (i8* null to i8 addrspace(5)*)
600f5f45e5eSYaxun Liu// CHECK: %[[tobool1:.*]] = icmp ne i8 addrspace(3)* %p2, addrspacecast (i8* null to i8 addrspace(3)*)
6018a156d1cSJuneyoung Lee// CHECK: %[[res:.*]] = select i1 %[[tobool]], i1 %[[tobool1]], i1 false
602402804b6SYaxun Liu// CHECK: %[[land_ext:.*]] = zext i1 %[[res]] to i32
603402804b6SYaxun Liu// CHECK: ret i32 %[[land_ext]]
604402804b6SYaxun Liuint test_and_ptr(private char* p1, local char* p2) {
605402804b6SYaxun Liu  return p1 && p2;
606402804b6SYaxun Liu}
607402804b6SYaxun Liu
608402804b6SYaxun Liu// Test folding of null pointer in function scope.
609bf5e3e43SMatt Arsenault// NOOPT-LABEL: test_fold_private
610402804b6SYaxun Liu// NOOPT: call void @test_fold_callee
611f5f45e5eSYaxun Liu// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)* addrspace(5)* %glob, align 8
612402804b6SYaxun Liu// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
613402804b6SYaxun Liu// NOOPT: call void @test_fold_callee
614301a6da8SMatt Arsenault// NOOPT: %{{.*}} = add nsw i64 %1, sext (i32 ptrtoint (i32 addrspace(5)* addrspacecast (i32* null to i32 addrspace(5)*) to i32) to i64)
615402804b6SYaxun Liu// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
616402804b6SYaxun Liuvoid test_fold_callee(void);
617bf5e3e43SMatt Arsenaultvoid test_fold_private(void) {
618402804b6SYaxun Liu  global int* glob = (test_fold_callee(), (global int*)(generic char*)0);
619402804b6SYaxun Liu  long x = glob - (global int*)(generic char*)0;
620402804b6SYaxun Liu  x = x + (int)(test_fold_callee(), (private int*)(generic char*)(global short*)0);
621402804b6SYaxun Liu  x = x - (int)((private int*)0 == (private int*)(generic char*)0);
622402804b6SYaxun Liu}
623bf5e3e43SMatt Arsenault
624bf5e3e43SMatt Arsenault// NOOPT-LABEL: test_fold_local
625bf5e3e43SMatt Arsenault// NOOPT: call void @test_fold_callee
626f5f45e5eSYaxun Liu// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)* addrspace(5)* %glob, align 8
627bf5e3e43SMatt Arsenault// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0
628bf5e3e43SMatt Arsenault// NOOPT: call void @test_fold_callee
629f5f45e5eSYaxun Liu// NOOPT: %{{.*}} = add nsw i64 %{{.*}}, sext (i32 ptrtoint (i32 addrspace(3)* addrspacecast (i32* null to i32 addrspace(3)*) to i32) to i64)
630bf5e3e43SMatt Arsenault// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1
631bf5e3e43SMatt Arsenaultvoid test_fold_local(void) {
632bf5e3e43SMatt Arsenault  global int* glob = (test_fold_callee(), (global int*)(generic char*)0);
633bf5e3e43SMatt Arsenault  long x = glob - (global int*)(generic char*)0;
634bf5e3e43SMatt Arsenault  x = x + (int)(test_fold_callee(), (local int*)(generic char*)(global short*)0);
635bf5e3e43SMatt Arsenault  x = x - (int)((local int*)0 == (local int*)(generic char*)0);
636bf5e3e43SMatt Arsenault}
637