1 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s 2 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s 3 // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s 4 // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s 5 // RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s 6 // expected-no-diagnostics 7 #ifndef HEADER 8 #define HEADER 9 10 volatile int g __attribute__((aligned(128))) = 1212; 11 12 template <class T> 13 struct S { 14 T f; 15 S(T a) : f(a + g) {} 16 S() : f(g) {} 17 operator T() { return T(); } 18 S &operator&(const S &) { return *this; } 19 ~S() {} 20 }; 21 22 struct SS { 23 int a; 24 int b : 4; 25 int &c; 26 SS(int &d) : a(0), b(0), c(d) { 27 #pragma omp parallel reduction(+: a, b, c) 28 #ifdef LAMBDA 29 [&]() { 30 ++this->a, --b, (this)->c /= 1; 31 #pragma omp parallel reduction(&: a, b, c) 32 ++(this)->a, --b, this->c /= 1; 33 }(); 34 #elif defined(BLOCKS) 35 ^{ 36 ++a; 37 --this->b; 38 (this)->c /= 1; 39 #pragma omp parallel reduction(-: a, b, c) 40 ++(this)->a, --b, this->c /= 1; 41 }(); 42 #else 43 ++this->a, --b, c /= 1; 44 #endif 45 } 46 }; 47 48 template<typename T> 49 struct SST { 50 T a; 51 SST() : a(T()) { 52 #pragma omp parallel reduction(*: a) 53 #ifdef LAMBDA 54 [&]() { 55 [&]() { 56 ++this->a; 57 #pragma omp parallel reduction(&& :a) 58 ++(this)->a; 59 }(); 60 }(); 61 #elif defined(BLOCKS) 62 ^{ 63 ^{ 64 ++a; 65 #pragma omp parallel reduction(|: a) 66 ++(this)->a; 67 }(); 68 }(); 69 #else 70 ++(this)->a; 71 #endif 72 } 73 }; 74 75 // CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 76 // LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 77 // BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 78 // CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } 79 // CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } 80 // CHECK-DAG: [[REDUCTION_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8* 81 // CHECK-DAG: [[REDUCTION_LOCK:@.+]] = common global [8 x i32] zeroinitializer 82 83 //CHECK: foo_array_sect 84 //CHECK: call void {{.+}}@__kmpc_fork_call( 85 //CHECK: ret void 86 void foo_array_sect(short x[1]) { 87 #pragma omp parallel reduction(+ : x[:]) 88 {} 89 } 90 91 template <typename T> 92 T tmain() { 93 T t; 94 S<T> test; 95 SST<T> sst; 96 T t_var __attribute__((aligned(128))) = T(), t_var1 __attribute__((aligned(128))); 97 T vec[] = {1, 2}; 98 S<T> s_arr[] = {1, 2}; 99 S<T> var __attribute__((aligned(128))) (3), var1 __attribute__((aligned(128))); 100 #pragma omp parallel reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1) 101 { 102 vec[0] = t_var; 103 s_arr[0] = var; 104 } 105 return T(); 106 } 107 108 int sivar; 109 int main() { 110 SS ss(sivar); 111 #ifdef LAMBDA 112 // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, 113 // LAMBDA-LABEL: @main 114 // LAMBDA: alloca [[SS_TY]], 115 // LAMBDA: alloca [[CAP_TY:%.+]], 116 // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@[^(]+]]([[CAP_TY]]* 117 [&]() { 118 // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( 119 // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]]) 120 #pragma omp parallel reduction(+:g) 121 { 122 // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]* 123 // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 124 // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* % 125 // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 126 // LAMBDA: store i8 127 // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 128 // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 129 // LAMBDA-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 130 // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 131 // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, i32*, i32*, i32*)* [[SS_MICROTASK:@.+]] to void 132 // LAMBDA: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 133 // LAMBDA: store i8 %{{.+}}, i8* [[B_REF]], 134 // LAMBDA: ret 135 136 // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}}) 137 // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* % 138 // LAMBDA: call{{.*}} void 139 // LAMBDA: ret void 140 141 // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* 142 // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, 143 // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, 144 // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, 145 // LAMBDA: store i{{[0-9]+}} -1, i{{[0-9]+}}* [[A_PRIV]], 146 // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], 147 // LAMBDA: store i{{[0-9]+}} -1, i{{[0-9]+}}* [[B_PRIV]], 148 // LAMBDA: store i{{[0-9]+}} -1, i{{[0-9]+}}* [[C_PRIV]], 149 // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], 150 // LAMBDA: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], 151 // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], 152 // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 153 // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], 154 // LAMBDA-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], 155 // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 156 // LAMBDA-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], 157 // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], 158 // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], 159 // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 160 // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], 161 // LAMBDA: call i32 @__kmpc_reduce_nowait( 162 // LAMBDA: ret void 163 164 // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) 165 // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, 166 167 // Reduction list for runtime. 168 // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x i8*], 169 170 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]] 171 // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 172 g = 1; 173 // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 174 // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 175 // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] 176 // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) 177 178 // LAMBDA: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i64 0, i64 0 179 // LAMBDA: [[BITCAST:%.+]] = bitcast i32* [[G_PRIVATE_ADDR]] to i8* 180 // LAMBDA: store i8* [[BITCAST]], i8** [[G_PRIV_REF]], 181 // LAMBDA: call i32 @__kmpc_reduce_nowait( 182 // LAMBDA: switch i32 %{{.+}}, label %[[REDUCTION_DONE:.+]] [ 183 // LAMBDA: i32 1, label %[[CASE1:.+]] 184 // LAMBDA: i32 2, label %[[CASE2:.+]] 185 // LAMBDA: [[CASE1]] 186 // LAMBDA: [[G_VAL:%.+]] = load i32, i32* [[G_REF]] 187 // LAMBDA: [[G_PRIV_VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]] 188 // LAMBDA: [[ADD:%.+]] = add nsw i32 [[G_VAL]], [[G_PRIV_VAL]] 189 // LAMBDA: store i32 [[ADD]], i32* [[G_REF]] 190 // LAMBDA: call void @__kmpc_end_reduce_nowait( 191 // LAMBDA: br label %[[REDUCTION_DONE]] 192 // LAMBDA: [[CASE2]] 193 // LAMBDA: [[G_PRIV_VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]] 194 // LAMBDA: atomicrmw add i32* [[G_REF]], i32 [[G_PRIV_VAL]] monotonic 195 // LAMBDA: br label %[[REDUCTION_DONE]] 196 // LAMBDA: [[REDUCTION_DONE]] 197 // LAMBDA: ret void 198 [&]() { 199 // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) 200 // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], 201 g = 2; 202 // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] 203 // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 204 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] 205 // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] 206 }(); 207 } 208 }(); 209 return 0; 210 #elif defined(BLOCKS) 211 // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, 212 // BLOCKS-LABEL: @main 213 // BLOCKS: call 214 // BLOCKS: call void {{%.+}}(i8 215 ^{ 216 // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* 217 // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]]) 218 #pragma omp parallel reduction(-:g) 219 { 220 // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}) 221 // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, 222 223 // Reduction list for runtime. 224 // BLOCKS: [[RED_LIST:%.+]] = alloca [1 x i8*], 225 226 // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]] 227 // BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 228 g = 1; 229 // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 230 // BLOCKS-NOT: [[G]]{{[[^:word:]]}} 231 // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] 232 // BLOCKS-NOT: [[G]]{{[[^:word:]]}} 233 // BLOCKS: call void {{%.+}}(i8 234 235 // BLOCKS: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i64 0, i64 0 236 // BLOCKS: [[BITCAST:%.+]] = bitcast i32* [[G_PRIVATE_ADDR]] to i8* 237 // BLOCKS: store i8* [[BITCAST]], i8** [[G_PRIV_REF]], 238 // BLOCKS: call i32 @__kmpc_reduce_nowait( 239 // BLOCKS: switch i32 %{{.+}}, label %[[REDUCTION_DONE:.+]] [ 240 // BLOCKS: i32 1, label %[[CASE1:.+]] 241 // BLOCKS: i32 2, label %[[CASE2:.+]] 242 // BLOCKS: [[CASE1]] 243 // BLOCKS: [[G_VAL:%.+]] = load i32, i32* [[G_REF]] 244 // BLOCKS: [[G_PRIV_VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]] 245 // BLOCKS: [[ADD:%.+]] = add nsw i32 [[G_VAL]], [[G_PRIV_VAL]] 246 // BLOCKS: store i32 [[ADD]], i32* [[G_REF]] 247 // BLOCKS: call void @__kmpc_end_reduce_nowait( 248 // BLOCKS: br label %[[REDUCTION_DONE]] 249 // BLOCKS: [[CASE2]] 250 // BLOCKS: [[G_PRIV_VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]] 251 // BLOCKS: atomicrmw add i32* [[G_REF]], i32 [[G_PRIV_VAL]] monotonic 252 // BLOCKS: br label %[[REDUCTION_DONE]] 253 // BLOCKS: [[REDUCTION_DONE]] 254 // BLOCKS: ret void 255 ^{ 256 // BLOCKS: define {{.+}} void {{@.+}}(i8* 257 g = 2; 258 // BLOCKS-NOT: [[G]]{{[[^:word:]]}} 259 // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* 260 // BLOCKS-NOT: [[G]]{{[[^:word:]]}} 261 // BLOCKS: ret 262 }(); 263 } 264 }(); 265 return 0; 266 // BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]* 267 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 268 // BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* % 269 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 270 // BLOCKS: store i8 271 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 272 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 273 // BLOCKS-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 274 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 275 // BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, i32*, i32*, i32*)* [[SS_MICROTASK:@.+]] to void 276 // BLOCKS: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 277 // BLOCKS: store i8 %{{.+}}, i8* [[B_REF]], 278 // BLOCKS: ret 279 280 // BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}}) 281 // BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* % 282 // BLOCKS: call{{.*}} void 283 // BLOCKS: ret void 284 285 // BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}}) 286 // BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, 287 // BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, 288 // BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, 289 // BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[A_PRIV]], 290 // BLOCKS: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], 291 // BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[B_PRIV]], 292 // BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[C_PRIV]], 293 // BLOCKS: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], 294 // BLOCKS: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], 295 // BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], 296 // BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 297 // BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], 298 // BLOCKS-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], 299 // BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 300 // BLOCKS-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], 301 // BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], 302 // BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], 303 // BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 304 // BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], 305 // BLOCKS: call i32 @__kmpc_reduce_nowait( 306 // BLOCKS: ret void 307 #else 308 S<float> test; 309 float t_var = 0, t_var1; 310 int vec[] = {1, 2}; 311 S<float> s_arr[] = {1, 2}; 312 S<float> var(3), var1; 313 float _Complex cf; 314 #pragma omp parallel reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1) 315 { 316 vec[0] = t_var; 317 s_arr[0] = var; 318 } 319 if (var1) 320 #pragma omp parallel reduction(+ : t_var) reduction(& : var) reduction(&& : var1) reduction(min : t_var1) 321 while (1) { 322 vec[0] = t_var; 323 s_arr[0] = var; 324 } 325 #pragma omp parallel reduction(+ : cf) 326 ; 327 return tmain<int>(); 328 #endif 329 } 330 331 // CHECK: define {{.*}}i{{[0-9]+}} @main() 332 // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], 333 // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) 334 // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, float*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*)* [[MAIN_MICROTASK:@.+]] to void 335 // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, float*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*)* [[MAIN_MICROTASK1:@.+]] to void 336 // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, { float, float }*)* [[MAIN_MICROTASK2:@.+]] to void 337 // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() 338 // CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* 339 // CHECK: ret 340 // 341 // CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, 342 // CHECK: [[T_VAR_PRIV:%.+]] = alloca float, 343 // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], 344 // CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_FLOAT_TY]], 345 // CHECK: [[T_VAR1_PRIV:%.+]] = alloca float, 346 347 // Reduction list for runtime. 348 // CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*], 349 350 // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], 351 352 // CHECK: [[T_VAR_REF:%.+]] = load float*, float** % 353 // CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % 354 // CHECK: [[VAR1_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % 355 // CHECK: [[T_VAR1_REF:%.+]] = load float*, float** % 356 357 // For + reduction operation initial value of private variable is 0. 358 // CHECK: store float 0.0{{.+}}, float* [[T_VAR_PRIV]], 359 360 // For & reduction operation initial value of private variable is ones in all bits. 361 // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) 362 363 // For && reduction operation initial value of private variable is 1.0. 364 // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR1_PRIV]]) 365 366 // For min reduction operation initial value of private variable is largest repesentable value. 367 // CHECK: store float 0x47EFFFFFE0000000, float* [[T_VAR1_PRIV]], 368 369 // Skip checks for internal operations. 370 371 // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]}; 372 373 // CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 0 374 // CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR_PRIV]] to i8* 375 // CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]], 376 // CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 1 377 // CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_PRIV]] to i8* 378 // CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]], 379 // CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 2 380 // CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_PRIV]] to i8* 381 // CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]], 382 // CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 3 383 // CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR1_PRIV]] to i8* 384 // CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]], 385 386 // res = __kmpc_reduce_nowait(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>); 387 388 // CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] 389 // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] 390 // CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8* 391 // CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 4, i64 32, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]]) 392 393 // switch(res) 394 // CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [ 395 // CHECK: i32 1, label %[[CASE1:.+]] 396 // CHECK: i32 2, label %[[CASE2:.+]] 397 // CHECK: ] 398 399 // case 1: 400 // t_var += t_var_reduction; 401 // CHECK: [[T_VAR_VAL:%.+]] = load float, float* [[T_VAR_REF]], 402 // CHECK: [[T_VAR_PRIV_VAL:%.+]] = load float, float* [[T_VAR_PRIV]], 403 // CHECK: [[UP:%.+]] = fadd float [[T_VAR_VAL]], [[T_VAR_PRIV_VAL]] 404 // CHECK: store float [[UP]], float* [[T_VAR_REF]], 405 406 // var = var.operator &(var_reduction); 407 // CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_PRIV]]) 408 // CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_REF]] to i8* 409 // CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8* 410 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) 411 412 // var1 = var1.operator &&(var1_reduction); 413 // CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_REF]]) 414 // CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0 415 // CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]] 416 // CHECK: [[TRUE]] 417 // CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_PRIV]]) 418 // CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0 419 // CHECK: br label %[[END2]] 420 // CHECK: [[END2]] 421 // CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ] 422 // CHECK: [[CONV:%.+]] = uitofp i1 [[COND_LVALUE]] to float 423 // CHECK: call void @{{.+}}([[S_FLOAT_TY]]* [[COND_LVALUE:%.+]], float [[CONV]]) 424 // CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_REF]] to i8* 425 // CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8* 426 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) 427 428 // t_var1 = min(t_var1, t_var1_reduction); 429 // CHECK: [[T_VAR1_VAL:%.+]] = load float, float* [[T_VAR1_REF]], 430 // CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load float, float* [[T_VAR1_PRIV]], 431 // CHECK: [[CMP:%.+]] = fcmp olt float [[T_VAR1_VAL]], [[T_VAR1_PRIV_VAL]] 432 // CHECK: br i1 [[CMP]] 433 // CHECK: [[UP:%.+]] = phi float 434 // CHECK: store float [[UP]], float* [[T_VAR1_REF]], 435 436 // __kmpc_end_reduce_nowait(<loc>, <gtid>, &<lock>); 437 // CHECK: call void @__kmpc_end_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]]) 438 439 // break; 440 // CHECK: br label %[[RED_DONE]] 441 442 // case 2: 443 // t_var += t_var_reduction; 444 // CHECK: load float, float* [[T_VAR_PRIV]] 445 // CHECK: [[T_VAR_REF_INT:%.+]] = bitcast float* [[T_VAR_REF]] to i32* 446 // CHECK: [[OLD1:%.+]] = load atomic i32, i32* [[T_VAR_REF_INT]] monotonic, 447 // CHECK: br label %[[CONT:.+]] 448 // CHECK: [[CONT]] 449 // CHECK: [[ORIG_OLD_INT:%.+]] = phi i32 [ [[OLD1]], %{{.+}} ], [ [[OLD2:%.+]], %[[CONT]] ] 450 // CHECK: fadd float 451 // CHECK: [[UP_INT:%.+]] = load i32 452 // CHECK: [[T_VAR_REF_INT:%.+]] = bitcast float* [[T_VAR_REF]] to i32* 453 // CHECK: [[RES:%.+]] = cmpxchg i32* [[T_VAR_REF_INT]], i32 [[ORIG_OLD_INT]], i32 [[UP_INT]] monotonic monotonic 454 // CHECK: [[OLD2:%.+]] = extractvalue { i32, i1 } [[RES]], 0 455 // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1 456 // CHECK: br i1 [[SUCCESS_FAIL]], label %[[ATOMIC_DONE:.+]], label %[[CONT]] 457 // CHECK: [[ATOMIC_DONE]] 458 459 // var = var.operator &(var_reduction); 460 // CHECK: call void @__kmpc_critical( 461 // CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_PRIV]]) 462 // CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_REF]] to i8* 463 // CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8* 464 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) 465 // CHECK: call void @__kmpc_end_critical( 466 467 // var1 = var1.operator &&(var1_reduction); 468 // CHECK: call void @__kmpc_critical( 469 // CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_REF]]) 470 // CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0 471 // CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]] 472 // CHECK: [[TRUE]] 473 // CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_PRIV]]) 474 // CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0 475 // CHECK: br label %[[END2]] 476 // CHECK: [[END2]] 477 // CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ] 478 // CHECK: [[CONV:%.+]] = uitofp i1 [[COND_LVALUE]] to float 479 // CHECK: call void @{{.+}}([[S_FLOAT_TY]]* [[COND_LVALUE:%.+]], float [[CONV]]) 480 // CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_REF]] to i8* 481 // CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8* 482 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) 483 // CHECK: call void @__kmpc_end_critical( 484 485 // t_var1 = min(t_var1, t_var1_reduction); 486 // CHECK: load float, float* [[T_VAR1_PRIV]] 487 // CHECK: [[T_VAR1_REF_INT:%.+]] = bitcast float* [[T_VAR1_REF]] to i32* 488 // CHECK: [[OLD1:%.+]] = load atomic i32, i32* [[T_VAR1_REF_INT]] monotonic, 489 // CHECK: br label %[[CONT:.+]] 490 // CHECK: [[CONT]] 491 // CHECK: [[ORIG_OLD_INT:%.+]] = phi i32 [ [[OLD1]], %{{.+}} ], [ [[OLD2:%.+]], %{{.+}} ] 492 // CHECK: [[CMP:%.+]] = fcmp olt float 493 // CHECK: br i1 [[CMP]] 494 // CHECK: [[UP:%.+]] = phi float 495 // CHECK: [[UP_INT:%.+]] = load i32 496 // CHECK: [[T_VAR1_REF_INT:%.+]] = bitcast float* [[T_VAR1_REF]] to i32* 497 // CHECK: [[RES:%.+]] = cmpxchg i32* [[T_VAR1_REF_INT]], i32 [[ORIG_OLD_INT]], i32 [[UP_INT]] monotonic monotonic 498 // CHECK: [[OLD2:%.+]] = extractvalue { i32, i1 } [[RES]], 0 499 // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1 500 // CHECK: br i1 [[SUCCESS_FAIL]], label %[[ATOMIC_DONE:.+]], label %[[CONT]] 501 // CHECK: [[ATOMIC_DONE]] 502 503 // break; 504 // CHECK: br label %[[RED_DONE]] 505 // CHECK: [[RED_DONE]] 506 507 // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) 508 // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* 509 // CHECK: ret void 510 511 // void reduce_func(void *lhs[<n>], void *rhs[<n>]) { 512 // *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]); 513 // ... 514 // *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1], 515 // *(Type<n>-1*)rhs[<n>-1]); 516 // } 517 // CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*) 518 // t_var_lhs = (float*)lhs[0]; 519 // CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0 520 // CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]], 521 // CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to float* 522 // t_var_rhs = (float*)rhs[0]; 523 // CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0 524 // CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]], 525 // CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to float* 526 527 // var_lhs = (S<float>*)lhs[1]; 528 // CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 1 529 // CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]], 530 // CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_FLOAT_TY]]* 531 // var_rhs = (S<float>*)rhs[1]; 532 // CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1 533 // CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]], 534 // CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_FLOAT_TY]]* 535 536 // var1_lhs = (S<float>*)lhs[2]; 537 // CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2 538 // CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]], 539 // CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_FLOAT_TY]]* 540 // var1_rhs = (S<float>*)rhs[2]; 541 // CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2 542 // CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]], 543 // CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_FLOAT_TY]]* 544 545 // t_var1_lhs = (float*)lhs[3]; 546 // CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 3 547 // CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]], 548 // CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to float* 549 // t_var1_rhs = (float*)rhs[3]; 550 // CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 3 551 // CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]], 552 // CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to float* 553 554 // t_var_lhs += t_var_rhs; 555 // CHECK: [[T_VAR_LHS_VAL:%.+]] = load float, float* [[T_VAR_LHS]], 556 // CHECK: [[T_VAR_RHS_VAL:%.+]] = load float, float* [[T_VAR_RHS]], 557 // CHECK: [[UP:%.+]] = fadd float [[T_VAR_LHS_VAL]], [[T_VAR_RHS_VAL]] 558 // CHECK: store float [[UP]], float* [[T_VAR_LHS]], 559 560 // var_lhs = var_lhs.operator &(var_rhs); 561 // CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_LHS]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_RHS]]) 562 // CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_LHS]] to i8* 563 // CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8* 564 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) 565 566 // var1_lhs = var1_lhs.operator &&(var1_rhs); 567 // CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_LHS]]) 568 // CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0 569 // CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]] 570 // CHECK: [[TRUE]] 571 // CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_RHS]]) 572 // CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0 573 // CHECK: br label %[[END2]] 574 // CHECK: [[END2]] 575 // CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ] 576 // CHECK: [[CONV:%.+]] = uitofp i1 [[COND_LVALUE]] to float 577 // CHECK: call void @{{.+}}([[S_FLOAT_TY]]* [[COND_LVALUE:%.+]], float [[CONV]]) 578 // CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_LHS]] to i8* 579 // CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8* 580 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) 581 582 // t_var1_lhs = min(t_var1_lhs, t_var1_rhs); 583 // CHECK: [[T_VAR1_LHS_VAL:%.+]] = load float, float* [[T_VAR1_LHS]], 584 // CHECK: [[T_VAR1_RHS_VAL:%.+]] = load float, float* [[T_VAR1_RHS]], 585 // CHECK: [[CMP:%.+]] = fcmp olt float [[T_VAR1_LHS_VAL]], [[T_VAR1_RHS_VAL]] 586 // CHECK: br i1 [[CMP]] 587 // CHECK: [[UP:%.+]] = phi float 588 // CHECK: store float [[UP]], float* [[T_VAR1_LHS]], 589 // CHECK: ret void 590 591 // CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, 592 // CHECK: [[T_VAR_PRIV:%.+]] = alloca float, 593 // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], 594 // CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_FLOAT_TY]], 595 // CHECK: [[T_VAR1_PRIV:%.+]] = alloca float, 596 597 // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], 598 599 // CHECK: [[T_VAR_REF:%.+]] = load float*, float** % 600 // CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % 601 // CHECK: [[VAR1_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % 602 // CHECK: [[T_VAR1_REF:%.+]] = load float*, float** % 603 604 // For + reduction operation initial value of private variable is 0. 605 // CHECK: store float 0.0{{.+}}, float* [[T_VAR_PRIV]], 606 607 // For & reduction operation initial value of private variable is ones in all bits. 608 // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) 609 610 // For && reduction operation initial value of private variable is 1.0. 611 // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR1_PRIV]]) 612 613 // For min reduction operation initial value of private variable is largest repesentable value. 614 // CHECK: store float 0x47EFFFFFE0000000, float* [[T_VAR1_PRIV]], 615 616 // CHECK-NOT: call i32 @__kmpc_reduce 617 618 // CHECK: ret void 619 620 // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() 621 // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], 622 // CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) 623 // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*, [[S_INT_TY]]*, i32*)* [[TMAIN_MICROTASK:@.+]] to void 624 // CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* 625 // CHECK: ret 626 // 627 // CHECK: define {{.+}} @{{.+}}([[SS_TY]]* 628 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 629 // CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* % 630 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 631 // CHECK: store i8 632 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 633 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 634 // CHECK-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 635 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 636 // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*)* [[SS_MICROTASK:@.+]] to void 637 // CHECK: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1 638 // CHECK: store i8 %{{.+}}, i8* [[B_REF]], 639 // CHECK: ret 640 641 // CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* 642 // CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, 643 // CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, 644 // CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, 645 // CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[A_PRIV]], 646 // CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], 647 // CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[B_PRIV]], 648 // CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[C_PRIV]], 649 // CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], 650 // CHECK: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], 651 // CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], 652 // CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 653 // CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], 654 // CHECK-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], 655 // CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 656 // CHECK-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], 657 // CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], 658 // CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], 659 // CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 660 // CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], 661 // CHECK: call i32 @__kmpc_reduce_nowait( 662 // CHECK: ret void 663 664 // CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, 665 // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128 666 // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], align 128 667 // CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_INT_TY]], align 128 668 // CHECK: [[T_VAR1_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128 669 670 // Reduction list for runtime. 671 // CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*], 672 673 // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], 674 675 // CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % 676 // CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % 677 // CHECK: [[VAR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % 678 // CHECK: [[T_VAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % 679 680 // For + reduction operation initial value of private variable is 0. 681 // CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[T_VAR_PRIV]], 682 683 // For & reduction operation initial value of private variable is ones in all bits. 684 // CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR_PRIV]]) 685 686 // For && reduction operation initial value of private variable is 1.0. 687 // CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR1_PRIV]]) 688 689 // For min reduction operation initial value of private variable is largest repesentable value. 690 // CHECK: store i{{[0-9]+}} 2147483647, i{{[0-9]+}}* [[T_VAR1_PRIV]], 691 692 // Skip checks for internal operations. 693 694 // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]}; 695 696 // CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 0 697 // CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR_PRIV]] to i8* 698 // CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]], 699 // CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 1 700 // CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_PRIV]] to i8* 701 // CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]], 702 // CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 2 703 // CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_PRIV]] to i8* 704 // CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]], 705 // CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 3 706 // CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR1_PRIV]] to i8* 707 // CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]], 708 709 // res = __kmpc_reduce_nowait(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>); 710 711 // CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] 712 // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] 713 // CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8* 714 // CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 4, i64 32, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]]) 715 716 // switch(res) 717 // CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [ 718 // CHECK: i32 1, label %[[CASE1:.+]] 719 // CHECK: i32 2, label %[[CASE2:.+]] 720 // CHECK: ] 721 722 // case 1: 723 // t_var += t_var_reduction; 724 // CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], 725 // CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]], 726 // CHECK: [[UP:%.+]] = add nsw i{{[0-9]+}} [[T_VAR_VAL]], [[T_VAR_PRIV_VAL]] 727 // CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR_REF]], 728 729 // var = var.operator &(var_reduction); 730 // CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* dereferenceable(4) [[VAR_PRIV]]) 731 // CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_REF]] to i8* 732 // CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8* 733 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) 734 735 // var1 = var1.operator &&(var1_reduction); 736 // CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_REF]]) 737 // CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0 738 // CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]] 739 // CHECK: [[TRUE]] 740 // CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_PRIV]]) 741 // CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0 742 // CHECK: [[END2]] 743 // CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ] 744 // CHECK: [[CONV:%.+]] = zext i1 [[COND_LVALUE]] to i32 745 // CHECK: call void @{{.+}}([[S_INT_TY]]* [[COND_LVALUE:%.+]], i32 [[CONV]]) 746 // CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_REF]] to i8* 747 // CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8* 748 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) 749 750 // t_var1 = min(t_var1, t_var1_reduction); 751 // CHECK: [[T_VAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_REF]], 752 // CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_PRIV]], 753 // CHECK: [[CMP:%.+]] = icmp slt i{{[0-9]+}} [[T_VAR1_VAL]], [[T_VAR1_PRIV_VAL]] 754 // CHECK: br i1 [[CMP]] 755 // CHECK: [[UP:%.+]] = phi i32 756 // CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR1_REF]], 757 758 // __kmpc_end_reduce_nowait(<loc>, <gtid>, &<lock>); 759 // CHECK: call void @__kmpc_end_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]]) 760 761 // break; 762 // CHECK: br label %[[RED_DONE]] 763 764 // case 2: 765 // t_var += t_var_reduction; 766 // CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]] 767 // CHECK: atomicrmw add i32* [[T_VAR_REF]], i32 [[T_VAR_PRIV_VAL]] monotonic 768 769 // var = var.operator &(var_reduction); 770 // CHECK: call void @__kmpc_critical( 771 // CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* dereferenceable(4) [[VAR_PRIV]]) 772 // CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_REF]] to i8* 773 // CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8* 774 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) 775 // CHECK: call void @__kmpc_end_critical( 776 777 // var1 = var1.operator &&(var1_reduction); 778 // CHECK: call void @__kmpc_critical( 779 // CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_REF]]) 780 // CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0 781 // CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]] 782 // CHECK: [[TRUE]] 783 // CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_PRIV]]) 784 // CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0 785 // CHECK: br label %[[END2]] 786 // CHECK: [[END2]] 787 // CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ] 788 // CHECK: [[CONV:%.+]] = zext i1 [[COND_LVALUE]] to i32 789 // CHECK: call void @{{.+}}([[S_INT_TY]]* [[COND_LVALUE:%.+]], i32 [[CONV]]) 790 // CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_REF]] to i8* 791 // CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8* 792 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) 793 // CHECK: call void @__kmpc_end_critical( 794 795 // t_var1 = min(t_var1, t_var1_reduction); 796 // CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_PRIV]] 797 // CHECK: atomicrmw min i32* [[T_VAR1_REF]], i32 [[T_VAR1_PRIV_VAL]] monotonic 798 799 // break; 800 // CHECK: br label %[[RED_DONE]] 801 // CHECK: [[RED_DONE]] 802 803 // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) 804 // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* 805 // CHECK: ret void 806 807 // void reduce_func(void *lhs[<n>], void *rhs[<n>]) { 808 // *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]); 809 // ... 810 // *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1], 811 // *(Type<n>-1*)rhs[<n>-1]); 812 // } 813 // CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*) 814 // t_var_lhs = (i{{[0-9]+}}*)lhs[0]; 815 // CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0 816 // CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]], 817 // CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to i{{[0-9]+}}* 818 // t_var_rhs = (i{{[0-9]+}}*)rhs[0]; 819 // CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0 820 // CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]], 821 // CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to i{{[0-9]+}}* 822 823 // var_lhs = (S<i{{[0-9]+}}>*)lhs[1]; 824 // CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 1 825 // CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]], 826 // CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_INT_TY]]* 827 // var_rhs = (S<i{{[0-9]+}}>*)rhs[1]; 828 // CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1 829 // CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]], 830 // CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_INT_TY]]* 831 832 // var1_lhs = (S<i{{[0-9]+}}>*)lhs[2]; 833 // CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2 834 // CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]], 835 // CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_INT_TY]]* 836 // var1_rhs = (S<i{{[0-9]+}}>*)rhs[2]; 837 // CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2 838 // CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]], 839 // CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_INT_TY]]* 840 841 // t_var1_lhs = (i{{[0-9]+}}*)lhs[3]; 842 // CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 3 843 // CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]], 844 // CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to i{{[0-9]+}}* 845 // t_var1_rhs = (i{{[0-9]+}}*)rhs[3]; 846 // CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 3 847 // CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]], 848 // CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to i{{[0-9]+}}* 849 850 // t_var_lhs += t_var_rhs; 851 // CHECK: [[T_VAR_LHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_LHS]], 852 // CHECK: [[T_VAR_RHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_RHS]], 853 // CHECK: [[UP:%.+]] = add nsw i{{[0-9]+}} [[T_VAR_LHS_VAL]], [[T_VAR_RHS_VAL]] 854 // CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR_LHS]], 855 856 // var_lhs = var_lhs.operator &(var_rhs); 857 // CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_LHS]], [[S_INT_TY]]* dereferenceable(4) [[VAR_RHS]]) 858 // CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_LHS]] to i8* 859 // CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8* 860 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) 861 862 // var1_lhs = var1_lhs.operator &&(var1_rhs); 863 // CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_LHS]]) 864 // CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0 865 // CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]] 866 // CHECK: [[TRUE]] 867 // CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_RHS]]) 868 // CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0 869 // CHECK: br label %[[END2]] 870 // CHECK: [[END2]] 871 // CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ] 872 // CHECK: [[CONV:%.+]] = zext i1 [[COND_LVALUE]] to i32 873 // CHECK: call void @{{.+}}([[S_INT_TY]]* [[COND_LVALUE:%.+]], i32 [[CONV]]) 874 // CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_LHS]] to i8* 875 // CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8* 876 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false) 877 878 // t_var1_lhs = min(t_var1_lhs, t_var1_rhs); 879 // CHECK: [[T_VAR1_LHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_LHS]], 880 // CHECK: [[T_VAR1_RHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_RHS]], 881 // CHECK: [[CMP:%.+]] = icmp slt i{{[0-9]+}} [[T_VAR1_LHS_VAL]], [[T_VAR1_RHS_VAL]] 882 // CHECK: br i1 [[CMP]] 883 // CHECK: [[UP:%.+]] = phi i32 884 // CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR1_LHS]], 885 // CHECK: ret void 886 887 #endif 888 889