1 /* Check that the SIMD versions of math routines give the same (or
2 sufficiently close) results as their scalar equivalents. */
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 } } */
20 static void null_printf (const char *f
, ...) { }
22 #define PRINTF null_printf
26 #define EPSILON_float 1e-5
27 #define EPSILON_double 1e-10
30 static int failed
= 0;
32 int deviation_float (float x
, float y
)
42 unsigned mask
= 0x80000000U
;
45 for (i
= 32; i
> 0; i
--)
46 if ((u
.u
^ v
.u
) & mask
)
54 int deviation_double (double x
, double y
)
64 unsigned long long mask
= 0x8000000000000000ULL
;
67 for (i
= 64; i
> 0; i
--)
68 if ((u
.u
^ v
.u
) & mask
)
76 #define TEST_FUN_XFAIL(TFLOAT, LOW, HIGH, FUN) \
78 TEST_FUN (TFLOAT, LOW, HIGH, FUN); \
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]) \
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) \
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); \
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]) \
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); \
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) \
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); \
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
);
165 TEST_FUN (float, -10.0, 10.0, gammaf
);
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
);
176 TEST_FUN2 (float, -50.0, 50.0, -10.0, 32.0, __builtin_scalbf
);
177 TEST_FUN (float, -10.0, 10.0, __builtin_significandf
);
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
);
202 TEST_FUN (double, -10.0, 10.0, gamma
);
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
);
213 TEST_FUN2 (double, -50.0, 50.0, -10.0, 32.0, __builtin_scalb
);
214 TEST_FUN (double, -10.0, 10.0, __builtin_significand
);
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
);