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