• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -verify -fopenmp -x c -emit-llvm %s -triple %itanium_abi_triple -o - -femit-all-decls -disable-llvm-passes | FileCheck %s
2 // RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes
3 // RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix=CHECK-LOAD %s
4 
5 // RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes -fopenmp-version=45
6 // RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes -fopenmp-version=45 | FileCheck --check-prefixes=CHECK-LOAD,OMP45-LOAD %s
7 
8 // RUN: %clang_cc1 -verify -fopenmp-simd -x c -emit-llvm %s -triple %itanium_abi_triple -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s
9 // RUN: %clang_cc1 -fopenmp-simd -x c -triple %itanium_abi_triple -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes
10 // RUN: %clang_cc1 -fopenmp-simd -x c -triple %itanium_abi_triple -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s
11 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
12 // expected-no-diagnostics
13 
14 #ifndef HEADER
15 #define HEADER
16 
17 // CHECK: [[SSS_INT:.+]] = type { i32 }
18 // CHECK-LOAD: [[SSS_INT:.+]] = type { i32 }
19 
20 #pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
21 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1)
22 // CHECK: [[MUL:%.+]] = mul nsw i32
23 // CHECK-NEXT: store i32 [[MUL]], i32*
24 // CHECK-NEXT: ret void
25 // CHECK-NEXT: }
26 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1)
27 // CHECK-LOAD: [[MUL:%.+]] = mul nsw i32
28 // CHECK-LOAD-NEXT: store i32 [[MUL]], i32*
29 // CHECK-LOAD-NEXT: ret void
30 // CHECK-LOAD-NEXT: }
31 
32 // CHECK: define internal {{.*}}void @{{[^(]+}}(i8* noalias %0, i8* noalias %1)
33 // CHECK: sext i8
34 // CHECK: sext i8
35 // CHECK: [[MUL:%.+]] = mul nsw i32
36 // CHECK-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
37 // CHECK-NEXT: store i8 [[TRUNC]], i8*
38 // CHECK-NEXT: ret void
39 // CHECK-NEXT: }
40 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias %0, i8* noalias %1)
41 // CHECK-LOAD: sext i8
42 // CHECK-LOAD: sext i8
43 // CHECK-LOAD: [[MUL:%.+]] = mul nsw i32
44 // CHECK-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
45 // CHECK-LOAD-NEXT: store i8 [[TRUNC]], i8*
46 // CHECK-LOAD-NEXT: ret void
47 // CHECK-LOAD-NEXT: }
48 
49 #pragma omp declare reduction(fun : float : omp_out += omp_in) initializer(omp_priv = 15 + omp_orig)
50 // CHECK: define internal {{.*}}void @{{[^(]+}}(float* noalias %0, float* noalias %1)
51 // CHECK: [[ADD:%.+]] = fadd float
52 // CHECK-NEXT: store float [[ADD]], float*
53 // CHECK-NEXT: ret void
54 // CHECK-NEXT: }
55 // CHECK: define internal {{.*}}void @{{[^(]+}}(float* noalias %0, float* noalias %1)
56 // CHECK: [[ADD:%.+]] = fadd float 1.5
57 // CHECK-NEXT: store float [[ADD]], float*
58 // CHECK-NEXT: ret void
59 // CHECK-NEXT: }
60 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(float* noalias %0, float* noalias %1)
61 // CHECK-LOAD: [[ADD:%.+]] = fadd float
62 // CHECK-LOAD-NEXT: store float [[ADD]], float*
63 // CHECK-LOAD-NEXT: ret void
64 // CHECK-LOAD-NEXT: }
65 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(float* noalias %0, float* noalias %1)
66 // CHECK-LOAD: [[ADD:%.+]] = fadd float 1.5
67 // CHECK-LOAD-NEXT: store float [[ADD]], float*
68 // CHECK-LOAD-NEXT: ret void
69 // CHECK-LOAD-NEXT: }
70 
71 struct SSS {
72   int field;
73 #pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
74   // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1)
75   // CHECK: [[MUL:%.+]] = mul nsw i32
76   // CHECK-NEXT: store i32 [[MUL]], i32*
77   // CHECK-NEXT: ret void
78   // CHECK-NEXT: }
79 
80   // CHECK: define internal {{.*}}void @{{[^(]+}}(i8* noalias %0, i8* noalias %1)
81   // CHECK: sext i8
82   // CHECK: sext i8
83   // CHECK: [[MUL:%.+]] = mul nsw i32
84   // CHECK-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
85   // CHECK-NEXT: store i8 [[TRUNC]], i8*
86   // CHECK-NEXT: ret void
87   // CHECK-NEXT: }
88 };
89 
90 void init(struct SSS *priv, struct SSS orig);
91 
92 #pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig))
93 // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
94 // CHECK: call void @llvm.memcpy
95 // CHECK-NEXT: ret void
96 // CHECK-NEXT: }
97 // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
98 // CHECK: call void @init(
99 // CHECK-NEXT: ret void
100 // CHECK-NEXT: }
101 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
102 // CHECK-LOAD: call void @llvm.memcpy
103 // CHECK-LOAD-NEXT: ret void
104 // CHECK-LOAD-NEXT: }
105 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
106 // CHECK-LOAD: call void @init(
107 // CHECK-LOAD-NEXT: ret void
108 // CHECK-LOAD-NEXT: }
109 
110 // CHECK-LABEL: @main
111 // CHECK-LOAD-LABEL: @main
main()112 int main() {
113 #pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig))
114   // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
115   // CHECK: call void @llvm.memcpy
116   // CHECK-NEXT: ret void
117   // CHECK-NEXT: }
118   // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
119   // CHECK: call void @init(
120   // CHECK-NEXT: ret void
121   // CHECK-NEXT: }
122   // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
123   // CHECK-LOAD: call void @llvm.memcpy
124   // CHECK-LOAD-NEXT: ret void
125   // CHECK-LOAD-NEXT: }
126   // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
127   // CHECK-LOAD: call void @init(
128   // CHECK-LOAD-NEXT: ret void
129   // CHECK-LOAD-NEXT: }
130   {
131 #pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig))
132     // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
133     // CHECK: call void @llvm.memcpy
134     // CHECK-NEXT: ret void
135     // CHECK-NEXT: }
136     // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
137     // CHECK: call void @init(
138     // CHECK-NEXT: ret void
139     // CHECK-NEXT: }
140     // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
141     // CHECK-LOAD: call void @llvm.memcpy
142     // CHECK-LOAD-NEXT: ret void
143     // CHECK-LOAD-NEXT: }
144     // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias %0, [[SSS_INT]]* noalias %1)
145     // CHECK-LOAD: call void @init(
146     // CHECK-LOAD-NEXT: ret void
147     // CHECK-LOAD-NEXT: }
148   }
149   return 0;
150 }
151 
152 // OMP45-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1)
153 // OMP45-LOAD: [[MUL:%.+]] = mul nsw i32
154 // OMP45-LOAD-NEXT: store i32 [[MUL]], i32*
155 // OMP45-LOAD-NEXT: ret void
156 // OMP45-LOAD-NEXT: }
157 
158 // OMP45-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias %0, i8* noalias %1)
159 // OMP45-LOAD: sext i8
160 // OMP45-LOAD: sext i8
161 // OMP45-LOAD: [[MUL:%.+]] = mul nsw i32
162 // OMP45-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
163 // OMP45-LOAD-NEXT: store i8 [[TRUNC]], i8*
164 // OMP45-LOAD-NEXT: ret void
165 // OMP45-LOAD-NEXT: }
166 #endif
167