libgomp, testsuite: Do not call nonstandard functions
[official-gcc.git] / libgomp / testsuite / libgomp.c / simd-math-1.c
blob42a008c80fc8317554462e24b13b1be01e1f1a0b
1 /* Check that the SIMD versions of math routines give the same (or
2 sufficiently close) results as their scalar equivalents. */
4 /* { dg-do run } */
5 /* { dg-options "-O2 -ftree-vectorize -fno-math-errno" } */
6 /* { dg-additional-options -foffload-options=amdgcn-amdhsa=-mstack-size=3000000 { target offload_target_amdgcn } } */
7 /* { dg-additional-options "-DNONSTDFUNC=1" { target nonstandard_math_functions } } */
9 #undef PRINT_RESULT
10 #define VERBOSE 0
11 #define EARLY_EXIT 1
13 #include <math.h>
14 #include <stdlib.h>
16 #ifdef PRINT_RESULT
17 #include <stdio.h>
18 #define PRINTF printf
19 #else
20 static void null_printf (const char *f, ...) { }
22 #define PRINTF null_printf
23 #endif
25 #define N 512
26 #define EPSILON_float 1e-5
27 #define EPSILON_double 1e-10
29 static int xfail = 0;
30 static int failed = 0;
32 int deviation_float (float x, float y)
34 union {
35 float f;
36 unsigned u;
37 } u, v;
39 u.f = x;
40 v.f = y;
42 unsigned mask = 0x80000000U;
43 int i;
45 for (i = 32; i > 0; i--)
46 if ((u.u ^ v.u) & mask)
47 break;
48 else
49 mask >>= 1;
51 return i;
54 int deviation_double (double x, double y)
56 union {
57 double d;
58 unsigned long long u;
59 } u, v;
61 u.d = x;
62 v.d = y;
64 unsigned long long mask = 0x8000000000000000ULL;
65 int i;
67 for (i = 64; i > 0; i--)
68 if ((u.u ^ v.u) & mask)
69 break;
70 else
71 mask >>= 1;
73 return i;
76 #define TEST_FUN_XFAIL(TFLOAT, LOW, HIGH, FUN) \
77 xfail = 1; \
78 TEST_FUN (TFLOAT, LOW, HIGH, FUN); \
79 xfail = 0;
81 #define TEST_FUN(TFLOAT, LOW, HIGH, FUN) \
82 __attribute__((optimize("no-tree-vectorize"))) \
83 __attribute__((optimize("no-unsafe-math-optimizations"))) \
84 void check_##FUN (TFLOAT res[N], TFLOAT a[N]) \
85 { \
86 for (int i = 0; i < N; i++) { \
87 TFLOAT expected = FUN (a[i]); \
88 TFLOAT diff = __builtin_fabs (expected - res[i]); \
89 int deviation = deviation_##TFLOAT (expected, res[i]); \
90 int fail = isnan (res[i]) != isnan (expected) \
91 || isinf (res[i]) != isinf (expected) \
92 || (diff > EPSILON_##TFLOAT && deviation > 10); \
93 if (VERBOSE || fail) \
94 PRINTF (#FUN "(%f) = %f, expected = %f, diff = %f, deviation = %d %s\n", \
95 a[i], res[i], expected, diff, deviation, fail ? "(!)" : ""); \
96 failed |= (fail && !xfail); \
97 if (EARLY_EXIT && failed) \
98 exit (1); \
99 } \
101 void test_##FUN (void) \
103 TFLOAT res[N], a[N]; \
104 for (int i = 0; i < N; i++) \
105 a[i] = LOW + ((HIGH - LOW) / N) * i; \
106 _Pragma ("omp target parallel for simd map(to:a) map(from:res)") \
107 for (int i = 0; i < N; i++) \
108 res[i] = FUN (a[i]); \
109 check_##FUN (res, a); \
111 test_##FUN ();
113 #define TEST_FUN2(TFLOAT, LOW1, HIGH1, LOW2, HIGH2, FUN) \
114 __attribute__((optimize("no-tree-vectorize"))) \
115 __attribute__((optimize("no-unsafe-math-optimizations"))) \
116 void check_##FUN (TFLOAT res[N], TFLOAT a[N], TFLOAT b[N]) \
118 int failed = 0; \
119 for (int i = 0; i < N; i++) { \
120 TFLOAT expected = FUN (a[i], b[i]); \
121 TFLOAT diff = __builtin_fabs (expected - res[i]); \
122 int deviation = deviation_##TFLOAT (expected, res[i]); \
123 int fail = isnan (res[i]) != isnan (expected) \
124 || isinf (res[i]) != isinf (expected) \
125 || (diff > EPSILON_##TFLOAT && deviation > 10); \
126 failed |= fail; \
127 if (VERBOSE || fail) \
128 PRINTF (#FUN "(%f,%f) = %f, expected = %f, diff = %f, deviation = %d %s\n", \
129 a[i], b[i], res[i], expected, diff, deviation, fail ? "(!)" : ""); \
130 if (EARLY_EXIT && fail) \
131 exit (1); \
134 void test_##FUN (void) \
136 TFLOAT res[N], a[N], b[N]; \
137 for (int i = 0; i < N; i++) { \
138 a[i] = LOW1 + ((HIGH1 - LOW1) / N) * i; \
139 b[i] = LOW2 + ((HIGH2 - LOW2) / N) * i; \
141 _Pragma ("omp target parallel for simd map(to:a) map(from:res)") \
142 for (int i = 0; i < N; i++) \
143 res[i] = FUN (a[i], b[i]); \
144 check_##FUN (res, a, b); \
146 test_##FUN ();
148 int main (void)
150 TEST_FUN (float, -1.1, 1.1, acosf);
151 TEST_FUN (float, -10, 10, acoshf);
152 TEST_FUN (float, -1.1, 1.1, asinf);
153 TEST_FUN (float, -10, 10, asinhf);
154 TEST_FUN (float, -1.1, 1.1, atanf);
155 TEST_FUN2 (float, -2.0, 2.0, 2.0, -2.0, atan2f);
156 TEST_FUN (float, -2.0, 2.0, atanhf);
157 TEST_FUN2 (float, -10.0, 10.0, 5.0, -15.0, copysignf);
158 TEST_FUN (float, -3.14159265359, 3.14159265359, cosf);
159 TEST_FUN (float, -3.14159265359, 3.14159265359, coshf);
160 TEST_FUN (float, -10.0, 10.0, erff);
161 TEST_FUN (float, -10.0, 10.0, expf);
162 TEST_FUN (float, -10.0, 10.0, exp2f);
163 TEST_FUN2 (float, -10.0, 10.0, 100.0, -25.0, fmodf);
164 #ifdef NONSTDFUNC
165 TEST_FUN (float, -10.0, 10.0, gammaf);
166 #endif
167 TEST_FUN2 (float, -10.0, 10.0, 15.0, -5.0,hypotf);
168 TEST_FUN (float, -10.0, 10.0, lgammaf);
169 TEST_FUN (float, -1.0, 50.0, logf);
170 TEST_FUN (float, -1.0, 500.0, log10f);
171 TEST_FUN (float, -1.0, 64.0, log2f);
172 TEST_FUN2 (float, -100.0, 100.0, 100.0, -100.0, powf);
173 TEST_FUN2 (float, -50.0, 100.0, -2.0, 40.0, remainderf);
174 TEST_FUN (float, -50.0, 50.0, rintf);
175 #ifdef NONSTDFUNC
176 TEST_FUN2 (float, -50.0, 50.0, -10.0, 32.0, __builtin_scalbf);
177 TEST_FUN (float, -10.0, 10.0, __builtin_significandf);
178 #endif
179 TEST_FUN (float, -3.14159265359, 3.14159265359, sinf);
180 TEST_FUN (float, -3.14159265359, 3.14159265359, sinhf);
181 TEST_FUN (float, -0.1, 10000.0, sqrtf);
182 TEST_FUN (float, -5.0, 5.0, tanf);
183 TEST_FUN (float, -3.14159265359, 3.14159265359, tanhf);
184 /* Newlib's version of tgammaf is known to have poor accuracy. */
185 TEST_FUN_XFAIL (float, -10.0, 10.0, tgammaf);
187 TEST_FUN (double, -1.1, 1.1, acos);
188 TEST_FUN (double, -10, 10, acosh);
189 TEST_FUN (double, -1.1, 1.1, asin);
190 TEST_FUN (double, -10, 10, asinh);
191 TEST_FUN (double, -1.1, 1.1, atan);
192 TEST_FUN2 (double, -2.0, 2.0, 2.0, -2.0, atan2);
193 TEST_FUN (double, -2.0, 2.0, atanh);
194 TEST_FUN2 (double, -10.0, 10.0, 5.0, -15.0, copysign);
195 TEST_FUN (double, -3.14159265359, 3.14159265359, cos);
196 TEST_FUN (double, -3.14159265359, 3.14159265359, cosh);
197 TEST_FUN (double, -10.0, 10.0, erf);
198 TEST_FUN (double, -10.0, 10.0, exp);
199 TEST_FUN (double, -10.0, 10.0, exp2);
200 TEST_FUN2 (double, -10.0, 10.0, 100.0, -25.0, fmod);
201 #ifdef NONSTDFUNC
202 TEST_FUN (double, -10.0, 10.0, gamma);
203 #endif
204 TEST_FUN2 (double, -10.0, 10.0, 15.0, -5.0, hypot);
205 TEST_FUN (double, -10.0, 10.0, lgamma);
206 TEST_FUN (double, -1.0, 50.0, log);
207 TEST_FUN (double, -1.0, 500.0, log10);
208 TEST_FUN (double, -1.0, 64.0, log2);
209 TEST_FUN2 (double, -100.0, 100.0, 100.0, -100.0, pow);
210 TEST_FUN2 (double, -50.0, 100.0, -2.0, 40.0, remainder);
211 TEST_FUN (double, -50.0, 50.0, rint);
212 #ifdef NONSTDFUNC
213 TEST_FUN2 (double, -50.0, 50.0, -10.0, 32.0, __builtin_scalb);
214 TEST_FUN (double, -10.0, 10.0, __builtin_significand);
215 #endif
216 TEST_FUN (double, -3.14159265359, 3.14159265359, sin);
217 TEST_FUN (double, -3.14159265359, 3.14159265359, sinh);
218 TEST_FUN (double, -0.1, 10000.0, sqrt);
219 TEST_FUN (double, -5.0, 5.0, tan);
220 TEST_FUN (double, -3.14159265359, 3.14159265359, tanh);
221 /* Newlib's version of tgamma is known to have poor accuracy. */
222 TEST_FUN_XFAIL (double, -10.0, 10.0, tgamma);
224 return failed;