Clang Project

clang_source_code/test/OpenMP/declare_reduction_codegen.c
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 -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}}
9// 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
164