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