1/* Excess precision tests.  Test excess precision is removed when
2   necessary.  */
3/* { dg-do run } */
4/* { dg-options "-O2 -mfpmath=387 -fexcess-precision=standard" } */
5
6#include <float.h>
7#include <stdarg.h>
8
9extern void abort (void);
10extern void exit (int);
11
12volatile float f1 = 1.0f;
13volatile float f2 = 0x1.0p-30f;
14volatile float f3 = 0x1.0p-60f;
15volatile double d1 = 1.0;
16volatile double d2 = 0x1.0p-30;
17volatile double d3 = 0x1.0p-60;
18volatile double d3d = 0x1.0p-52;
19volatile float fadd1 = 1.0f + 0x1.0p-30f;
20volatile double dadd2 = 1.0 + 0x1.0p-30 + 0x1.0p-60;
21volatile double dh = 0x1.0p-24;
22volatile float fha = 1.0f + 0x1.0p-23f;
23
24void
25test_assign (void)
26{
27  float f;
28  double d;
29  f = f1 + f2;
30  if (f != fadd1)
31    abort ();
32  d = f1 + f2;
33  if (d != dadd2)
34    abort ();
35  d = d1 + d2 + d3;
36  if (d != dadd2)
37    abort ();
38  /* Verify rounding direct to float without double rounding.  */
39  if (sizeof(long double) > sizeof(double)  )  {
40    f = d1 + dh + d3;
41    if (f != fha)
42      abort ();
43  } else {
44      f = d1 + dh + d3d;
45      if (f != fha)
46        abort ();
47  }
48}
49
50void
51test_init (void)
52{
53  float f = f1 + f2;
54  double d = d1 + d2 + d3;
55  if (f != fadd1)
56    abort ();
57  if (d != dadd2)
58    abort ();
59}
60
61volatile int i1 = 0x40000001;
62volatile unsigned int u1 = 0x80000001u;
63volatile long long ll1 = 0x4000000000000001ll;
64volatile unsigned long long ull1 = 0x8000000000000001ull;
65
66void
67test_cast (void)
68{
69  if ((float)(f1 + f2) != fadd1)
70    abort ();
71  if ((double)(d1 + d2 + d3) != dadd2)
72    abort ();
73  if ((double)(f1 + f2 + f3) != dadd2)
74    abort ();
75  if ((float)i1 != 0x1.0p30f)
76    abort ();
77  if ((float)u1 != 0x1.0p31f)
78    abort ();
79  if ((float)ll1 != 0x1.0p62f)
80    abort ();
81  if ((float)ull1 != 0x1.0p63f)
82    abort ();
83  if ((double)ll1 != 0x1.0p62)
84    abort ();
85  if ((double)ull1 != 0x1.0p63)
86    abort ();
87}
88
89static inline void
90check_float (float f)
91{
92  if (f != fadd1)
93    abort ();
94}
95
96static inline void
97check_double (double d)
98{
99  if (d != dadd2)
100    abort ();
101}
102
103static inline void
104check_float_nonproto (f)
105     float f;
106{
107  if (f != fadd1)
108    abort ();
109}
110
111static inline void
112check_double_nonproto (d)
113     double d;
114{
115  if (d != dadd2)
116    abort ();
117}
118
119static void
120check_double_va (int i, ...)
121{
122  va_list ap;
123  va_start (ap, i);
124  if (va_arg (ap, double) != dadd2)
125    abort ();
126  va_end (ap);
127}
128
129void
130test_call (void)
131{
132  check_float (f1 + f2);
133  check_double (d1 + d2 + d3);
134  check_double (f1 + f2 + f3);
135  check_float_nonproto (f1 + f2);
136  check_double_nonproto (d1 + d2 + d3);
137  check_double_nonproto (f1 + f2 + f3);
138  check_double_va (0, d1 + d2 + d3);
139  check_double_va (0, f1 + f2 + f3);
140}
141
142static inline float
143return_float (void)
144{
145  return f1 + f2;
146}
147
148static inline double
149return_double1 (void)
150{
151  return d1 + d2 + d3;
152}
153
154static inline double
155return_double2 (void)
156{
157  return f1 + f2 + f3;
158}
159
160void
161test_return (void)
162{
163  if (return_float () != fadd1)
164    abort ();
165  if (return_double1 () != dadd2)
166    abort ();
167  if (return_double2 () != dadd2)
168    abort ();
169}
170
171volatile float flt_min = FLT_MIN;
172volatile double dbl_min = DBL_MIN;
173volatile float flt_max = FLT_MAX;
174volatile double dbl_max = DBL_MAX;
175
176void
177test_builtin (void)
178{
179  /* Classification macros convert to the semantic type.  signbit and
180     comparison macros do not.  */
181  if (!__builtin_isinf (flt_max * flt_max))
182    abort ();
183  if (!__builtin_isinf (dbl_max * dbl_max))
184    abort ();
185  if (__builtin_isnormal (flt_max * flt_max))
186    abort ();
187  if (__builtin_isnormal (dbl_max * dbl_max))
188    abort ();
189  if (__builtin_isfinite (flt_max * flt_max))
190    abort ();
191  if (__builtin_isfinite (dbl_max * dbl_max))
192    abort ();
193  if (!__builtin_isgreater (flt_min * flt_min, 0.0f))
194    abort ();
195  if (!__builtin_isgreaterequal (flt_min * flt_min, 0.0f))
196    abort ();
197  if (!__builtin_isless (0.0f, flt_min * flt_min))
198    abort ();
199  if (__builtin_islessequal (flt_min * flt_min, 0.0f))
200    abort ();
201  if (!__builtin_islessgreater (flt_min * flt_min, 0.0f))
202    abort ();
203  if (!__builtin_isgreaterequal (dbl_min * dbl_min, 0.0))
204    abort ();
205  if (sizeof(long double) > sizeof(double)  ) {
206    if (!__builtin_isgreater (dbl_min * dbl_min, 0.0))
207      abort ();
208    if (!__builtin_isless (0.0, dbl_min * dbl_min))
209      abort ();
210    if (__builtin_islessequal (dbl_min * dbl_min, 0.0))
211      abort ();
212    if (!__builtin_islessgreater (dbl_min * dbl_min, 0.0))
213      abort ();
214  }
215  else {
216    if (__builtin_isgreater (dbl_min * dbl_min, 0.0))
217      abort ();
218    if (__builtin_isless (0.0, dbl_min * dbl_min))
219      abort ();
220    if (!__builtin_islessequal (dbl_min * dbl_min, 0.0))
221      abort ();
222    if (__builtin_islessgreater (dbl_min * dbl_min, 0.0))
223      abort ();
224  }
225}
226
227int
228main (void)
229{
230  test_assign ();
231  test_init ();
232  test_cast ();
233  test_call ();
234  test_return ();
235  test_builtin ();
236  exit (0);
237}
238