| // REQUIRES: webassembly-registered-target |
| // RUN: %clang_cc1 -triple wasm32-unknown-emscripten -fopenmp -fnoopenmp-use-tls -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WASM32 |
| // RUN: %clang_cc1 -triple wasm64-unknown-emscripten -fopenmp -fnoopenmp-use-tls -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WASM64 |
| // RUN: %clang_cc1 -triple wasm32-unknown-emscripten -fopenmp -fnoopenmp-use-tls -emit-obj -o %t.wasm32.o %s |
| // RUN: %clang_cc1 -triple wasm64-unknown-emscripten -fopenmp -fnoopenmp-use-tls -emit-obj -o %t.wasm64.o %s |
| |
| // Exercise representative host OpenMP lowering for both WebAssembly pointer |
| // models. WebAssembly does not support common linkage, so compiler-generated |
| // locks and caches must have internal linkage. |
| // CHECK-DAG: @.gomp_critical_user_.var = internal global [8 x i32] zeroinitializer |
| // CHECK-DAG: @.gomp_critical_user_named.var = internal global [8 x i32] zeroinitializer |
| // CHECK-DAG: @.gomp_critical_user_.reduction.var = internal global [8 x i32] zeroinitializer |
| // CHECK-DAG: @threadprivate_var.cache. = internal global ptr null |
| |
| // The dependency record and size_t parameters must follow the target pointer |
| // width rather than assuming wasm32. |
| // WASM32-DAG: %struct.kmp_depend_info = type { i32, i32, i8 } |
| // WASM64-DAG: %struct.kmp_depend_info = type { i64, i64, i8 } |
| // WASM32-DAG: call ptr @__kmpc_omp_task_alloc({{.*}}i32 {{[0-9]+}}, i32 {{[0-9]+}}, ptr |
| // WASM64-DAG: call ptr @__kmpc_omp_task_alloc({{.*}}i64 {{[0-9]+}}, i64 {{[0-9]+}}, ptr |
| // WASM32-DAG: call ptr @__kmpc_threadprivate_cached({{.*}}i32 4, ptr @threadprivate_var.cache.) |
| // WASM64-DAG: call ptr @__kmpc_threadprivate_cached({{.*}}i64 4, ptr @threadprivate_var.cache.) |
| // WASM32-DAG: call i32 @__kmpc_reduce_nowait({{.*}}i32 4, ptr |
| // WASM64-DAG: call i32 @__kmpc_reduce_nowait({{.*}}i64 8, ptr |
| |
| // CHECK-DAG: call void (ptr, i32, ptr, ...) @__kmpc_fork_call( |
| // CHECK-DAG: call void @__kmpc_for_static_init_4( |
| // CHECK-DAG: call i32 @__kmpc_omp_task_with_deps( |
| // CHECK-DAG: call i32 @__kmpc_omp_taskwait( |
| // CHECK-DAG: call void @__kmpc_critical( |
| |
| void critical_regions(void) { |
| #pragma omp critical |
| {} |
| |
| #pragma omp critical(named) |
| {} |
| } |
| |
| int threadprivate_var; |
| #pragma omp threadprivate(threadprivate_var) |
| |
| int openmp_constructs(int *values, int count) { |
| int sum = 0; |
| #pragma omp parallel for reduction(+ : sum) |
| for (int i = 0; i < count; ++i) |
| sum += values[i]; |
| |
| #pragma omp task shared(values) depend(inout : values[0 : count]) |
| values[0] = sum; |
| |
| #pragma omp taskwait |
| |
| #pragma omp critical(named) |
| threadprivate_var += sum; |
| |
| return sum; |
| } |