blob: 0d40cd68fb710ac7cca45e1ec8a5ca2ef05284f7 [file] [edit]
// 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;
}