1// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -ffake-address-space-map -cl-std=CL2.0 -emit-llvm -o - | FileCheck %s
2// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -ffake-address-space-map -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - | FileCheck %s
3// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -cl-std=CL2.0 -emit-llvm -o - | FileCheck --check-prefix=CHECK-NOFAKE %s
4// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - | FileCheck --check-prefix=CHECK-NOFAKE %s
5// When -ffake-address-space-map is not used, all addr space mapped to 0 for x86_64.
6
7// test that we generate address space casts everywhere we need conversions of
8// pointers to different address spaces
9
10// CHECK: define{{.*}} void @test
11void test(global int *arg_glob, generic int *arg_gen,
12          __attribute__((opencl_global_device)) int *arg_device,
13          __attribute__((opencl_global_host)) int *arg_host) {
14  int var_priv;
15  arg_gen = arg_glob; // implicit cast global -> generic
16  // CHECK: %{{[0-9]+}} = addrspacecast i32 addrspace(1)* %{{[0-9]+}} to i32 addrspace(4)*
17  // CHECK-NOFAKE-NOT: addrspacecast
18
19  arg_gen = &var_priv; // implicit cast with obtaining adr, private -> generic
20  // CHECK: %{{[._a-z0-9]+}} = addrspacecast i32* %{{[._a-z0-9]+}} to i32 addrspace(4)*
21  // CHECK-NOFAKE-NOT: addrspacecast
22
23  arg_glob = (global int *)arg_gen; // explicit cast
24  // CHECK: %{{[0-9]+}} = addrspacecast i32 addrspace(4)* %{{[0-9]+}} to i32 addrspace(1)*
25  // CHECK-NOFAKE-NOT: addrspacecast
26
27  global int *var_glob =
28      (global int *)arg_glob; // explicit cast in the same address space
29  // CHECK-NOT: %{{[0-9]+}} = addrspacecast i32 addrspace(1)* %{{[0-9]+}} to i32 addrspace(1)*
30  // CHECK-NOFAKE-NOT: addrspacecast
31
32  var_priv = arg_gen - arg_glob; // arithmetic operation
33  // CHECK: %{{.*}} = ptrtoint i32 addrspace(4)* %{{.*}} to i64
34  // CHECK: %{{.*}} = ptrtoint i32 addrspace(1)* %{{.*}} to i64
35  // CHECK-NOFAKE: %{{.*}} = ptrtoint i32* %{{.*}} to i64
36  // CHECK-NOFAKE: %{{.*}} = ptrtoint i32* %{{.*}} to i64
37
38  var_priv = arg_gen > arg_glob; // comparison
39  // CHECK: %{{[0-9]+}} = addrspacecast i32 addrspace(1)* %{{[0-9]+}} to i32 addrspace(4)*
40
41  generic void *var_gen_v = arg_glob;
42  // CHECK: addrspacecast
43  // CHECK-NOT: bitcast
44  // CHECK-NOFAKE: bitcast
45  // CHECK-NOFAKE-NOT: addrspacecast
46
47  arg_glob = arg_device; // implicit cast
48  // CHECK: addrspacecast
49  // CHECK-NOFAKE-NOT: addrspacecast
50
51  arg_glob = arg_host; // implicit cast
52  // CHECK: addrspacecast
53  // CHECK-NOFAKE-NOT: addrspacecast
54
55  arg_glob = (global int *)arg_device; // explicit cast
56  // CHECK: addrspacecast
57  // CHECK-NOFAKE-NOT: addrspacecast
58
59  arg_glob = (global int *)arg_host; // explicit cast
60  // CHECK: addrspacecast
61  // CHECK-NOFAKE-NOT: addrspacecast
62
63  arg_device = (__attribute((opencl_global_device)) int *)arg_glob; // explicit cast
64  // CHECK: addrspacecast
65  // CHECK-NOFAKE-NOT: addrspacecast
66
67  arg_host = (__attribute((opencl_global_host)) int *)arg_glob; // explicit cast
68  // CHECK: addrspacecast
69  // CHECK-NOFAKE-NOT: addrspacecast
70}
71
72// Test ternary operator.
73// CHECK: define{{.*}} void @test_ternary
74void test_ternary(void) {
75  global int *var_glob;
76  generic int *var_gen;
77  generic int *var_gen2;
78  generic float *var_gen_f;
79  generic void *var_gen_v;
80
81  var_gen = var_gen ? var_gen : var_gen2; // operands of the same addr spaces and the same type
82  // CHECK: icmp
83  // CHECK-NOT: addrspacecast
84  // CHECK-NOT: bitcast
85  // CHECK: phi
86  // CHECK: store i32 addrspace(4)* %{{.+}}, i32 addrspace(4)** %{{.+}}
87
88  var_gen = var_gen ? var_gen : var_glob; // operands of overlapping addr spaces and the same type
89  // CHECK: icmp
90  // CHECK-NOT: bitcast
91  // CHECK: %{{.+}} = addrspacecast i32 addrspace(1)* %{{.+}} to i32 addrspace(4)*
92  // CHECK: phi
93  // CHECK: store
94
95  typedef int int_t;
96  global int_t *var_glob_typedef;
97  var_gen = var_gen ? var_gen : var_glob_typedef; // operands of overlapping addr spaces and equivalent types
98  // CHECK: icmp
99  // CHECK-NOT: bitcast
100  // CHECK: %{{.+}} = addrspacecast i32 addrspace(1)* %{{.+}} to i32 addrspace(4)*
101  // CHECK: phi
102  // CHECK: store
103
104  var_gen_v = var_gen ? var_gen : var_gen_f; // operands of the same addr space and different types
105  // CHECK: icmp
106  // CHECK: %{{.+}} = bitcast i32 addrspace(4)* %{{.+}} to i8 addrspace(4)*
107  // CHECK: %{{.+}} = bitcast float addrspace(4)* %{{.+}} to i8 addrspace(4)*
108  // CHECK: phi
109  // CHECK: store
110
111  var_gen_v = var_gen ? var_glob : var_gen_f; // operands of overlapping addr spaces and different types
112  // CHECK: icmp
113  // CHECK: %{{.+}} = addrspacecast i32 addrspace(1)* %{{.+}} to i8 addrspace(4)*
114  // CHECK: %{{.+}} = bitcast float addrspace(4)* %{{.+}} to i8 addrspace(4)*
115  // CHECK: phi
116  // CHECK: store
117}
118