1 |
12 |
jlechner |
/* Copyright (C) 2004 Free Software Foundation.
|
2 |
|
|
|
3 |
|
|
Verify that built-in math function conversion to smaller FP types
|
4 |
|
|
is correctly performed by the compiler.
|
5 |
|
|
|
6 |
|
|
Written by Kaveh Ghazi, 2004-03-17. */
|
7 |
|
|
|
8 |
|
|
/* { dg-do link } */
|
9 |
|
|
/* { dg-options "-ffast-math" } */
|
10 |
|
|
/* { dg-options "-ffast-math -mmacosx-version-min=10.3" { target powerpc-*-darwin* } } */
|
11 |
|
|
|
12 |
|
|
#include "../builtins-config.h"
|
13 |
|
|
|
14 |
|
|
/* This check is necessary when converting to a C99 function. */
|
15 |
|
|
#ifdef HAVE_C99_RUNTIME
|
16 |
|
|
#define C99CODE(CODE) (CODE)
|
17 |
|
|
#define MAYBEC99(CODE, C99) (CODE)
|
18 |
|
|
#else
|
19 |
|
|
#define C99CODE(CODE) 0
|
20 |
|
|
#define MAYBEC99(CODE, C99) (!(C99) && (CODE))
|
21 |
|
|
#endif
|
22 |
|
|
|
23 |
|
|
#define PROTOTYPE1(FN) extern double FN(double); extern float FN##f(float); \
|
24 |
|
|
extern long double FN##l(long double);
|
25 |
|
|
|
26 |
|
|
void test(double d1, float f1, long double ld1)
|
27 |
|
|
{
|
28 |
|
|
/* Test converting math builtins to narrower FP types based on a
|
29 |
|
|
narrowing cast on the outside of the call. MATHFN is the
|
30 |
|
|
function to test, and C99 is 0/1 depending on whether the
|
31 |
|
|
`double' version of MATHFN is a C99 function. The optimization
|
32 |
|
|
is only performed if the replacement function is actually
|
33 |
|
|
narrower in width, so check that first. */
|
34 |
|
|
#define OUTER_CAST1(MATHFN, C99) \
|
35 |
|
|
PROTOTYPE1 (MATHFN) \
|
36 |
|
|
extern void link_failure_outer_##MATHFN##l_##MATHFN##_1(void); \
|
37 |
|
|
extern void link_failure_outer_##MATHFN##l_##MATHFN##_2(void); \
|
38 |
|
|
extern void link_failure_outer_##MATHFN##l_##MATHFN##f_1(void); \
|
39 |
|
|
extern void link_failure_outer_##MATHFN##l_##MATHFN##f_2(void); \
|
40 |
|
|
extern void link_failure_outer_##MATHFN##_##MATHFN##f_1(void); \
|
41 |
|
|
extern void link_failure_outer_##MATHFN##_##MATHFN##f_2(void); \
|
42 |
|
|
if (sizeof (long double) > sizeof (double) \
|
43 |
|
|
&& MAYBEC99 ((double) MATHFN##l((double)ld1) != MATHFN(ld1), C99)) \
|
44 |
|
|
link_failure_outer_##MATHFN##l_##MATHFN##_1(); \
|
45 |
|
|
if (sizeof (long double) > sizeof (double) \
|
46 |
|
|
&& MAYBEC99 ((double) MATHFN##l(d1) != MATHFN(d1), C99)) \
|
47 |
|
|
link_failure_outer_##MATHFN##l_##MATHFN##_1(); \
|
48 |
|
|
if (sizeof (long double) > sizeof (double) \
|
49 |
|
|
&& MAYBEC99 ((double) MATHFN##l(f1) != MATHFN(f1), C99)) \
|
50 |
|
|
link_failure_outer_##MATHFN##l_##MATHFN##_2(); \
|
51 |
|
|
if (sizeof (long double) > sizeof (float) \
|
52 |
|
|
&& C99CODE ((float) MATHFN##l((float) ld1) != MATHFN##f(ld1))) \
|
53 |
|
|
link_failure_outer_##MATHFN##l_##MATHFN##f_1(); \
|
54 |
|
|
if (sizeof (long double) > sizeof (float) \
|
55 |
|
|
&& C99CODE ((float) MATHFN##l((float) d1) != MATHFN##f(d1))) \
|
56 |
|
|
link_failure_outer_##MATHFN##l_##MATHFN##f_1(); \
|
57 |
|
|
if (sizeof (long double) > sizeof (float) \
|
58 |
|
|
&& C99CODE ((float) MATHFN##l(f1) != MATHFN##f(f1))) \
|
59 |
|
|
link_failure_outer_##MATHFN##l_##MATHFN##f_2(); \
|
60 |
|
|
if (sizeof (double) > sizeof (float) \
|
61 |
|
|
&& C99CODE ((float) MATHFN((float) ld1) != MATHFN##f(ld1))) \
|
62 |
|
|
link_failure_outer_##MATHFN##_##MATHFN##f_1(); \
|
63 |
|
|
if (sizeof (double) > sizeof (float) \
|
64 |
|
|
&& C99CODE ((float) MATHFN((float) d1) != MATHFN##f(d1))) \
|
65 |
|
|
link_failure_outer_##MATHFN##_##MATHFN##f_1(); \
|
66 |
|
|
if (sizeof (double) > sizeof (float) \
|
67 |
|
|
&& C99CODE ((float) MATHFN(f1) != MATHFN##f(f1))) \
|
68 |
|
|
link_failure_outer_##MATHFN##_##MATHFN##f_2()
|
69 |
|
|
|
70 |
|
|
/* Test converting math builtins to narrower FP types based on if
|
71 |
|
|
the argument is a narrower type (perhaps implicitly) cast to a
|
72 |
|
|
wider one. */
|
73 |
|
|
#define INNER_CAST1(MATHFN, C99) \
|
74 |
|
|
PROTOTYPE1 (MATHFN) \
|
75 |
|
|
extern void link_failure_inner_##MATHFN##l_##MATHFN(void); \
|
76 |
|
|
extern void link_failure_inner_##MATHFN##l_##MATHFN##f(void); \
|
77 |
|
|
extern void link_failure_inner_##MATHFN##_##MATHFN##f(void); \
|
78 |
|
|
if (sizeof (long double) > sizeof (double) \
|
79 |
|
|
&& MAYBEC99 (MATHFN##l(d1) != (long double) MATHFN(d1), C99)) \
|
80 |
|
|
link_failure_inner_##MATHFN##l_##MATHFN(); \
|
81 |
|
|
if (sizeof (long double) > sizeof (float) \
|
82 |
|
|
&& C99CODE (MATHFN##l(f1) != (long double) MATHFN##f(f1))) \
|
83 |
|
|
link_failure_inner_##MATHFN##l_##MATHFN##f(); \
|
84 |
|
|
if (sizeof (long double) > sizeof (float) \
|
85 |
|
|
&& C99CODE (MATHFN##l((double)f1) != (long double) MATHFN##f(f1))) \
|
86 |
|
|
link_failure_inner_##MATHFN##l_##MATHFN##f(); \
|
87 |
|
|
if (sizeof (double) > sizeof (float) \
|
88 |
|
|
&& C99CODE (MATHFN(f1) != (double) MATHFN##f(f1))) \
|
89 |
|
|
link_failure_inner_##MATHFN##_##MATHFN##f()
|
90 |
|
|
|
91 |
|
|
|
92 |
|
|
#ifdef __OPTIMIZE__
|
93 |
|
|
OUTER_CAST1 (acos, /*C99=*/ 0);
|
94 |
|
|
OUTER_CAST1 (acosh, /*C99=*/ 1);
|
95 |
|
|
OUTER_CAST1 (asin, /*C99=*/ 1);
|
96 |
|
|
OUTER_CAST1 (asinh, /*C99=*/ 1);
|
97 |
|
|
OUTER_CAST1 (atan, /*C99=*/ 0);
|
98 |
|
|
OUTER_CAST1 (atanh, /*C99=*/ 1);
|
99 |
|
|
OUTER_CAST1 (cbrt, /*C99=*/ 1);
|
100 |
|
|
OUTER_CAST1 (cos, /*C99=*/ 0);
|
101 |
|
|
OUTER_CAST1 (cosh, /*C99=*/ 0);
|
102 |
|
|
OUTER_CAST1 (erf, /*C99=*/ 1);
|
103 |
|
|
OUTER_CAST1 (erfc, /*C99=*/ 1);
|
104 |
|
|
OUTER_CAST1 (exp, /*C99=*/ 0);
|
105 |
|
|
OUTER_CAST1 (exp2, /*C99=*/ 1);
|
106 |
|
|
OUTER_CAST1 (expm1, /*C99=*/ 1);
|
107 |
|
|
OUTER_CAST1 (fabs, /*C99=*/ 0);
|
108 |
|
|
OUTER_CAST1 (lgamma, /*C99=*/ 1);
|
109 |
|
|
OUTER_CAST1 (log, /*C99=*/ 0);
|
110 |
|
|
OUTER_CAST1 (log10, /*C99=*/ 0);
|
111 |
|
|
OUTER_CAST1 (log1p, /*C99=*/ 1);
|
112 |
|
|
OUTER_CAST1 (log2, /*C99=*/ 1);
|
113 |
|
|
OUTER_CAST1 (logb, /*C99=*/ 1);
|
114 |
|
|
OUTER_CAST1 (sin, /*C99=*/ 0);
|
115 |
|
|
OUTER_CAST1 (sinh, /*C99=*/ 0);
|
116 |
|
|
OUTER_CAST1 (sqrt, /*C99=*/ 0);
|
117 |
|
|
OUTER_CAST1 (tan, /*C99=*/ 0);
|
118 |
|
|
OUTER_CAST1 (tanh, /*C99=*/ 0);
|
119 |
|
|
OUTER_CAST1 (tgamma, /*C99=*/ 1);
|
120 |
|
|
|
121 |
|
|
INNER_CAST1 (ceil, /*C99=*/ 0);
|
122 |
|
|
OUTER_CAST1 (ceil, /*C99=*/ 0);
|
123 |
|
|
INNER_CAST1 (floor, /*C99=*/ 0);
|
124 |
|
|
OUTER_CAST1 (floor, /*C99=*/ 0);
|
125 |
|
|
INNER_CAST1 (nearbyint, /*C99=*/ 1);
|
126 |
|
|
OUTER_CAST1 (nearbyint, /*C99=*/ 1);
|
127 |
|
|
INNER_CAST1 (rint, /*C99=*/ 1);
|
128 |
|
|
OUTER_CAST1 (rint, /*C99=*/ 1);
|
129 |
|
|
INNER_CAST1 (round, /*C99=*/ 1);
|
130 |
|
|
OUTER_CAST1 (round, /*C99=*/ 1);
|
131 |
|
|
INNER_CAST1 (trunc, /*C99=*/ 1);
|
132 |
|
|
OUTER_CAST1 (trunc, /*C99=*/ 1);
|
133 |
|
|
#endif /* __OPTIMIZE__ */
|
134 |
|
|
}
|
135 |
|
|
|
136 |
|
|
int main (void)
|
137 |
|
|
{
|
138 |
|
|
return 0;
|
139 |
|
|
}
|