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