1 // Test target codegen - host bc file has to be created first.
2 // RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
3 // RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
4 // RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
5 // RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
6 // expected-no-diagnostics
7 #ifndef HEADER
8 #define HEADER
9 
10 #ifdef CK1
11 
12 template <typename T>
13 int tmain(T argc) {
14 #pragma omp target
15 #pragma omp teams
16   argc = 0;
17   return 0;
18 }
19 
20 
21 int main (int argc, char **argv) {
22 #pragma omp target
23 #pragma omp teams
24   {
25   argc = 0;
26   }
27   return tmain(argv);
28 }
29 
30 // only nvptx side: do not outline teams region and do not call fork_teams
31 // CK1:  define {{.*}}void @{{[^,]+}}(i{{[0-9]+}} [[ARGC:%.+]])
32 // CK1:  {{.+}} = alloca i{{[0-9]+}}*,
33 // CK1:  {{.+}} = alloca i{{[0-9]+}}*,
34 // CK1:  [[ARGCADDR_PTR:%.+]] = alloca i{{[0-9]+}}*,
35 // CK1:  [[ARGCADDR:%.+]] = alloca i{{[0-9]+}},
36 // CK1:  store {{.+}} 0, {{.+}},
37 // CK1:  store i{{[0-9]+}} [[ARGC]], i{{[0-9]+}}* [[ARGCADDR]],
38 // CK1-64:  [[CONV:%.+]] = bitcast i{{[0-9]+}}* [[ARGCADDR]] to i{{[0-9]+}}*
39 // CK1:  call i8* @__kmpc_data_sharing_push_stack(i{{[0-9]+}} 4, i16 0)
40 // CK1-64:  [[ARG:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[CONV]]
41 // CK1-32:  [[ARG:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[ARGCADDR]]
42 // CK1:  [[ARGCADDR:%.+]] = getelementptr inbounds %struct.{{.*}}, %struct.{{.*}}* %{{.*}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
43 // CK1:  store i{{[0-9]+}} [[ARG]], i{{[0-9]+}}* [[ARGCADDR]],
44 // CK1:  store i{{[0-9]+}}* [[ARGCADDR]], i{{[0-9]+}}** [[ARGCADDR_PTR]],
45 // CK1:  [[ARGCADDR_PTR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[ARGCADDR_PTR]],
46 // CK1:  store i{{[0-9]+}} 0, i{{[0-9]+}}* [[ARGCADDR_PTR_REF]],
47 // CK1-NOT: call {{.*}}void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(
48 // CK1:  ret void
49 // CK1-NEXT: }
50 
51 // target region in template
52 // CK1: define {{.*}}void @{{[^,]+}}(i{{.+}}** [[ARGC:%.+]])
53 // CK1: [[ARGCADDR_PTR:%.+]] = alloca i{{.+}}***,
54 // CK1: [[ARGCADDR:%.+]] = alloca i{{.+}}**,
55 // CK1: store i{{.+}}** [[ARGC]], i{{.+}}*** [[ARGCADDR]]
56 // CK1: call i8* @__kmpc_data_sharing_push_stack(i{{[0-9]+}} {{4|8}}, i16 0)
57 // CK1: [[ARG:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** [[ARGCADDR]]
58 // CK1: [[ARGCADDR:%.+]] = getelementptr inbounds %struct.{{.*}}, %struct.{{.*}}* %{{.*}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
59 // CK1: store i{{[0-9]+}}** [[ARG]], i{{[0-9]+}}*** [[ARGCADDR]],
60 // CK1: store i8*** [[ARGCADDR]], i8**** [[ARGCADDR_PTR]],
61 // CK1: [[ARGCADDR_PTR_REF:%.+]] = load i{{.+}}**, i{{.+}}*** [[ARGCADDR_PTR]],
62 // CK1: store i{{[0-9]+}}** null, i{{[0-9]+}}*** [[ARGCADDR_PTR_REF]],
63 // CK1-NOT: call {{.*}}void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(
64 // CK1:  ret void
65 // CK1-NEXT: }
66 
67 
68 #endif // CK1
69 
70 // Test target codegen - host bc file has to be created first.
71 // RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
72 // RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
73 // RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
74 // RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
75 // expected-no-diagnostics
76 #ifdef CK2
77 
78 template <typename T>
79 int tmain(T argc) {
80   int a = 10;
81   int b = 5;
82 #pragma omp target
83 #pragma omp teams num_teams(a) thread_limit(b)
84   {
85   argc = 0;
86   }
87   return 0;
88 }
89 
90 int main (int argc, char **argv) {
91   int a = 20;
92   int b = 5;
93 #pragma omp target
94 #pragma omp teams num_teams(a) thread_limit(b)
95   {
96   argc = 0;
97   }
98   return tmain(argv);
99 }
100 
101 // CK2: define {{.*}}void @{{[^,]+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[B_IN:%.+]], i{{[0-9]+}} [[ARGC_IN:.+]])
102 // CK2: {{.}} = alloca i{{[0-9]+}}*,
103 // CK2: {{.}} = alloca i{{[0-9]+}}*,
104 // CK2: [[ARGCADDR_PTR:%.+]] = alloca i{{[0-9]+}}*,
105 // CK2: [[AADDR:%.+]] = alloca i{{[0-9]+}},
106 // CK2: [[BADDR:%.+]] = alloca i{{[0-9]+}},
107 // CK2: [[ARGCADDR:%.+]] = alloca i{{[0-9]+}},
108 // CK2:  {{%.+}} = call i32 @__kmpc_global_thread_num(
109 // CK2: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[AADDR]],
110 // CK2: store i{{[0-9]+}} [[B_IN]], i{{[0-9]+}}* [[BADDR]],
111 // CK2: store i{{[0-9]+}} [[ARGC_IN]], i{{[0-9]+}}* [[ARGCADDR]],
112 // CK2-64: [[ACONV:%.+]] = bitcast i64* [[AADDR]] to i32*
113 // CK2-64: [[BCONV:%.+]] = bitcast i64* [[BADDR]] to i32*
114 // CK2-64: [[CONV:%.+]] = bitcast i64* [[ARGCADDR]] to i32*
115 // CK2:  call i8* @__kmpc_data_sharing_push_stack(i{{[0-9]+}} 4, i16 0)
116 // CK2-64:  [[ARG:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[CONV]]
117 // CK2-32:  [[ARG:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[ARGCADDR]]
118 // CK2:  [[ARGCADDR:%.+]] = getelementptr inbounds %struct.{{.*}}, %struct.{{.*}}* %{{.*}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
119 // CK2:  store i{{[0-9]+}} [[ARG]], i{{[0-9]+}}* [[ARGCADDR]],
120 // CK2:  store i{{[0-9]+}}* [[ARGCADDR]], i{{[0-9]+}}** [[ARGCADDR_PTR]],
121 // CK2:  [[ARGCADDR_PTR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[ARGCADDR_PTR]],
122 // CK2: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[ARGCADDR_PTR_REF]],
123 // CK2-NOT:  {{.+}} = call i32 @__kmpc_push_num_teams(
124 // CK2-NOT:  call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(
125 // CK2: ret
126 
127 // CK2: define {{.*}}void @{{[^,]+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[BP:%.+]], i{{[0-9]+}}** [[ARGC:%.+]])
128 // CK2: [[ARGCADDR_PTR:%.+]] = alloca i{{[0-9]+}}***,
129 // CK2: [[AADDR:%.+]] = alloca i{{[0-9]+}},
130 // CK2: [[BADDR:%.+]] = alloca i{{[0-9]+}},
131 // CK2: [[ARGCADDR:%.+]] = alloca i{{[0-9]+}}**,
132 // CK2: {{%.+}} = call i32 @__kmpc_global_thread_num(
133 // CK2: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[AADDR]],
134 // CK2: store i{{[0-9]+}} [[B_IN]], i{{[0-9]+}}* [[BADDR]],
135 // CK2: store i{{[0-9]+}}** [[ARGC]], i{{[0-9]+}}*** [[ARGCADDR]],
136 // CK2: call i8* @__kmpc_data_sharing_push_stack(i{{[0-9]+}} {{4|8}}, i16 0)
137 // CK2: [[ARG:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** [[ARGCADDR]]
138 // CK2: [[ARGCADDR:%.+]] = getelementptr inbounds %struct.{{.*}}, %struct.{{.*}}* %{{.*}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
139 // CK2: store i{{[0-9]+}}** [[ARG]], i{{[0-9]+}}*** [[ARGCADDR]],
140 // CK2: store i{{[0-9]+}}*** [[ARGCADDR]], i{{[0-9]+}}**** [[ARGCADDR_PTR]],
141 // CK2: [[ARGCADDR_PTR_REF:%.+]] = load i{{[0-9]+}}***, i{{[0-9]+}}**** [[ARGCADDR_PTR]],
142 // CK2: store i{{[0-9]+}}** null, i{{[0-9]+}}*** [[ARGCADDR_PTR_REF]],
143 // CK2-NOT: {{.+}} = call i32 @__kmpc_push_num_teams(
144 // CK2-NOT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(
145 // CK2:  ret void
146 
147 #endif // CK2
148 #endif
149