1 // 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 4 // 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 63 struct 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 82 void 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 104 int 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 159