blob: e041d5b2b7d834d0aeed94c4775e00b9070bff9f [file] [log] [blame]
Alexey Bataev60705422018-10-30 15:50:12 +00001// REQUIRES: powerpc-registered-target
2// REQUIRES: nvptx-registered-target
3
4// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -o - | FileCheck %s --check-prefix HOST
5// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
6// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple nvptx64-nvidia-cuda -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefixes=CLASS,FUN,CHECK
7// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple nvptx64-nvidia-cuda -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -emit-pch -o %t
8// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple nvptx64-nvidia-cuda -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -o - | FileCheck %s --check-prefixes=CLASS,CHECK
9// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple nvptx64-nvidia-cuda -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -o - | FileCheck %s --check-prefixes=FUN,CHECK
10
11// expected-no-diagnostics
12#ifndef HEADER
13#define HEADER
14
15// HOST-DAG: = private unnamed_addr constant [11 x i64] [i64 4, i64 4, i64 0, i64 4, i64 40, i64 4, i64 4, i64 4, i64 8, i64 4, i64 4]
Alexey Bataev2dc07d02018-11-02 15:25:06 +000016// HOST-DAG: = private unnamed_addr constant [11 x i64] [i64 547, i64 547, i64 544, i64 33, i64 673, i64 1407374883554064, i64 1407374883554064, i64 1407374883554064, i64 1407374883554064, i64 1407374883554064, i64 800]
Alexey Bataev60705422018-10-30 15:50:12 +000017// HOST-DAG: = private unnamed_addr constant [11 x i64] [i64 4, i64 4, i64 4, i64 0, i64 4, i64 40, i64 4, i64 4, i64 4, i64 8, i64 4]
Alexey Bataev2dc07d02018-11-02 15:25:06 +000018// HOST-DAG: = private unnamed_addr constant [11 x i64] [i64 547, i64 547, i64 547, i64 544, i64 547, i64 673, i64 1688849860264720, i64 1688849860264720, i64 1688849860264720, i64 1688849860264720, i64 1688849860264720]
Alexey Bataev60705422018-10-30 15:50:12 +000019// HOST-DAG: = private unnamed_addr constant [3 x i64] [i64 4, i64 8, i64 8]
Alexey Bataev2dc07d02018-11-02 15:25:06 +000020// HOST-DAG: = private unnamed_addr constant [3 x i64] [i64 547, i64 673, i64 562949953422096]
Alexey Bataev60705422018-10-30 15:50:12 +000021// HOST-DAG: = private unnamed_addr constant [3 x i64] [i64 4, i64 8, i64 8]
Alexey Bataev2dc07d02018-11-02 15:25:06 +000022// HOST-DAG: = private unnamed_addr constant [3 x i64] [i64 547, i64 673, i64 562949953422096]
Alexey Bataev60705422018-10-30 15:50:12 +000023// CHECK-DAG: [[S:%.+]] = type { i32 }
24// CHECK-DAG: [[CAP1:%.+]] = type { [[S]]* }
25// CHECK-DAG: [[CAP2:%.+]] = type { i32*, i32*, i32*, i32**, i32* }
26
27// CLASS: define internal void @__omp_offloading_{{.*}}_{{.*}}foo{{.*}}_l63_worker()
28// CLASS: define weak void @__omp_offloading_{{.*}}_{{.*}}foo{{.*}}_l63([[S]]* {{%.+}}, [[CAP1]]* dereferenceable(8) {{%.+}})
29// CLASS-NOT: getelementptr
30// CLASS: br i1 %
31// CLASS: call void @__omp_offloading_{{.*}}_{{.*}}foo{{.*}}_l63_worker()
32// CLASS: br label %
33// CLASS: br i1 %
34// CLASS: call void @__kmpc_kernel_init(
35// CLASS: call void @__kmpc_data_sharing_init_stack()
36// CLASS: call void @llvm.memcpy.
37// CLASS: [[L:%.+]] = load [[CAP1]]*, [[CAP1]]** [[L_ADDR:%.+]],
38// CLASS: [[THIS_REF:%.+]] = getelementptr inbounds [[CAP1]], [[CAP1]]* [[L]], i32 0, i32 0
39// CLASS: store [[S]]* [[S_:%.+]], [[S]]** [[THIS_REF]],
40// CLASS: [[L:%.+]] = load [[CAP1]]*, [[CAP1]]** [[L_ADDR]],
41// CLASS: call i32 [[LAMBDA1:@.+foo.+]]([[CAP1]]* [[L]])
42// CLASS: ret void
43
44// CLASS: define weak void @__omp_offloading_{{.+}}foo{{.+}}_l65([[S]]* %{{.+}}, [[CAP1]]* dereferenceable(8) %{{.+}})
45// CLASS-NOT: getelementptr
46// CLASS: call void [[PARALLEL:@.+]](i32* %{{.+}}, i32* %{{.+}}, [[S]]* %{{.+}}, [[CAP1]]* %{{.+}})
47// CLASS: ret void
48
49// CLASS: define internal void [[PARALLEL]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, [[S]]* %{{.+}}, [[CAP1]]* dereferenceable(8) %{{.+}})
50// CLASS-NOT: getelementptr
51// CLASS: call void @llvm.memcpy.
52// CLASS: [[L:%.+]] = load [[CAP1]]*, [[CAP1]]** [[L_ADDR:%.+]],
53// CLASS: [[THIS_REF:%.+]] = getelementptr inbounds [[CAP1]], [[CAP1]]* [[L]], i32 0, i32 0
54// CLASS: store [[S]]* %{{.+}}, [[S]]** [[THIS_REF]],
55// CLASS: [[L:%.+]] = load [[CAP1]]*, [[CAP1]]** [[L_ADDR]],
56// CLASS: call i32 [[LAMBDA1]]([[CAP1]]* [[L]])
57// CLASS: ret void
58
59struct S {
60 int a = 15;
61 int foo() {
62 auto &&L = [&]() { return a; };
63#pragma omp target
64 L();
65#pragma omp target parallel
66 L();
67 return a;
68 }
69} s;
70
71// FUN: define internal void @__omp_offloading_{{.+}}_main_l125_worker()
72// FUN: define weak void @__omp_offloading_{{.+}}_main_l125(i32* dereferenceable(4) %{{.+}}, i32* dereferenceable(4) %{{.+}}, i32* %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[CAP2]]* dereferenceable(40) %{{.+}}, i64 %{{.+}})
73// FUN-NOT: getelementptr
74// FUN: br i1 %
75// FUN: call void @__omp_offloading_{{.*}}_{{.*}}main{{.*}}_l125_worker()
76// FUN: br label %
77// FUN: br i1 %
78// FUN: call void @__kmpc_kernel_init(
79// FUN: call void @__kmpc_data_sharing_init_stack()
80// FUN: call void @llvm.memcpy.
81// FUN: [[L:%.+]] = load [[CAP2]]*, [[CAP2]]** [[L_ADDR:%.+]],
82// FUN: [[ARGC_CAP:%.+]] = getelementptr inbounds [[CAP2]], [[CAP2]]* [[L]], i32 0, i32 0
83// FUN: store i32* %{{.+}}, i32** [[ARGC_CAP]],
84// FUN: [[B_CAP:%.+]] = getelementptr inbounds [[CAP2]], [[CAP2]]* [[L]], i32 0, i32 1
85// FUN: store i32* %{{.+}}, i32** [[B_CAP]],
86// FUN: [[C_CAP:%.+]] = getelementptr inbounds [[CAP2]], [[CAP2]]* [[L]], i32 0, i32 2
87// FUN: store i32* %{{.+}}, i32** [[C_CAP]],
88// FUN: [[D_CAP:%.+]] = getelementptr inbounds [[CAP2]], [[CAP2]]* [[L]], i32 0, i32 3
89// FUN: store i32** %{{.+}}, i32*** [[D_CAP]],
90// FUN: [[A_CAP:%.+]] = getelementptr inbounds [[CAP2]], [[CAP2]]* [[L]], i32 0, i32 4
91// FUN: store i32* %{{.+}}, i32** [[A_CAP]],
92// FUN: [[L:%.+]] = load [[CAP2]]*, [[CAP2]]** [[L_ADDR:%.+]],
93// FUN: call i64 [[LAMBDA2:@.+main.+]]([[CAP2]]* [[L]])
94// FUN: ret void
95
96// FUN: define weak void @__omp_offloading_{{.+}}_main_l127(i32* dereferenceable(4) %{{.+}}, i32* dereferenceable(4) %{{.+}} i32* dereferenceable(4) %{{.+}}, i32* %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[CAP2]]* dereferenceable(40) %{{.+}})
97// FUN-NOT: getelementptr
98// FUN: call void [[PARALLEL:@.+]](i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, [[CAP2]]* %{{.+}})
99// FUN: ret void
100
101// FUN: define internal void [[PARALLEL:@.+]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, i32* dereferenceable(4) %{{.+}}, i32* dereferenceable(4) %{{.+}}, i32* %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[CAP2]]* dereferenceable(40) %{{.+}})
102// FUN-NOT: getelementptr
103// FUN: call void @llvm.memcpy.
104// FUN: [[L:%.+]] = load [[CAP2]]*, [[CAP2]]** [[L_ADDR]],
105// FUN: [[ARGC_CAP:%.+]] = getelementptr inbounds [[CAP2]], [[CAP2]]* [[L]], i32 0, i32 0
106// FUN: store i32* %{{.+}}, i32** [[ARGC_CAP]],
107// FUN: [[B_CAP:%.+]] = getelementptr inbounds [[CAP2]], [[CAP2]]* [[L]], i32 0, i32 1
108// FUN: store i32* %{{.+}}, i32** [[B_CAP]],
109// FUN: [[C_CAP:%.+]] = getelementptr inbounds [[CAP2]], [[CAP2]]* [[L]], i32 0, i32 2
110// FUN: store i32* %{{.+}}, i32** [[C_CAP]],
111// FUN: [[D_CAP:%.+]] = getelementptr inbounds [[CAP2]], [[CAP2]]* [[L]], i32 0, i32 3
112// FUN: store i32** %{{.+}}, i32*** [[D_CAP]],
113// FUN: [[A_CAP:%.+]] = getelementptr inbounds [[CAP2]], [[CAP2]]* [[L]], i32 0, i32 4
114// FUN: store i32* %{{.+}}, i32** [[A_CAP]],
115// FUN: [[L:%.+]] = load [[CAP2]]*, [[CAP2]]** [[L_ADDR]],
116// FUN: call i64 [[LAMBDA2]]([[CAP2]]* [[L]])
117// FUN: ret void
118
119int main(int argc, char **argv) {
120 int &b = argc;
121 int &&c = 1;
122 int *d = &argc;
123 int a;
124 auto &&L = [&]() { return argc + b + c + reinterpret_cast<long int>(d) + a; };
125#pragma omp target firstprivate(argc) map(to : a)
126 L();
127#pragma omp target parallel
128 L();
129 return argc + s.foo();
130}
131
132#endif // HEADER