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 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