xref: /llvm-project/clang/test/CodeGenOpenCL/address-spaces-conversions.cl (revision 3d84f4268dd9e1257e71938485fa23d17210ba44)
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 ptr addrspace(1) %{{[0-9]+}} to ptr 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 ptr %{{[._a-z0-9]+}} to ptr addrspace(4)
21  // CHECK-NOFAKE-NOT: addrspacecast
22
23  arg_glob = (global int *)arg_gen; // explicit cast
24  // CHECK: %{{[0-9]+}} = addrspacecast ptr addrspace(4) %{{[0-9]+}} to ptr 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 ptr addrspace(1) %{{[0-9]+}} to ptr addrspace(1)
30  // CHECK-NOFAKE-NOT: addrspacecast
31
32  var_priv = arg_gen - arg_glob; // arithmetic operation
33  // CHECK: %{{.*}} = ptrtoint ptr addrspace(4) %{{.*}} to i64
34  // CHECK: %{{.*}} = ptrtoint ptr addrspace(1) %{{.*}} to i64
35  // CHECK-NOFAKE: %{{.*}} = ptrtoint ptr %{{.*}} to i64
36  // CHECK-NOFAKE: %{{.*}} = ptrtoint ptr %{{.*}} to i64
37
38  var_priv = arg_gen > arg_glob; // comparison
39  // CHECK: %{{[0-9]+}} = addrspacecast ptr addrspace(1) %{{[0-9]+}} to ptr addrspace(4)
40
41  generic void *var_gen_v = arg_glob;
42  // CHECK: addrspacecast
43  // CHECK-NOFAKE-NOT: addrspacecast
44
45  arg_glob = arg_device; // implicit cast
46  // CHECK: addrspacecast
47  // CHECK-NOFAKE-NOT: addrspacecast
48
49  arg_glob = arg_host; // implicit cast
50  // CHECK: addrspacecast
51  // CHECK-NOFAKE-NOT: addrspacecast
52
53  arg_glob = (global int *)arg_device; // explicit cast
54  // CHECK: addrspacecast
55  // CHECK-NOFAKE-NOT: addrspacecast
56
57  arg_glob = (global int *)arg_host; // explicit cast
58  // CHECK: addrspacecast
59  // CHECK-NOFAKE-NOT: addrspacecast
60
61  arg_device = (__attribute((opencl_global_device)) int *)arg_glob; // explicit cast
62  // CHECK: addrspacecast
63  // CHECK-NOFAKE-NOT: addrspacecast
64
65  arg_host = (__attribute((opencl_global_host)) int *)arg_glob; // explicit cast
66  // CHECK: addrspacecast
67  // CHECK-NOFAKE-NOT: addrspacecast
68}
69
70// Test ternary operator.
71// CHECK: define{{.*}} void @test_ternary
72void test_ternary(void) {
73  global int *var_glob;
74  generic int *var_gen;
75  generic int *var_gen2;
76  generic float *var_gen_f;
77  generic void *var_gen_v;
78
79  var_gen = var_gen ? var_gen : var_gen2; // operands of the same addr spaces and the same type
80  // CHECK: icmp
81  // CHECK-NOT: addrspacecast
82  // CHECK: phi
83  // CHECK: store ptr addrspace(4) %{{.+}}, ptr %{{.+}}
84
85  var_gen = var_gen ? var_gen : var_glob; // operands of overlapping addr spaces and the same type
86  // CHECK: icmp
87  // CHECK: %{{.+}} = addrspacecast ptr addrspace(1) %{{.+}} to ptr addrspace(4)
88  // CHECK: phi
89  // CHECK: store
90
91  typedef int int_t;
92  global int_t *var_glob_typedef;
93  var_gen = var_gen ? var_gen : var_glob_typedef; // operands of overlapping addr spaces and equivalent types
94  // CHECK: icmp
95  // CHECK: %{{.+}} = addrspacecast ptr addrspace(1) %{{.+}} to ptr addrspace(4)
96  // CHECK: phi
97  // CHECK: store
98
99  var_gen_v = var_gen ? var_gen : var_gen_f; // operands of the same addr space and different types
100  // CHECK: icmp
101  // CHECK: phi
102  // CHECK: store
103
104  var_gen_v = var_gen ? var_glob : var_gen_f; // operands of overlapping addr spaces and different types
105  // CHECK: icmp
106  // CHECK: %{{.+}} = addrspacecast ptr addrspace(1) %{{.+}} to ptr addrspace(4)
107  // CHECK: phi
108  // CHECK: store
109}
110