1// 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 3 4typedef struct { 5 private char *p1; 6 local char *p2; 7 constant char *p3; 8 global char *p4; 9 generic char *p5; 10} StructTy1; 11 12typedef struct { 13 constant char *p3; 14 global char *p4; 15 generic char *p5; 16} StructTy2; 17 18// LLVM requests global variable with common linkage to be initialized with zeroinitializer, therefore use -fno-common 19// to suppress common linkage for tentative definition. 20 21// Test 0 as initializer. 22 23// CHECK: @private_p = local_unnamed_addr addrspace(1) global i8* null, align 4 24private char *private_p = 0; 25 26// CHECK: @local_p = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4 27local char *local_p = 0; 28 29// CHECK: @global_p = local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 4 30global char *global_p = 0; 31 32// CHECK: @constant_p = local_unnamed_addr addrspace(1) global i8 addrspace(2)* null, align 4 33constant char *constant_p = 0; 34 35// CHECK: @generic_p = local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 4 36generic char *generic_p = 0; 37 38// Test NULL as initializer. 39 40// CHECK: @private_p_NULL = local_unnamed_addr addrspace(1) global i8* null, align 4 41private char *private_p_NULL = NULL; 42 43// CHECK: @local_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4 44local char *local_p_NULL = NULL; 45 46// CHECK: @global_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 4 47global char *global_p_NULL = NULL; 48 49// CHECK: @constant_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(2)* null, align 4 50constant char *constant_p_NULL = NULL; 51 52// CHECK: @generic_p_NULL = local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 4 53generic char *generic_p_NULL = NULL; 54 55// Test constant folding of null pointer. 56// A null pointer should be folded to a null pointer in the target address space. 57 58// CHECK: @fold_generic = local_unnamed_addr addrspace(1) global i32 addrspace(4)* null, align 4 59generic int *fold_generic = (global int*)(generic float*)(private char*)0; 60 61// CHECK: @fold_priv = local_unnamed_addr addrspace(1) global i16* null, align 4 62private short *fold_priv = (private short*)(generic int*)(global void*)0; 63 64// CHECK: @fold_priv_arith = local_unnamed_addr addrspace(1) global i8* inttoptr (i32 10 to i8*), align 4 65private char *fold_priv_arith = (private char*)0 + 10; 66 67// CHECK: @fold_int = local_unnamed_addr addrspace(1) global i32 14, align 4 68int fold_int = (int)(private void*)(generic char*)(global int*)0 + 14; 69 70// CHECK: @fold_int2 = local_unnamed_addr addrspace(1) global i32 13, align 4 71int fold_int2 = (int) ((private void*)0 + 13); 72 73// CHECK: @fold_int3 = local_unnamed_addr addrspace(1) global i32 0, align 4 74int fold_int3 = (int) ((private int*)0); 75 76// CHECK: @fold_int4 = local_unnamed_addr addrspace(1) global i32 8, align 4 77int fold_int4 = (int) &((private int*)0)[2]; 78 79// CHECK: @fold_int5 = local_unnamed_addr addrspace(1) global i32 4, align 4 80int fold_int5 = (int) &((private StructTy1*)0)->p2; 81 82 83// CHECK: @fold_int_local = local_unnamed_addr addrspace(1) global i32 13, align 4 84int fold_int_local = (int)(local void*)(generic char*)(global int*)0 + 14; 85 86// CHECK: @fold_int2_local = local_unnamed_addr addrspace(1) global i32 12, align 4 87int fold_int2_local = (int) ((local void*)0 + 13); 88 89// CHECK: @fold_int3_local = local_unnamed_addr addrspace(1) global i32 -1, align 4 90int fold_int3_local = (int) ((local int*)0); 91 92// CHECK: @fold_int4_local = local_unnamed_addr addrspace(1) global i32 7, align 4 93int fold_int4_local = (int) &((local int*)0)[2]; 94 95// CHECK: @fold_int5_local = local_unnamed_addr addrspace(1) global i32 3, align 4 96int fold_int5_local = (int) &((local StructTy1*)0)->p2; 97 98 99// Test static variable initialization. 100 101// NOOPT: @test_static_var_private.sp1 = internal addrspace(1) global i8* null, align 4 102// NOOPT: @test_static_var_private.sp2 = internal addrspace(1) global i8* null, align 4 103// NOOPT: @test_static_var_private.sp3 = internal addrspace(1) global i8* null, align 4 104// NOOPT: @test_static_var_private.sp4 = internal addrspace(1) global i8* null, align 4 105// NOOPT: @test_static_var_private.sp5 = internal addrspace(1) global i8* null, align 4 106// NOOPT: @test_static_var_private.SS1 = internal addrspace(1) global %struct.StructTy1 { i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(2)* null, i8 addrspace(1)* null, i8 addrspace(4)* null }, align 4 107// NOOPT: @test_static_var_private.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 4 108 109void test_static_var_private(void) { 110 static private char *sp1 = 0; 111 static private char *sp2 = NULL; 112 static private char *sp3; 113 static private char *sp4 = (private char*)((void)0, 0); 114 const int x = 0; 115 static private char *sp5 = (private char*)x; 116 static StructTy1 SS1; 117 static StructTy2 SS2; 118} 119 120// NOOPT: @test_static_var_local.sp1 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4 121// NOOPT: @test_static_var_local.sp2 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4 122// NOOPT: @test_static_var_local.sp3 = internal addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4 123// NOOPT: @test_static_var_local.sp4 = internal addrspace(1) global i8 addrspace(3)* null, align 4 124// NOOPT: @test_static_var_local.sp5 = internal addrspace(1) global i8 addrspace(3)* null, align 4 125// NOOPT: @test_static_var_local.SS1 = internal addrspace(1) global %struct.StructTy1 { i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(2)* null, i8 addrspace(1)* null, i8 addrspace(4)* null }, align 4 126// NOOPT: @test_static_var_local.SS2 = internal addrspace(1) global %struct.StructTy2 zeroinitializer, align 4 127void test_static_var_local(void) { 128 static local char *sp1 = 0; 129 static local char *sp2 = NULL; 130 static local char *sp3; 131 static local char *sp4 = (local char*)((void)0, 0); 132 const int x = 0; 133 static local char *sp5 = (local char*)x; 134 static StructTy1 SS1; 135 static StructTy2 SS2; 136} 137 138// Test function-scope variable initialization. 139// NOOPT-LABEL: @test_func_scope_var_private( 140// NOOPT: store i8* null, i8** %sp1, align 4 141// NOOPT: store i8* null, i8** %sp2, align 4 142// NOOPT: store i8* null, i8** %sp3, align 4 143// NOOPT: store i8* null, i8** %sp4, align 4 144// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1* %SS1 to i8* 145// NOOPT: call void @llvm.memcpy.p0i8.p2i8.i64(i8* %[[SS1]], i8 addrspace(2)* bitcast (%struct.StructTy1 addrspace(2)* @test_func_scope_var_private.SS1 to i8 addrspace(2)*), i64 32, i32 4, i1 false) 146// NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2* %SS2 to i8* 147// NOOPT: call void @llvm.memset.p0i8.i64(i8* %[[SS2]], i8 0, i64 24, i32 4, i1 false) 148void test_func_scope_var_private(void) { 149 private char *sp1 = 0; 150 private char *sp2 = NULL; 151 private char *sp3 = (private char*)((void)0, 0); 152 const int x = 0; 153 private char *sp4 = (private char*)x; 154 StructTy1 SS1 = {0, 0, 0, 0, 0}; 155 StructTy2 SS2 = {0, 0, 0}; 156} 157 158// Test function-scope variable initialization. 159// NOOPT-LABEL: @test_func_scope_var_local( 160// NOOPT: store i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(3)** %sp1, align 4 161// NOOPT: store i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(3)** %sp2, align 4 162// NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)** %sp3, align 4 163// NOOPT: store i8 addrspace(3)* null, i8 addrspace(3)** %sp4, align 4 164// NOOPT: %[[SS1:.*]] = bitcast %struct.StructTy1* %SS1 to i8* 165// NOOPT: call void @llvm.memcpy.p0i8.p2i8.i64(i8* %[[SS1]], i8 addrspace(2)* bitcast (%struct.StructTy1 addrspace(2)* @test_func_scope_var_local.SS1 to i8 addrspace(2)*), i64 32, i32 4, i1 false) 166// NOOPT: %[[SS2:.*]] = bitcast %struct.StructTy2* %SS2 to i8* 167// NOOPT: call void @llvm.memset.p0i8.i64(i8* %[[SS2]], i8 0, i64 24, i32 4, i1 false) 168void test_func_scope_var_local(void) { 169 local char *sp1 = 0; 170 local char *sp2 = NULL; 171 local char *sp3 = (local char*)((void)0, 0); 172 const int x = 0; 173 local char *sp4 = (local char*)x; 174 StructTy1 SS1 = {0, 0, 0, 0, 0}; 175 StructTy2 SS2 = {0, 0, 0}; 176} 177 178 179// Test default initialization of pointers. 180 181// Tentative definition of global variables with non-zero initializer 182// cannot have common linkage since common linkage requires zero initialization 183// and does not have explicit section. 184 185// CHECK: @p1 = common local_unnamed_addr addrspace(1) global i8* null, align 4 186private char *p1; 187 188// CHECK: @p2 = weak local_unnamed_addr addrspace(1) global i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), align 4 189local char *p2; 190 191// CHECK: @p3 = common local_unnamed_addr addrspace(1) global i8 addrspace(2)* null, align 4 192constant char *p3; 193 194// CHECK: @p4 = common local_unnamed_addr addrspace(1) global i8 addrspace(1)* null, align 4 195global char *p4; 196 197// CHECK: @p5 = common local_unnamed_addr addrspace(1) global i8 addrspace(4)* null, align 4 198generic char *p5; 199 200// Test default initialization of sturcture. 201 202// CHECK: @S1 = weak local_unnamed_addr addrspace(1) global %struct.StructTy1 { i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(2)* null, i8 addrspace(1)* null, i8 addrspace(4)* null }, align 4 203StructTy1 S1; 204 205// CHECK: @S2 = common local_unnamed_addr addrspace(1) global %struct.StructTy2 zeroinitializer, align 4 206StructTy2 S2; 207 208// Test default initialization of array. 209// CHECK: @A1 = weak local_unnamed_addr addrspace(1) global [2 x %struct.StructTy1] [%struct.StructTy1 { i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(2)* null, i8 addrspace(1)* null, i8 addrspace(4)* null }, %struct.StructTy1 { i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(2)* null, i8 addrspace(1)* null, i8 addrspace(4)* null }], align 4 210StructTy1 A1[2]; 211 212// CHECK: @A2 = common local_unnamed_addr addrspace(1) global [2 x %struct.StructTy2] zeroinitializer, align 4 213StructTy2 A2[2]; 214 215// Test comparison with 0. 216 217// CHECK-LABEL: cmp_private 218// CHECK: icmp eq i8* %p, null 219void cmp_private(private char* p) { 220 if (p != 0) 221 *p = 0; 222} 223 224// CHECK-LABEL: cmp_local 225// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*) 226void cmp_local(local char* p) { 227 if (p != 0) 228 *p = 0; 229} 230 231// CHECK-LABEL: cmp_global 232// CHECK: icmp eq i8 addrspace(1)* %p, null 233void cmp_global(global char* p) { 234 if (p != 0) 235 *p = 0; 236} 237 238// CHECK-LABEL: cmp_constant 239// CHECK: icmp eq i8 addrspace(2)* %p, null 240char cmp_constant(constant char* p) { 241 if (p != 0) 242 return *p; 243 else 244 return 0; 245} 246 247// CHECK-LABEL: cmp_generic 248// CHECK: icmp eq i8 addrspace(4)* %p, null 249void cmp_generic(generic char* p) { 250 if (p != 0) 251 *p = 0; 252} 253 254// Test comparison with NULL. 255 256// CHECK-LABEL: cmp_NULL_private 257// CHECK: icmp eq i8* %p, null 258void cmp_NULL_private(private char* p) { 259 if (p != NULL) 260 *p = 0; 261} 262 263// CHECK-LABEL: cmp_NULL_local 264// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*) 265void cmp_NULL_local(local char* p) { 266 if (p != NULL) 267 *p = 0; 268} 269 270// CHECK-LABEL: cmp_NULL_global 271// CHECK: icmp eq i8 addrspace(1)* %p, null 272void cmp_NULL_global(global char* p) { 273 if (p != NULL) 274 *p = 0; 275} 276 277// CHECK-LABEL: cmp_NULL_constant 278// CHECK: icmp eq i8 addrspace(2)* %p, null 279char cmp_NULL_constant(constant char* p) { 280 if (p != NULL) 281 return *p; 282 else 283 return 0; 284} 285 286// CHECK-LABEL: cmp_NULL_generic 287// CHECK: icmp eq i8 addrspace(4)* %p, null 288void cmp_NULL_generic(generic char* p) { 289 if (p != NULL) 290 *p = 0; 291} 292 293// Test storage 0 as null pointer. 294// CHECK-LABEL: test_storage_null_pointer 295// CHECK: store i8* null, i8* addrspace(4)* %arg_private 296// CHECK: store i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(4)* %arg_local 297// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)* addrspace(4)* %arg_global 298// CHECK: store i8 addrspace(2)* null, i8 addrspace(2)* addrspace(4)* %arg_constant 299// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)* addrspace(4)* %arg_generic 300void test_storage_null_pointer(private char** arg_private, 301 local char** arg_local, 302 global char** arg_global, 303 constant char** arg_constant, 304 generic char** arg_generic) { 305 *arg_private = 0; 306 *arg_local = 0; 307 *arg_global = 0; 308 *arg_constant = 0; 309 *arg_generic = 0; 310} 311 312// Test storage NULL as null pointer. 313// CHECK-LABEL: test_storage_null_pointer_NULL 314// CHECK: store i8* null, i8* addrspace(4)* %arg_private 315// CHECK: store i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(3)* addrspace(4)* %arg_local 316// CHECK: store i8 addrspace(1)* null, i8 addrspace(1)* addrspace(4)* %arg_global 317// CHECK: store i8 addrspace(2)* null, i8 addrspace(2)* addrspace(4)* %arg_constant 318// CHECK: store i8 addrspace(4)* null, i8 addrspace(4)* addrspace(4)* %arg_generic 319void test_storage_null_pointer_NULL(private char** arg_private, 320 local char** arg_local, 321 global char** arg_global, 322 constant char** arg_constant, 323 generic char** arg_generic) { 324 *arg_private = NULL; 325 *arg_local = NULL; 326 *arg_global = NULL; 327 *arg_constant = NULL; 328 *arg_generic = NULL; 329} 330 331// Test pass null pointer to function as argument. 332void test_pass_null_pointer_arg_calee(private char* arg_private, 333 local char* arg_local, 334 global char* arg_global, 335 constant char* arg_constant, 336 generic char* arg_generic); 337 338// CHECK-LABEL: test_pass_null_pointer_arg 339// CHECK: call void @test_pass_null_pointer_arg_calee(i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(2)* null, i8 addrspace(4)* null) 340// CHECK: call void @test_pass_null_pointer_arg_calee(i8* null, i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*), i8 addrspace(1)* null, i8 addrspace(2)* null, i8 addrspace(4)* null) 341void test_pass_null_pointer_arg(void) { 342 test_pass_null_pointer_arg_calee(0, 0, 0, 0, 0); 343 test_pass_null_pointer_arg_calee(NULL, NULL, NULL, NULL, NULL); 344} 345 346// Test cast null pointer to size_t. 347void test_cast_null_pointer_to_sizet_calee(size_t arg_private, 348 size_t arg_local, 349 size_t arg_global, 350 size_t arg_constant, 351 size_t arg_generic); 352 353// CHECK-LABEL: test_cast_null_pointer_to_sizet 354// CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 0, i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0) 355// CHECK: call void @test_cast_null_pointer_to_sizet_calee(i64 0, i64 ptrtoint (i8 addrspace(3)* addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*) to i64), i64 0, i64 0, i64 0) 356void test_cast_null_pointer_to_sizet(void) { 357 test_cast_null_pointer_to_sizet_calee((size_t)((private char*)0), 358 (size_t)((local char*)0), 359 (size_t)((global char*)0), 360 (size_t)((constant char*)0), 361 (size_t)((generic char*)0)); 362 test_cast_null_pointer_to_sizet_calee((size_t)((private char*)NULL), 363 (size_t)((local char*)NULL), 364 (size_t)((global char*)NULL), 365 (size_t)((constant char*)0), // NULL cannot be casted to constant pointer since it is defined as a generic pointer 366 (size_t)((generic char*)NULL)); 367} 368 369// Test comparision between null pointers. 370#define TEST_EQ00(addr1, addr2) int test_eq00_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)0; } 371#define TEST_EQ0N(addr1, addr2) int test_eq0N_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; } 372#define TEST_EQN0(addr1, addr2) int test_eqN0_##addr1##_##addr2(void) { return (addr1 char*)NULL == (addr2 char*)0; } 373#define TEST_EQNN(addr1, addr2) int test_eqNN_##addr1##_##addr2(void) { return (addr1 char*)0 == (addr2 char*)NULL; } 374#define TEST_NE00(addr1, addr2) int test_ne00_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)0; } 375#define TEST_NE0N(addr1, addr2) int test_ne0N_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; } 376#define TEST_NEN0(addr1, addr2) int test_neN0_##addr1##_##addr2(void) { return (addr1 char*)NULL != (addr2 char*)0; } 377#define TEST_NENN(addr1, addr2) int test_neNN_##addr1##_##addr2(void) { return (addr1 char*)0 != (addr2 char*)NULL; } 378#define TEST(addr1, addr2) \ 379 TEST_EQ00(addr1, addr2) \ 380 TEST_EQ0N(addr1, addr2) \ 381 TEST_EQN0(addr1, addr2) \ 382 TEST_EQNN(addr1, addr2) \ 383 TEST_NE00(addr1, addr2) \ 384 TEST_NE0N(addr1, addr2) \ 385 TEST_NEN0(addr1, addr2) \ 386 TEST_NENN(addr1, addr2) 387 388// CHECK-LABEL: test_eq00_generic_private 389// CHECK: ret i32 1 390// CHECK-LABEL: test_eq0N_generic_private 391// CHECK: ret i32 1 392// CHECK-LABEL: test_eqN0_generic_private 393// CHECK: ret i32 1 394// CHECK-LABEL: test_eqNN_generic_private 395// CHECK: ret i32 1 396// CHECK-LABEL: test_ne00_generic_private 397// CHECK: ret i32 0 398// CHECK-LABEL: test_ne0N_generic_private 399// CHECK: ret i32 0 400// CHECK-LABEL: test_neN0_generic_private 401// CHECK: ret i32 0 402// CHECK-LABEL: test_neNN_generic_private 403// CHECK: ret i32 0 404TEST(generic, private) 405 406// CHECK-LABEL: test_eq00_generic_local 407// CHECK: ret i32 1 408// CHECK-LABEL: test_eq0N_generic_local 409// CHECK: ret i32 1 410// CHECK-LABEL: test_eqN0_generic_local 411// CHECK: ret i32 1 412// CHECK-LABEL: test_eqNN_generic_local 413// CHECK: ret i32 1 414// CHECK-LABEL: test_ne00_generic_local 415// CHECK: ret i32 0 416// CHECK-LABEL: test_ne0N_generic_local 417// CHECK: ret i32 0 418// CHECK-LABEL: test_neN0_generic_local 419// CHECK: ret i32 0 420// CHECK-LABEL: test_neNN_generic_local 421// CHECK: ret i32 0 422TEST(generic, local) 423 424// CHECK-LABEL: test_eq00_generic_global 425// CHECK: ret i32 1 426// CHECK-LABEL: test_eq0N_generic_global 427// CHECK: ret i32 1 428// CHECK-LABEL: test_eqN0_generic_global 429// CHECK: ret i32 1 430// CHECK-LABEL: test_eqNN_generic_global 431// CHECK: ret i32 1 432// CHECK-LABEL: test_ne00_generic_global 433// CHECK: ret i32 0 434// CHECK-LABEL: test_ne0N_generic_global 435// CHECK: ret i32 0 436// CHECK-LABEL: test_neN0_generic_global 437// CHECK: ret i32 0 438// CHECK-LABEL: test_neNN_generic_global 439// CHECK: ret i32 0 440TEST(generic, global) 441 442// CHECK-LABEL: test_eq00_generic_generic 443// CHECK: ret i32 1 444// CHECK-LABEL: test_eq0N_generic_generic 445// CHECK: ret i32 1 446// CHECK-LABEL: test_eqN0_generic_generic 447// CHECK: ret i32 1 448// CHECK-LABEL: test_eqNN_generic_generic 449// CHECK: ret i32 1 450// CHECK-LABEL: test_ne00_generic_generic 451// CHECK: ret i32 0 452// CHECK-LABEL: test_ne0N_generic_generic 453// CHECK: ret i32 0 454// CHECK-LABEL: test_neN0_generic_generic 455// CHECK: ret i32 0 456// CHECK-LABEL: test_neNN_generic_generic 457// CHECK: ret i32 0 458TEST(generic, generic) 459 460// CHECK-LABEL: test_eq00_constant_constant 461// CHECK: ret i32 1 462TEST_EQ00(constant, constant) 463 464// Test cast to bool. 465 466// CHECK-LABEL: cast_bool_private 467// CHECK: icmp eq i8* %p, null 468void cast_bool_private(private char* p) { 469 if (p) 470 *p = 0; 471} 472 473// CHECK-LABEL: cast_bool_local 474// CHECK: icmp eq i8 addrspace(3)* %p, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*) 475void cast_bool_local(local char* p) { 476 if (p) 477 *p = 0; 478} 479 480// CHECK-LABEL: cast_bool_global 481// CHECK: icmp eq i8 addrspace(1)* %p, null 482void cast_bool_global(global char* p) { 483 if (p) 484 *p = 0; 485} 486 487// CHECK-LABEL: cast_bool_constant 488// CHECK: icmp eq i8 addrspace(2)* %p, null 489char cast_bool_constant(constant char* p) { 490 if (p) 491 return *p; 492 else 493 return 0; 494} 495 496// CHECK-LABEL: cast_bool_generic 497// CHECK: icmp eq i8 addrspace(4)* %p, null 498void cast_bool_generic(generic char* p) { 499 if (p) 500 *p = 0; 501} 502 503// Test initialize a struct using memset. 504// For large structures which is mostly zero, clang generats llvm.memset for 505// the zero part and store for non-zero members. 506typedef struct { 507 long a, b, c, d; 508 private char *p; 509} StructTy3; 510 511// CHECK-LABEL: test_memset_private 512// CHECK: call void @llvm.memset.p0i8.i64(i8* nonnull {{.*}}, i8 0, i64 40, i32 8, i1 false) 513StructTy3 test_memset_private(void) { 514 StructTy3 S3 = {0, 0, 0, 0, 0}; 515 return S3; 516} 517 518// Test casting literal 0 to pointer. 519// A 0 literal casted to pointer should become a null pointer. 520 521// CHECK-LABEL: test_cast_0_to_local_ptr 522// CHECK: ret i32 addrspace(3)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(3)*) 523local int* test_cast_0_to_local_ptr(void) { 524 return (local int*)0; 525} 526 527// CHECK-LABEL: test_cast_0_to_private_ptr 528// CHECK: ret i32* null 529private int* test_cast_0_to_private_ptr(void) { 530 return (private int*)0; 531} 532 533// Test casting non-literal integer with 0 value to pointer. 534// A non-literal integer expression with 0 value is casted to a pointer with 535// zero value. 536 537// CHECK-LABEL: test_cast_int_to_ptr1_private 538// CHECK: ret i32* null 539private int* test_cast_int_to_ptr1_private(void) { 540 return (private int*)((void)0, 0); 541} 542 543// CHECK-LABEL: test_cast_int_to_ptr1_local 544 // CHECK: ret i32 addrspace(3)* null 545local int* test_cast_int_to_ptr1_local(void) { 546 return (local int*)((void)0, 0); 547} 548 549// CHECK-LABEL: test_cast_int_to_ptr2 550// CHECK: ret i32* null 551private int* test_cast_int_to_ptr2(void) { 552 int x = 0; 553 return (private int*)x; 554} 555 556// Test logical operations. 557// CHECK-LABEL: test_not_nullptr 558// CHECK: ret i32 1 559int test_not_nullptr(void) { 560 return !(private char*)NULL; 561} 562 563// CHECK-LABEL: test_and_nullptr 564// CHECK: ret i32 0 565int test_and_nullptr(int a) { 566 return a && ((private char*)NULL); 567} 568 569// CHECK-LABEL: test_not_private_ptr 570// CHECK: %[[lnot:.*]] = icmp eq i8* %p, null 571// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32 572// CHECK: ret i32 %[[lnot_ext]] 573int test_not_private_ptr(private char* p) { 574 return !p; 575} 576 577// CHECK-LABEL: test_not_local_ptr 578// CHECK: %[[lnot:.*]] = icmp eq i8 addrspace(3)* %p, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*) 579// CHECK: %[[lnot_ext:.*]] = zext i1 %[[lnot]] to i32 580// CHECK: ret i32 %[[lnot_ext]] 581int test_not_local_ptr(local char* p) { 582 return !p; 583} 584 585 586// CHECK-LABEL: test_and_ptr 587// CHECK: %[[tobool:.*]] = icmp ne i8* %p1, null 588// CHECK: %[[tobool1:.*]] = icmp ne i8 addrspace(3)* %p2, addrspacecast (i8 addrspace(4)* null to i8 addrspace(3)*) 589// CHECK: %[[res:.*]] = and i1 %[[tobool]], %[[tobool1]] 590// CHECK: %[[land_ext:.*]] = zext i1 %[[res]] to i32 591// CHECK: ret i32 %[[land_ext]] 592int test_and_ptr(private char* p1, local char* p2) { 593 return p1 && p2; 594} 595 596// Test folding of null pointer in function scope. 597// NOOPT-LABEL: test_fold_private 598// NOOPT: call void @test_fold_callee 599// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)** %glob, align 4 600// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0 601// NOOPT: call void @test_fold_callee 602// NOOPT: %{{.*}} = add nsw i64 %{{.*}}, 0 603// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1 604void test_fold_callee(void); 605void test_fold_private(void) { 606 global int* glob = (test_fold_callee(), (global int*)(generic char*)0); 607 long x = glob - (global int*)(generic char*)0; 608 x = x + (int)(test_fold_callee(), (private int*)(generic char*)(global short*)0); 609 x = x - (int)((private int*)0 == (private int*)(generic char*)0); 610} 611 612// NOOPT-LABEL: test_fold_local 613// NOOPT: call void @test_fold_callee 614// NOOPT: store i32 addrspace(1)* null, i32 addrspace(1)** %glob, align 4 615// NOOPT: %{{.*}} = sub i64 %{{.*}}, 0 616// NOOPT: call void @test_fold_callee 617// NOOPT: %{{.*}} = add nsw i64 %{{.*}}, sext (i32 ptrtoint (i32 addrspace(3)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(3)*) to i32) to i64) 618// NOOPT: %{{.*}} = sub nsw i64 %{{.*}}, 1 619void test_fold_local(void) { 620 global int* glob = (test_fold_callee(), (global int*)(generic char*)0); 621 long x = glob - (global int*)(generic char*)0; 622 x = x + (int)(test_fold_callee(), (local int*)(generic char*)(global short*)0); 623 x = x - (int)((local int*)0 == (local int*)(generic char*)0); 624} 625