// RUN: %libomp-compile -mlong-double-80 && %libomp-run
// UNSUPPORTED: gcc
// REQUIRES: x86-target-arch
#include <stdio.h>
#include <omp.h>
// Used to detect architecture
#include "../../src/kmp_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void* ident_t;
extern void __kmpc_atomic_float10_max(ident_t *id_ref, int gtid,
long double *lhs, long double rhs);
extern void __kmpc_atomic_float10_min(ident_t *id_ref, int gtid,
long double *lhs, long double rhs);
extern long double __kmpc_atomic_float10_max_cpt(ident_t *id_ref, int gtid,
long double *lhs,
long double rhs, int flag);
extern long double __kmpc_atomic_float10_min_cpt(ident_t *id_ref, int gtid,
long double *lhs,
long double rhs, int flag);
#ifdef __cplusplus
}
#endif
int main() {
int ret = 0;
#if (KMP_ARCH_X86 || KMP_ARCH_X86_64) && !defined(_MSC_VER)
long double s = 012.3456; // small
long double e = 123.4567; // middle
long double d = 234.5678; // big
long double x = 123.4567; // object
long double v = 0.; // captured value
// initialize OpenMP runtime library
omp_set_num_threads(4);
// max
// #pragma omp atomic compare update
// if (x < d) x = d;
__kmpc_atomic_float10_max(NULL, 0, &x, d);
if (x != d) {
ret++;
printf("Error max: %Lf != %Lf\n", x, d);
}
__kmpc_atomic_float10_max(NULL, 0, &x, s); // no-op
if (x != d) {
ret++;
printf("Error max: %Lf != %Lf\n", x, d);
}
// min
// #pragma omp atomic compare update
// if (x > s) x = s;
__kmpc_atomic_float10_min(NULL, 0, &x, s);
if (x != s) {
ret++;
printf("Error min: %Lf != %Lf\n", x, s);
}
__kmpc_atomic_float10_min(NULL, 0, &x, e); // no-op
if (x != s) {
ret++;
printf("Error min: %Lf != %Lf\n", x, s);
}
// max_cpt old
// #pragma omp atomic compare update capture
// { v = x; if (x < d) x = d; }
v = __kmpc_atomic_float10_max_cpt(NULL, 0, &x, d, 0);
if (x != d) {
ret++;
printf("Error max_cpt obj: %Lf != %Lf\n", x, d);
}
if (v != s) {
ret++;
printf("Error max_cpt cpt: %Lf != %Lf\n", v, s);
}
v = __kmpc_atomic_float10_max_cpt(NULL, 0, &x, e, 0); // no-op
if (x != d) {
ret++;
printf("Error max_cpt obj: %Lf != %Lf\n", x, d);
}
if (v != d) {
ret++;
printf("Error max_cpt cpt: %Lf != %Lf\n", v, d);
}
// min_cpt old
// #pragma omp atomic compare update capture
// { v = x; if (x > d) x = d; }
v = __kmpc_atomic_float10_min_cpt(NULL, 0, &x, s, 0);
if (x != s) {
ret++;
printf("Error min_cpt obj: %Lf != %Lf\n", x, s);
}
if (v != d) {
ret++;
printf("Error min_cpt cpt: %Lf != %Lf\n", v, d);
}
v = __kmpc_atomic_float10_min_cpt(NULL, 0, &x, e, 0); // no-op
if (x != s) {
ret++;
printf("Error max_cpt obj: %Lf != %Lf\n", x, s);
}
if (v != s) {
ret++;
printf("Error max_cpt cpt: %Lf != %Lf\n", v, s);
}
// max_cpt new
// #pragma omp atomic compare update capture
// { if (x < d) x = d; v = x; }
v = __kmpc_atomic_float10_max_cpt(NULL, 0, &x, d, 1);
if (x != d) {
ret++;
printf("Error max_cpt obj: %Lf != %Lf\n", x, d);
}
if (v != d) {
ret++;
printf("Error max_cpt cpt: %Lf != %Lf\n", v, d);
}
v = __kmpc_atomic_float10_max_cpt(NULL, 0, &x, e, 1); // no-op
if (x != d) {
ret++;
printf("Error max_cpt obj: %Lf != %Lf\n", x, d);
}
if (v != d) {
ret++;
printf("Error max_cpt cpt: %Lf != %Lf\n", v, d);
}
// min_cpt new
// #pragma omp atomic compare update capture
// { if (x > d) x = d; v = x; }
v = __kmpc_atomic_float10_min_cpt(NULL, 0, &x, s, 1);
if (x != s) {
ret++;
printf("Error min_cpt obj: %Lf != %Lf\n", x, s);
}
if (v != s) {
ret++;
printf("Error min_cpt cpt: %Lf != %Lf\n", v, s);
}
v = __kmpc_atomic_float10_min_cpt(NULL, 0, &x, e, 1); // no-op
if (x != s) {
ret++;
printf("Error max_cpt obj: %Lf != %Lf\n", x, s);
}
if (v != s) {
ret++;
printf("Error max_cpt cpt: %Lf != %Lf\n", v, s);
}
if (ret == 0)
printf("passed\n");
#else
printf("Unsupported architecture, skipping test...\n");
#endif // (KMP_ARCH_X86 || KMP_ARCH_X86_64) && !defined(_MSC_VER)
return ret;
}