1 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope -DHOST | FileCheck %s
2 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-linux -fexceptions -fcxx-exceptions -emit-pch -o %t -fopenmp-version=50 %s -DHOST
3 // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 -DHOST | FileCheck %s
4 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple aarch64-unknown-linux -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope -DHOST | FileCheck %s
5 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple aarch64-unknown-linux -fexceptions -fcxx-exceptions -emit-pch -o %t -fopenmp-version=50 %s -DHOST
6 // RUN: %clang_cc1 -fopenmp -x c++ -triple aarch64-unknown-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 -DHOST | FileCheck %s
7 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple ppc64le-unknown-linux -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope -DHOST | FileCheck %s
8 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple ppc64le-unknown-linux -fexceptions -fcxx-exceptions -emit-pch -o %t -fopenmp-version=50 %s -DHOST
9 // RUN: %clang_cc1 -fopenmp -x c++ -triple ppc64le-unknown-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 -DHOST | FileCheck %s
10 
11 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope -DCPU | FileCheck %s
12 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-linux -fexceptions -fcxx-exceptions -emit-pch -o %t -fopenmp-version=50 %s -DCPU
13 // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 -DCPU | FileCheck %s
14 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple aarch64-unknown-linux -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope -DCPU | FileCheck %s
15 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple aarch64-unknown-linux -fexceptions -fcxx-exceptions -emit-pch -o %t -fopenmp-version=50 %s -DCPU
16 // RUN: %clang_cc1 -fopenmp -x c++ -triple aarch64-unknown-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 -DCPU | FileCheck %s
17 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple ppc64le-unknown-linux -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope -DCPU | FileCheck %s
18 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple ppc64le-unknown-linux -fexceptions -fcxx-exceptions -emit-pch -o %t -fopenmp-version=50 %s -DCPU
19 // RUN: %clang_cc1 -fopenmp -x c++ -triple ppc64le-unknown-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 -DCPU | FileCheck %s
20 
21 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -fopenmp-targets=x86_64-unknown-linux -emit-llvm-bc %s -o %t-host.bc -DCPU
22 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -o - -DCPU | FileCheck %s
23 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -emit-pch -o %t -DCPU
24 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -include-pch %t -o - -DCPU | FileCheck %s
25 
26 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple ppc64le-unknown-linux -fopenmp-targets=ppc64le-unknown-linux -emit-llvm-bc %s -o %t-host.bc -DCPU
27 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple ppc64le-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -o - -DCPU | FileCheck %s
28 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple ppc64le-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -emit-pch -o %t -DCPU
29 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple ppc64le-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -include-pch %t -o - -DCPU | FileCheck %s
30 
31 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -fopenmp-targets=x86_64-unknown-linux -emit-llvm-bc %s -o %t-host.bc -DNOHOST
32 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -o - -DNOHOST | FileCheck %s
33 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -emit-pch -o %t -DNOHOST
34 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -include-pch %t -o - -DNOHOST | FileCheck %s
35 
36 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple ppc64le-unknown-linux -fopenmp-targets=ppc64le-unknown-linux -emit-llvm-bc %s -o %t-host.bc -DNOHOST
37 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple ppc64le-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -o - -DNOHOST | FileCheck %s
38 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple ppc64le-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -emit-pch -o %t -DNOHOST
39 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple ppc64le-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -include-pch %t -o - -DNOHOST | FileCheck %s
40 
41 // expected-no-diagnostics
42 
43 // CHECK-NOT: ret i32 {{1|4|81|84}}
44 // CHECK-DAG: @_Z3barv = {{.*}}alias i32 (), i32 ()* @_Z3foov
45 // CHECK-DAG: @_ZN16SpecSpecialFuncs6MethodEv = {{.*}}alias i32 (%struct.SpecSpecialFuncs*), i32 (%struct.SpecSpecialFuncs*)* @_ZN16SpecSpecialFuncs7method_Ev
46 // CHECK-DAG: @_ZN16SpecSpecialFuncs6methodEv = linkonce_odr {{.*}}alias i32 (%struct.SpecSpecialFuncs*), i32 (%struct.SpecSpecialFuncs*)* @_ZN16SpecSpecialFuncs7method_Ev
47 // CHECK-DAG: @_ZN12SpecialFuncs6methodEv = linkonce_odr {{.*}}alias i32 (%struct.SpecialFuncs*), i32 (%struct.SpecialFuncs*)* @_ZN12SpecialFuncs7method_Ev
48 // CHECK-DAG: @_Z5prio_v = {{.*}}alias i32 (), i32 ()* @_Z5prio1v
49 // CHECK-DAG: @_ZL6prio1_v = internal alias i32 (), i32 ()* @_ZL5prio2v
50 // CHECK-DAG: @_Z4callv = {{.*}}alias i32 (), i32 ()* @_Z4testv
51 // CHECK-DAG: @_ZL9stat_usedv = internal alias i32 (), i32 ()* @_ZL10stat_used_v
52 // CHECK-DAG: @_ZN12SpecialFuncs6MethodEv = {{.*}}alias i32 (%struct.SpecialFuncs*), i32 (%struct.SpecialFuncs*)* @_ZN12SpecialFuncs7method_Ev
53 // CHECK-DAG: @fn_linkage = {{.*}}alias i32 (), i32 ()* @_Z18fn_linkage_variantv
54 // CHECK-DAG: @_Z11fn_linkage1v = {{.*}}alias i32 (), i32 ()* @fn_linkage_variant1
55 // CHECK-DAG: declare {{.*}}i32 @_Z5bazzzv()
56 // CHECK-DAG: declare {{.*}}i32 @_Z3bazv()
57 // CHECK-DAG: ret i32 2
58 // CHECK-DAG: ret i32 3
59 // CHECK-DAG: ret i32 5
60 // CHECK-DAG: ret i32 6
61 // CHECK-DAG: ret i32 7
62 // CHECK-DAG: ret i32 82
63 // CHECK-DAG: ret i32 83
64 // CHECK-DAG: ret i32 85
65 // CHECK-DAG: ret i32 86
66 // CHECK-DAG: ret i32 87
67 // CHECK-NOT: ret i32 {{1|4|81|84}}
68 
69 #ifndef HEADER
70 #define HEADER
71 
72 #pragma omp declare target
73 #ifdef HOST
74 #define SUBSET host
75 #define CORRECT host, cpu
76 #define WRONG host, nohost
77 #endif // HOST
78 #ifdef CPU
79 #define SUBSET cpu
80 #define CORRECT cpu, any
81 #define WRONG cpu, gpu
82 #endif // CPU
83 #ifdef NOHOST
84 #define SUBSET nohost
85 #define CORRECT nohost, cpu
86 #define WRONG nohost, host
87 #endif // NOHOST
88 
89 int foo() { return 2; }
90 
91 #pragma omp declare variant(foo) match(device = {kind(CORRECT)})
92 int bar() { return 1; }
93 
94 int bazzz();
95 #pragma omp declare variant(bazzz) match(device = {kind(CORRECT)})
96 int baz() { return 1; }
97 
98 int test();
99 #pragma omp declare variant(test) match(device = {kind(CORRECT)})
100 int call() { return 1; }
101 
102 static int stat_unused_();
103 #pragma omp declare variant(stat_unused_) match(device = {kind(CORRECT)})
104 static int stat_unused() { return 1; }
105 
106 static int stat_used_();
107 #pragma omp declare variant(stat_used_) match(device = {kind(CORRECT)})
108 static int stat_used() { return 1; }
109 
110 int main() { return bar() + baz() + call() + stat_used(); }
111 
112 int test() { return 3; }
113 static int stat_unused_() { return 4; }
114 static int stat_used_() { return 5; }
115 
116 struct SpecialFuncs {
117   void vd() {}
118   SpecialFuncs();
119   ~SpecialFuncs();
120 
121   int method_() { return 6; }
122 #pragma omp declare variant(SpecialFuncs::method_) \
123     match(device = {kind(CORRECT)})
124   int method() { return 1; }
125 #pragma omp declare variant(SpecialFuncs::method_) \
126     match(device = {kind(CORRECT)})
127   int Method();
128 } s;
129 
130 int SpecialFuncs::Method() { return 1; }
131 
132 struct SpecSpecialFuncs {
133   void vd() {}
134   SpecSpecialFuncs();
135   ~SpecSpecialFuncs();
136 
137   int method_();
138 #pragma omp declare variant(SpecSpecialFuncs::method_) \
139     match(device = {kind(CORRECT)})
140   int method() { return 1; }
141 #pragma omp declare variant(SpecSpecialFuncs::method_) \
142     match(device = {kind(CORRECT)})
143   int Method();
144 } s1;
145 
146 int SpecSpecialFuncs::method_() { return 7; }
147 int SpecSpecialFuncs::Method() { return 1; }
148 
149 void xxx() {
150   (void)s.method();
151   (void)s1.method();
152 }
153 
154 int prio() { return 81; }
155 int prio1() { return 82; }
156 
157 #pragma omp declare variant(prio) match(device = {kind(SUBSET)})
158 #pragma omp declare variant(prio1) match(device = {kind(CORRECT)})
159 int prio_() { return 1; }
160 
161 static int prio2() { return 83; }
162 static int prio3() { return 84; }
163 static int prio4() { return 84; }
164 
165 #pragma omp declare variant(prio4) match(device = {kind(SUBSET)})
166 #pragma omp declare variant(prio2) match(device = {kind(CORRECT)})
167 #pragma omp declare variant(prio3) match(device = {kind(SUBSET)})
168 static int prio1_() { return 1; }
169 
170 int int_fn() { return prio1_(); }
171 
172 int fn_linkage_variant() { return 85; }
173 extern "C" {
174 #pragma omp declare variant(fn_linkage_variant) match(device = {kind(CORRECT)})
175 int fn_linkage() { return 1; }
176 }
177 
178 extern "C" int fn_linkage_variant1() { return 86; }
179 #pragma omp declare variant(fn_linkage_variant1) match(device = {kind(CORRECT)})
180 int fn_linkage1() { return 1; }
181 
182 int fn_variant2() { return 1; }
183 #pragma omp declare variant(fn_variant2) match(device = {kind(WRONG)})
184 int fn2() { return 87; }
185 
186 #pragma omp end declare target
187 #endif // HEADER
188