mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 12:00:11 -05:00
hppa*-*-hpux* lacks necessary math functions. 2024-01-20 John David Anglin <danglin@gcc.gnu.org> libgomp/ChangeLog: * testsuite/libgomp.c/simd-math-1.c: Don't run on hppa*-*-hpux*.
226 lines
6.9 KiB
C
226 lines
6.9 KiB
C
/* Check that the SIMD versions of math routines give the same (or
|
|
sufficiently close) results as their scalar equivalents. */
|
|
|
|
/* { dg-do run { target { ! hppa*-*-hpux* } } } */
|
|
/* { dg-options "-O2 -ftree-vectorize -fno-math-errno" } */
|
|
/* { dg-additional-options -foffload-options=amdgcn-amdhsa=-mstack-size=3000000 { target offload_target_amdgcn } } */
|
|
/* { dg-additional-options "-DNONSTDFUNC=1" { target nonstandard_math_functions } } */
|
|
|
|
#undef PRINT_RESULT
|
|
#define VERBOSE 0
|
|
#define EARLY_EXIT 1
|
|
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifdef PRINT_RESULT
|
|
#include <stdio.h>
|
|
#define PRINTF printf
|
|
#else
|
|
static void null_printf (const char *f, ...) { }
|
|
|
|
#define PRINTF null_printf
|
|
#endif
|
|
|
|
#define N 512
|
|
#define EPSILON_float 1e-5
|
|
#define EPSILON_double 1e-10
|
|
|
|
static int xfail = 0;
|
|
static int failed = 0;
|
|
|
|
int deviation_float (float x, float y)
|
|
{
|
|
union {
|
|
float f;
|
|
unsigned u;
|
|
} u, v;
|
|
|
|
u.f = x;
|
|
v.f = y;
|
|
|
|
unsigned mask = 0x80000000U;
|
|
int i;
|
|
|
|
for (i = 32; i > 0; i--)
|
|
if ((u.u ^ v.u) & mask)
|
|
break;
|
|
else
|
|
mask >>= 1;
|
|
|
|
return i;
|
|
}
|
|
|
|
int deviation_double (double x, double y)
|
|
{
|
|
union {
|
|
double d;
|
|
unsigned long long u;
|
|
} u, v;
|
|
|
|
u.d = x;
|
|
v.d = y;
|
|
|
|
unsigned long long mask = 0x8000000000000000ULL;
|
|
int i;
|
|
|
|
for (i = 64; i > 0; i--)
|
|
if ((u.u ^ v.u) & mask)
|
|
break;
|
|
else
|
|
mask >>= 1;
|
|
|
|
return i;
|
|
}
|
|
|
|
#define TEST_FUN_XFAIL(TFLOAT, LOW, HIGH, FUN) \
|
|
xfail = 1; \
|
|
TEST_FUN (TFLOAT, LOW, HIGH, FUN); \
|
|
xfail = 0;
|
|
|
|
#define TEST_FUN(TFLOAT, LOW, HIGH, FUN) \
|
|
__attribute__((optimize("no-tree-vectorize"))) \
|
|
__attribute__((optimize("no-unsafe-math-optimizations"))) \
|
|
void check_##FUN (TFLOAT res[N], TFLOAT a[N]) \
|
|
{ \
|
|
for (int i = 0; i < N; i++) { \
|
|
TFLOAT expected = FUN (a[i]); \
|
|
TFLOAT diff = __builtin_fabs (expected - res[i]); \
|
|
int deviation = deviation_##TFLOAT (expected, res[i]); \
|
|
int fail = isnan (res[i]) != isnan (expected) \
|
|
|| isinf (res[i]) != isinf (expected) \
|
|
|| (diff > EPSILON_##TFLOAT && deviation > 10); \
|
|
if (VERBOSE || fail) \
|
|
PRINTF (#FUN "(%f) = %f, expected = %f, diff = %f, deviation = %d %s\n", \
|
|
a[i], res[i], expected, diff, deviation, fail ? "(!)" : ""); \
|
|
failed |= (fail && !xfail); \
|
|
if (EARLY_EXIT && failed) \
|
|
exit (1); \
|
|
} \
|
|
} \
|
|
void test_##FUN (void) \
|
|
{ \
|
|
TFLOAT res[N], a[N]; \
|
|
for (int i = 0; i < N; i++) \
|
|
a[i] = LOW + ((HIGH - LOW) / N) * i; \
|
|
_Pragma ("omp target parallel for simd map(to:a) map(from:res)") \
|
|
for (int i = 0; i < N; i++) \
|
|
res[i] = FUN (a[i]); \
|
|
check_##FUN (res, a); \
|
|
}\
|
|
test_##FUN ();
|
|
|
|
#define TEST_FUN2(TFLOAT, LOW1, HIGH1, LOW2, HIGH2, FUN) \
|
|
__attribute__((optimize("no-tree-vectorize"))) \
|
|
__attribute__((optimize("no-unsafe-math-optimizations"))) \
|
|
void check_##FUN (TFLOAT res[N], TFLOAT a[N], TFLOAT b[N]) \
|
|
{ \
|
|
int failed = 0; \
|
|
for (int i = 0; i < N; i++) { \
|
|
TFLOAT expected = FUN (a[i], b[i]); \
|
|
TFLOAT diff = __builtin_fabs (expected - res[i]); \
|
|
int deviation = deviation_##TFLOAT (expected, res[i]); \
|
|
int fail = isnan (res[i]) != isnan (expected) \
|
|
|| isinf (res[i]) != isinf (expected) \
|
|
|| (diff > EPSILON_##TFLOAT && deviation > 10); \
|
|
failed |= fail; \
|
|
if (VERBOSE || fail) \
|
|
PRINTF (#FUN "(%f,%f) = %f, expected = %f, diff = %f, deviation = %d %s\n", \
|
|
a[i], b[i], res[i], expected, diff, deviation, fail ? "(!)" : ""); \
|
|
if (EARLY_EXIT && fail) \
|
|
exit (1); \
|
|
} \
|
|
} \
|
|
void test_##FUN (void) \
|
|
{ \
|
|
TFLOAT res[N], a[N], b[N]; \
|
|
for (int i = 0; i < N; i++) { \
|
|
a[i] = LOW1 + ((HIGH1 - LOW1) / N) * i; \
|
|
b[i] = LOW2 + ((HIGH2 - LOW2) / N) * i; \
|
|
} \
|
|
_Pragma ("omp target parallel for simd map(to:a) map(from:res)") \
|
|
for (int i = 0; i < N; i++) \
|
|
res[i] = FUN (a[i], b[i]); \
|
|
check_##FUN (res, a, b); \
|
|
}\
|
|
test_##FUN ();
|
|
|
|
int main (void)
|
|
{
|
|
TEST_FUN (float, -1.1, 1.1, acosf);
|
|
TEST_FUN (float, -10, 10, acoshf);
|
|
TEST_FUN (float, -1.1, 1.1, asinf);
|
|
TEST_FUN (float, -10, 10, asinhf);
|
|
TEST_FUN (float, -1.1, 1.1, atanf);
|
|
TEST_FUN2 (float, -2.0, 2.0, 2.0, -2.0, atan2f);
|
|
TEST_FUN (float, -2.0, 2.0, atanhf);
|
|
TEST_FUN2 (float, -10.0, 10.0, 5.0, -15.0, copysignf);
|
|
TEST_FUN (float, -3.14159265359, 3.14159265359, cosf);
|
|
TEST_FUN (float, -3.14159265359, 3.14159265359, coshf);
|
|
TEST_FUN (float, -10.0, 10.0, erff);
|
|
TEST_FUN (float, -10.0, 10.0, expf);
|
|
TEST_FUN (float, -10.0, 10.0, exp2f);
|
|
TEST_FUN2 (float, -10.0, 10.0, 100.0, -25.0, fmodf);
|
|
#ifdef NONSTDFUNC
|
|
TEST_FUN (float, -10.0, 10.0, gammaf);
|
|
#endif
|
|
TEST_FUN2 (float, -10.0, 10.0, 15.0, -5.0,hypotf);
|
|
TEST_FUN (float, -10.0, 10.0, lgammaf);
|
|
TEST_FUN (float, -1.0, 50.0, logf);
|
|
TEST_FUN (float, -1.0, 500.0, log10f);
|
|
TEST_FUN (float, -1.0, 64.0, log2f);
|
|
TEST_FUN2 (float, -100.0, 100.0, 100.0, -100.0, powf);
|
|
TEST_FUN2 (float, -50.0, 100.0, -2.0, 40.0, remainderf);
|
|
TEST_FUN (float, -50.0, 50.0, rintf);
|
|
#ifdef NONSTDFUNC
|
|
TEST_FUN2 (float, -50.0, 50.0, -10.0, 32.0, __builtin_scalbf);
|
|
TEST_FUN (float, -10.0, 10.0, __builtin_significandf);
|
|
#endif
|
|
TEST_FUN (float, -3.14159265359, 3.14159265359, sinf);
|
|
TEST_FUN (float, -3.14159265359, 3.14159265359, sinhf);
|
|
TEST_FUN (float, -0.1, 10000.0, sqrtf);
|
|
TEST_FUN (float, -5.0, 5.0, tanf);
|
|
TEST_FUN (float, -3.14159265359, 3.14159265359, tanhf);
|
|
/* Newlib's version of tgammaf is known to have poor accuracy. */
|
|
TEST_FUN_XFAIL (float, -10.0, 10.0, tgammaf);
|
|
|
|
TEST_FUN (double, -1.1, 1.1, acos);
|
|
TEST_FUN (double, -10, 10, acosh);
|
|
TEST_FUN (double, -1.1, 1.1, asin);
|
|
TEST_FUN (double, -10, 10, asinh);
|
|
TEST_FUN (double, -1.1, 1.1, atan);
|
|
TEST_FUN2 (double, -2.0, 2.0, 2.0, -2.0, atan2);
|
|
TEST_FUN (double, -2.0, 2.0, atanh);
|
|
TEST_FUN2 (double, -10.0, 10.0, 5.0, -15.0, copysign);
|
|
TEST_FUN (double, -3.14159265359, 3.14159265359, cos);
|
|
TEST_FUN (double, -3.14159265359, 3.14159265359, cosh);
|
|
TEST_FUN (double, -10.0, 10.0, erf);
|
|
TEST_FUN (double, -10.0, 10.0, exp);
|
|
TEST_FUN (double, -10.0, 10.0, exp2);
|
|
TEST_FUN2 (double, -10.0, 10.0, 100.0, -25.0, fmod);
|
|
#ifdef NONSTDFUNC
|
|
TEST_FUN (double, -10.0, 10.0, gamma);
|
|
#endif
|
|
TEST_FUN2 (double, -10.0, 10.0, 15.0, -5.0, hypot);
|
|
TEST_FUN (double, -10.0, 10.0, lgamma);
|
|
TEST_FUN (double, -1.0, 50.0, log);
|
|
TEST_FUN (double, -1.0, 500.0, log10);
|
|
TEST_FUN (double, -1.0, 64.0, log2);
|
|
TEST_FUN2 (double, -100.0, 100.0, 100.0, -100.0, pow);
|
|
TEST_FUN2 (double, -50.0, 100.0, -2.0, 40.0, remainder);
|
|
TEST_FUN (double, -50.0, 50.0, rint);
|
|
#ifdef NONSTDFUNC
|
|
TEST_FUN2 (double, -50.0, 50.0, -10.0, 32.0, __builtin_scalb);
|
|
TEST_FUN (double, -10.0, 10.0, __builtin_significand);
|
|
#endif
|
|
TEST_FUN (double, -3.14159265359, 3.14159265359, sin);
|
|
TEST_FUN (double, -3.14159265359, 3.14159265359, sinh);
|
|
TEST_FUN (double, -0.1, 10000.0, sqrt);
|
|
TEST_FUN (double, -5.0, 5.0, tan);
|
|
TEST_FUN (double, -3.14159265359, 3.14159265359, tanh);
|
|
/* Newlib's version of tgamma is known to have poor accuracy. */
|
|
TEST_FUN_XFAIL (double, -10.0, 10.0, tgamma);
|
|
|
|
return failed;
|
|
}
|