1/* Excess precision tests.  Test that excess precision is carried
2   through various operations.  */
3/* { dg-do run } */
4/* { dg-options "-O2 -mfpmath=387 -fexcess-precision=standard" } */
5
6#include <float.h>
7
8extern void abort (void);
9extern void exit (int);
10
11volatile float f1 = 1.0f;
12volatile float f2 = 0x1.0p-30f;
13volatile float f3 = 0x1.0p-60f;
14volatile double d1 = 1.0;
15volatile double d2 = 0x1.0p-30;
16volatile double d3 = 0x1.0p-60;
17volatile float fadd1 = 1.0f + 0x1.0p-30f;
18volatile double dadd2 = 1.0 + 0x1.0p-30 + 0x1.0p-60;
19volatile long double ldadd1 = 1.0l + 0x1.0p-30l;
20volatile long double ldadd2 = 1.0l + 0x1.0p-30l + 0x1.0p-60l;
21
22void
23test_add (void)
24{
25  if (f1 + f2 != ldadd1)
26    abort ();
27  if (f1 + f2 + f3 != ldadd2)
28    abort ();
29  if (d1 + d2 != ldadd1)
30    abort ();
31  if (d1 + d2 + d3 != ldadd2)
32    abort ();
33  if (f1 + d2 + f3 != ldadd2)
34    abort ();
35  if (f1 + f2 == fadd1)
36    abort ();
37  if (f1 + f2 <= fadd1)
38    abort ();
39  if (f1 + f2 < fadd1)
40    abort ();
41  if (d1 + d2 + d3 == dadd2)
42    abort ();
43  if (!(d1 + d2 + d3 > dadd2))
44    abort ();
45  if (!(d1 + d2 + d3 >= dadd2))
46    abort ();
47}
48
49volatile long double ldsub1 = 1.0l - 0x1.0p-30l;
50volatile long double ldsub2 = 1.0l - 0x1.0p-30l - 0x1.0p-60l;
51
52void
53test_sub (void)
54{
55  if (f1 - f2 != ldsub1)
56    abort ();
57  if (f1 - f2 - f3 != ldsub2)
58    abort ();
59  if (d1 - d2 != ldsub1)
60    abort ();
61  if (d1 - d2 - d3 != ldsub2)
62    abort ();
63  if (f1 - d2 - f3 != ldsub2)
64    abort ();
65  if (+(f1 - d2 - f3) != ldsub2)
66    abort ();
67  if (-(f1 - d2 - f3) != -ldsub2)
68    abort ();
69}
70
71volatile float flt_min = FLT_MIN;
72volatile double dbl_min = DBL_MIN;
73volatile long double flt_min2 = (long double)FLT_MIN * (long double)FLT_MIN;
74volatile long double dbl_min3 = (long double)DBL_MIN * (long double)DBL_MIN * (long double)DBL_MIN;
75
76void
77test_mul (void)
78{
79  if (flt_min * flt_min != flt_min2)
80    abort ();
81  if (flt_min * flt_min == 0)
82    abort ();
83  if (flt_min * flt_min == 0)
84    abort ();
85  if (!(flt_min * flt_min))
86    abort ();
87  if (dbl_min * dbl_min * dbl_min != dbl_min3)
88    abort ();
89  if ((long double)(dbl_min * dbl_min * dbl_min) != dbl_min3)
90    abort ();
91  if ((0, dbl_min * dbl_min * dbl_min) != dbl_min3)
92    abort ();
93  if (dbl_min * dbl_min * dbl_min == 0)
94    abort ();
95  if ((flt_min * flt_min ? dbl_min * dbl_min * dbl_min : 0) == 0)
96    abort ();
97  if ((flt_min * flt_min ? : 0) == 0)
98    abort ();
99}
100
101volatile float f4 = 0x1.0p100f;
102volatile double d4 = 0x1.0p100;
103volatile long double flt_div = 0x1.0p100l / (long double) FLT_MIN;
104volatile long double dbl_div = 0x1.0p100l / (long double) DBL_MIN;
105
106void
107test_div (void)
108{
109  if (f4 / flt_min != flt_div)
110    abort ();
111  if (d4 / dbl_min != dbl_div)
112    abort ();
113}
114
115volatile float f5 = 0x1.0p30;
116
117void
118test_cast (void)
119{
120  if ((int)(f1 + f5) != 0x40000001)
121    abort ();
122}
123
124volatile float _Complex f1c = 1.0f + 1.0if;
125volatile float _Complex f2c = 0x1.0p-30f + 0x1.0p-31if;
126volatile float _Complex f3c = 0x1.0p-60f + 0x1.0p-59if;
127volatile double _Complex d1c = 1.0 + 1.0i;
128volatile double _Complex d2c = 0x1.0p-30 + 0x1.0p-31i;
129volatile double _Complex d3c = 0x1.0p-60 + 0x1.0p-59i;
130volatile long double _Complex ldadd1c = 1.0l + 0x1.0p-30l + 1.0il + 0x1.0p-31il;
131volatile long double _Complex ldadd2c = 1.0l + 0x1.0p-30l + 0x1.0p-60l + 1.0il + 0x1.0p-31il + 0x1.0p-59il;
132volatile long double _Complex ldadd2cc = 1.0l + 0x1.0p-30l + 0x1.0p-60l - 1.0il - 0x1.0p-31il - 0x1.0p-59il;
133volatile float _Complex flt_minc = FLT_MIN;
134volatile double _Complex dbl_minc = DBL_MIN;
135volatile float _Complex f4c = 0x1.0p100f;
136volatile double _Complex d4c = 0x1.0p100;
137
138void
139test_complex (void)
140{
141  if (f1c + f2c != ldadd1c)
142    abort ();
143  if (f1c + f2c + f3c != ldadd2c)
144    abort ();
145  if (d1c + d2c != ldadd1c)
146    abort ();
147  if (d1c + d2c + d3c != ldadd2c)
148    abort ();
149  if (__real__ (f1c + f2c + f3c) != ldadd2)
150    abort ();
151  if (__imag__ (d1c + d2c + d3c) != __imag__ ldadd2c)
152    abort ();
153  if (~(d1c + d2c + d3c) != ldadd2cc)
154    abort ();
155  /* The following call libgcc functions and so would fail unless they
156     call those for long double.  */
157  if (flt_minc * flt_minc != flt_min2)
158    abort ();
159  if (dbl_minc * dbl_minc * dbl_minc != dbl_min3)
160    abort ();
161  if (f4c / flt_minc != flt_div)
162    abort ();
163  if (d4c / dbl_minc != dbl_div)
164    abort ();
165  if (f4 / flt_minc != flt_div)
166    abort ();
167  if (d4 / dbl_minc != dbl_div)
168    abort ();
169  if (f4c / flt_min != flt_div)
170    abort ();
171  if (d4c / dbl_min != dbl_div)
172    abort ();
173}
174
175int
176main (void)
177{
178  test_add ();
179  test_sub ();
180  test_mul ();
181  test_div ();
182  test_cast ();
183  test_complex ();
184  exit (0);
185}
186