OSDN Git Service

2010-05-02 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.dg / torture / builtin-math-4.c
1 /* Copyright (C) 2007  Free Software Foundation.
2
3    Verify that built-in math function constant folding of constant
4    arguments is correctly performed by the compiler.  This testcase is
5    for functionality that was available as of mpfr-2.3.0.
6
7    Origin: Kaveh R. Ghazi,  April 23, 2007.  */
8
9 /* { dg-do link } */
10
11 /* All references to link_error should go away at compile-time.  */
12 extern void link_error(int);
13
14 /* Return TRUE if the sign of X != sign of Y.  This is important when
15    comparing signed zeros.  */
16 #define CKSGN_F(X,Y) \
17   (__builtin_copysignf(1.0F,(X)) != __builtin_copysignf(1.0F,(Y)))
18 #define CKSGN(X,Y) \
19   (__builtin_copysign(1.0,(X)) != __builtin_copysign(1.0,(Y)))
20 #define CKSGN_L(X,Y) \
21   (__builtin_copysignl(1.0L,(X)) != __builtin_copysignl(1.0L,(Y)))
22
23 /* Test that FUNC(ARG) == (RES).  */
24 #define TESTIT(FUNC,ARG,RES) do { \
25   if (__builtin_##FUNC##f(ARG##F) != RES##F \
26       || CKSGN_F(__builtin_##FUNC##f(ARG##F),RES##F)) \
27     link_error(__LINE__); \
28   if (__builtin_##FUNC(ARG) != RES \
29       || CKSGN(__builtin_##FUNC(ARG),RES)) \
30     link_error(__LINE__); \
31   if (__builtin_##FUNC##l(ARG##L) != RES##L \
32       || CKSGN_L(__builtin_##FUNC##l(ARG##L),RES##L)) \
33     link_error(__LINE__); \
34   } while (0)
35
36 /* Range test, check that (LOW) < FUNC(ARG) < (HI).  */
37 #define TESTIT_R(FUNC,ARG,LOW,HI) do { \
38   if (__builtin_##FUNC##f(ARG) <= (LOW) || __builtin_##FUNC##f(ARG) >= (HI)) \
39     link_error(__LINE__); \
40   if (__builtin_##FUNC(ARG) <= (LOW) || __builtin_##FUNC(ARG) >= (HI)) \
41     link_error(__LINE__); \
42   if (__builtin_##FUNC##l(ARG) <= (LOW) || __builtin_##FUNC##l(ARG) >= (HI)) \
43     link_error(__LINE__); \
44   } while (0)
45
46 /* Test that FUNC(ARG1, ARG2) == (RES).  */
47 #define TESTIT2(FUNC,ARG1,ARG2,RES) do { \
48   if (__builtin_##FUNC##f(ARG1, ARG2##F) != RES##F \
49       || CKSGN_F(__builtin_##FUNC##f(ARG1,ARG2##F),RES##F)) \
50     link_error(__LINE__); \
51   if (__builtin_##FUNC(ARG1, ARG2) != RES \
52       || CKSGN(__builtin_##FUNC(ARG1,ARG2),RES)) \
53     link_error(__LINE__); \
54   if (__builtin_##FUNC##l(ARG1, ARG2##L) != RES##L \
55       || CKSGN_L(__builtin_##FUNC##l(ARG1,ARG2##L),RES##L)) \
56     link_error(__LINE__); \
57   } while (0)
58
59 /* Range test, check that (LOW) < FUNC(ARG1,ARG2) < (HI).  */
60 #define TESTIT2_R(FUNC,ARG1,ARG2,LOW,HI) do { \
61   if (__builtin_##FUNC##f(ARG1, ARG2##F) <= (LOW) \
62       || __builtin_##FUNC##f(ARG1, ARG2##F) >= (HI)) \
63     link_error(__LINE__); \
64   if (__builtin_##FUNC(ARG1, ARG2) <= (LOW) \
65       || __builtin_##FUNC(ARG1, ARG2) >= (HI)) \
66     link_error(__LINE__); \
67   if (__builtin_##FUNC##l(ARG1, ARG2##L) <= (LOW) \
68       || __builtin_##FUNC##l(ARG1, ARG2##L) >= (HI)) \
69     link_error(__LINE__); \
70   } while (0)
71
72 /* Test that remquo(ARG0, ARG1, &ARG_Q) == RES and ARG_Q == RES_Q.
73    Also test remainder/drem (ARG0,ARG1) == RES.  */
74 #define TESTIT2_REMQUO(ARG0,ARG1,ARG_Q,RES,RES_Q) do { \
75   ARG_Q = 12345; \
76   if (__builtin_remquof(ARG0##F, ARG1##F, &ARG_Q) != RES##F \
77       || CKSGN_F(__builtin_remquof(ARG0##F, ARG1##F, &ARG_Q),RES##F) \
78       || ARG_Q != RES_Q \
79       || __builtin_remainderf(ARG0##F, ARG1##F) != RES##F \
80       || CKSGN_F(__builtin_remainderf(ARG0##F, ARG1##F),RES##F) \
81       || __builtin_dremf(ARG0##F, ARG1##F) != RES##F \
82       || CKSGN_F(__builtin_dremf(ARG0##F, ARG1##F),RES##F)) \
83     link_error(__LINE__); \
84   ARG_Q = 12345; \
85   if (__builtin_remquo(ARG0, ARG1, &ARG_Q) != RES \
86       || CKSGN(__builtin_remquo(ARG0, ARG1, &ARG_Q),RES) \
87       || ARG_Q != RES_Q \
88       || __builtin_remainder(ARG0, ARG1) != RES \
89       || CKSGN(__builtin_remainder(ARG0, ARG1),RES) \
90       || __builtin_drem(ARG0, ARG1) != RES \
91       || CKSGN(__builtin_drem(ARG0, ARG1),RES)) \
92     link_error(__LINE__); \
93   ARG_Q = 12345; \
94   if (__builtin_remquol(ARG0##L, ARG1##L, &ARG_Q) != RES##L \
95       || CKSGN_L(__builtin_remquol(ARG0##L, ARG1##L, &ARG_Q),RES##L) \
96       || ARG_Q != RES_Q \
97       || __builtin_remainderl(ARG0##L, ARG1##L) != RES##L \
98       || CKSGN_L(__builtin_remainderl(ARG0##L, ARG1##L),RES##L) \
99       || __builtin_dreml(ARG0##L, ARG1##L) != RES##L \
100       || CKSGN_L(__builtin_dreml(ARG0##L, ARG1##L),RES##L)) \
101     link_error(__LINE__); \
102   } while (0)
103
104 /* Test that FUNC(ARG,&SG) == (RES) && SG == RES_SG.  */
105 #define TESTIT_LGAMMA_REENT(FUNC,ARG,RES,RES_SG) do { \
106   int sg; \
107   sg = 123; \
108   if (__builtin_##FUNC##f_r(ARG##F,&sg) != RES##F \
109       || sg != RES_SG \
110       || CKSGN_F(__builtin_##FUNC##f_r(ARG##F,&sg),RES##F)) \
111     link_error(__LINE__); \
112   sg = 123; \
113   if (__builtin_##FUNC##_r(ARG,&sg) != RES \
114       || sg != RES_SG \
115       || CKSGN(__builtin_##FUNC##_r(ARG,&sg),RES)) \
116     link_error(__LINE__); \
117   sg = 123; \
118   if (__builtin_##FUNC##l_r(ARG##L,&sg) != RES##L \
119       || sg != RES_SG \
120       || CKSGN_L(__builtin_##FUNC##l_r(ARG##L,&sg),RES##L)) \
121     link_error(__LINE__); \
122   } while (0)
123
124 /* Range test, check that (LOW) < FUNC(ARG,&SG) < (HI), and also test
125    that SG == RES_SG.  */
126 #define TESTIT_LGAMMA_REENT_R(FUNC,ARG,LOW,HI,RES_SG) do { \
127   int sg; \
128   sg = 123; \
129   if (__builtin_##FUNC##f_r(ARG,&sg) <= (LOW) || __builtin_##FUNC##f_r(ARG,&sg) >= (HI) \
130       || sg != RES_SG) \
131     link_error(__LINE__); \
132   sg = 123; \
133   if (__builtin_##FUNC##_r(ARG,&sg) <= (LOW) || __builtin_##FUNC##_r(ARG,&sg) >= (HI) \
134       || sg != RES_SG) \
135     link_error(__LINE__); \
136   sg = 123; \
137   if (__builtin_##FUNC##l_r(ARG,&sg) <= (LOW) || __builtin_##FUNC##l_r(ARG,&sg) >= (HI) \
138       || sg != RES_SG) \
139     link_error(__LINE__); \
140   } while (0)
141
142 int main (void)
143 {
144 #ifdef __OPTIMIZE__
145   int q;
146 #endif
147
148   TESTIT (j0, 0.0, 1.0); /* j0(0) == 1 */
149   TESTIT (j0, -0.0, 1.0); /* j0(-0) == 1 */
150   TESTIT_R (j0, 1.0, 0.765, 0.766); /* j0(1) == 0.7651... */
151   TESTIT_R (j0, -1.0, 0.765, 0.766); /* j0(-1) == 0.7651... */
152
153   TESTIT (j1, 0.0, 0.0); /* j1(0) == 0 */
154   TESTIT (j1, -0.0, -0.0); /* j1(-0) == -0 */
155   TESTIT_R (j1, 1.0, 0.44, 0.45); /* j1(1) == 0.440... */
156   TESTIT_R (j1, -1.0, -0.45, -0.44); /* j1(-1) == -0.440... */
157
158   TESTIT2 (jn, 5, 0.0, 0.0); /* jn(5,0) == 0 */
159   TESTIT2 (jn, 5, -0.0, -0.0); /* jn(5,-0) == -0 */
160   TESTIT2 (jn, 6, 0.0, 0.0); /* jn(6,0) == 0 */
161   TESTIT2 (jn, 6, -0.0, 0.0); /* jn(6,-0) == 0 */
162
163   TESTIT2 (jn, -5, 0.0, -0.0); /* jn(-5,0) == -0 */
164   TESTIT2 (jn, -5, -0.0, 0.0); /* jn(-5,-0) == 0 */
165   TESTIT2 (jn, -6, 0.0, 0.0); /* jn(-6,0) == 0 */
166   TESTIT2 (jn, -6, -0.0, 0.0); /* jn(-6,-0) == 0 */
167
168   TESTIT2_R (jn, 2, 1.0, 0.11, 0.12); /* jn(2,1) == 0.114... */
169   TESTIT2_R (jn, 2, -1.0, 0.11, 0.12); /* jn(2,-1) == 0.114... */
170   TESTIT2_R (jn, 3, 5.0, 0.36, 0.37); /* jn(3,5) == 0.364... */
171   TESTIT2_R (jn, 3, -5.0, -0.37, -0.36); /* jn(3,-5) == -0.364... */
172
173   TESTIT2_R (jn, -2, 1.0, 0.11, 0.12); /* jn(-2,1) == 0.114... */
174   TESTIT2_R (jn, -2, -1.0, 0.11, 0.12); /* jn(-2,-1) == 0.114... */
175   TESTIT2_R (jn, -3, 5.0, -0.37, -0.36); /* jn(-3,5) == -0.364... */
176   TESTIT2_R (jn, -3, -5.0, 0.36, 0.37); /* jn(-3,-5) == 0.364... */
177
178   TESTIT2_R (jn, 4, 3.5, 0.20, 0.21); /* jn(4,3.5) == 0.204... */
179   TESTIT2_R (jn, 4, -3.5, 0.20, 0.21); /* jn(4,-3.5) == 0.204... */
180   TESTIT2_R (jn, 5, 4.6, 0.20, 0.21); /* jn(5,4.6) == 0.207... */
181   TESTIT2_R (jn, 5, -4.6, -0.21, -0.20); /* jn(5,-4.6) == -0.207... */
182
183   TESTIT2_R (jn, -4, 3.5, 0.20, 0.21); /* jn(-4,3.5) == 0.204... */
184   TESTIT2_R (jn, -4, -3.5, 0.20, 0.21); /* jn(-4,-3.5) == 0.204... */
185   TESTIT2_R (jn, -5, 4.6, -0.21, -0.20); /* jn(-5,4.6) == -0.207... */
186   TESTIT2_R (jn, -5, -4.6, 0.20, 0.21); /* jn(-5,-4.6) == 0.207... */
187
188   TESTIT_R (y0, 5.0, -0.31, -0.30); /* y0(5) == -0.308... */
189   TESTIT_R (y0, 0.1, -1.54, -1.53); /* y0(0.1) == -1.534... */
190
191   TESTIT_R (y1, 5.0, 0.14, 0.15); /* y1(5) == 0.147... */
192   TESTIT_R (y1, 0.1, -6.46, -6.45); /* y1(0.1) == -6.458... */
193
194   TESTIT2_R (yn, -1, 3.0, -0.33, -0.32); /* yn(-1,3) == -0.324... */
195   TESTIT2_R (yn, -1, 0.25, 2.70, 2.71); /* yn(-1,0.25) == 2.704... */
196
197   TESTIT2_R (yn, 2, 4.0, 0.21, 0.22); /* yn(2,4) == 0.215... */
198   TESTIT2_R (yn, 2, 0.9, -1.95, -1.94); /* yn(2,0.9) == -1.945... */
199   TESTIT2_R (yn, -2, 4.0, 0.21, 0.22); /* yn(-2,4) == 0.215... */
200   TESTIT2_R (yn, -2, 0.9, -1.95, -1.94); /* yn(-2,0.9) == -1.945... */
201
202   TESTIT2_R (yn, 3, 6.0, 0.32, 0.33); /* yn(3,6) == 0.328... */
203   TESTIT2_R (yn, 3, 0.89, -8.03, -8.02); /* yn(3,0.89) == -8.020... */
204   TESTIT2_R (yn, -3, 8.0, -0.03, -0.02); /* yn(-3,8) == -0.026... */
205   TESTIT2_R (yn, -3, 0.99, 5.98, 5.99); /* yn(-3,0.99) == 5.982... */
206
207 #ifdef __OPTIMIZE__
208   /* These tests rely on propagating the variable q, which happens
209      only when optimization is turned on.  This macro also tests
210      remainder/drem.  */
211   TESTIT2_REMQUO (0.0, 1.0, q, 0.0, 0); /* remquo(0,1,&q)==0, q==0 */
212   TESTIT2_REMQUO (1.0, 1.0, q, 0.0, 1); /* remquo(1,1,&q)==0, q==1 */
213   TESTIT2_REMQUO (2.0, 1.0, q, 0.0, 2); /* remquo(2,1,&q)==0, q==2 */
214   TESTIT2_REMQUO (-0.0, 1.0, q, -0.0, 0); /* remquo(-0,1,&q)==-0, q==0 */
215   TESTIT2_REMQUO (-1.0, 1.0, q, -0.0, -1); /* remquo(-1,1,&q)==-0, q==-1 */
216   TESTIT2_REMQUO (-2.0, 1.0, q, -0.0, -2); /* remquo(-2,1,&q)==-0, q==-2 */
217
218   TESTIT2_REMQUO (0.0, -1.0, q, 0.0, 0); /* remquo(0,-1,&q)==0, q==0 */
219   TESTIT2_REMQUO (1.0, -1.0, q, 0.0, -1); /* remquo(1,-1,&q)==0, q==-1 */
220   TESTIT2_REMQUO (2.0, -1.0, q, 0.0, -2); /* remquo(2,-1,&q)==0, q==-2 */
221   TESTIT2_REMQUO (-0.0, -1.0, q, -0.0, 0); /* remquo(-0,-1,&q)==-0, q==0 */
222   TESTIT2_REMQUO (-1.0, -1.0, q, -0.0, 1); /* remquo(-1,-1,&q)==-0, q==1 */
223   TESTIT2_REMQUO (-2.0, -1.0, q, -0.0, 2); /* remquo(-2,-1,&q)==-0, q==2 */
224
225   TESTIT2_REMQUO (1.0, 2.0, q, 1.0, 0); /* remquo(1,2,&q)==1, q==0 */
226   TESTIT2_REMQUO (3.0, 2.0, q, -1.0, 2); /* remquo(3,2,&q)==-1, q==2 */
227   TESTIT2_REMQUO (5.0, 2.0, q, 1.0, 2); /* remquo(5,2,&q)==1, q==2 */
228   TESTIT2_REMQUO (-1.0, 2.0, q, -1.0, 0); /* remquo(-1,2,&q)==-1, q==0 */
229   TESTIT2_REMQUO (-3.0, 2.0, q, 1.0, -2); /* remquo(-3,2,&q)==1, q==-2 */
230   TESTIT2_REMQUO (-5.0, 2.0, q, -1.0, -2); /* remquo(-5,2,&q)==-1, q==-2 */
231
232   TESTIT2_REMQUO (1.0, -2.0, q, 1.0, 0); /* remquo(1,-2,&q)==1, q==0 */
233   TESTIT2_REMQUO (3.0, -2.0, q, -1.0, -2); /* remquo(3,-2,&q)==-1, q==-2 */
234   TESTIT2_REMQUO (5.0, -2.0, q, 1.0, -2); /* remquo(5,-2,&q)==1, q==-2 */
235   TESTIT2_REMQUO (-1.0, -2.0, q, -1.0, 0); /* remquo(-1,-2,&q)==-1, q==0 */
236   TESTIT2_REMQUO (-3.0, -2.0, q, 1.0, 2); /* remquo(-3,-2,&q)==1, q==2 */
237   TESTIT2_REMQUO (-5.0, -2.0, q, -1.0, 2); /* remquo(-5,-2,&q)==-1, q==2 */
238
239   /* Test that the maximum possible value can be generated into the
240      int quotient, and check for wrap around (modulo) when that value
241      is exceeded.  We can only check for this when the mantissa has
242      enough bits to hold an INT_MAX value with complete precision.  */
243
244 #define MAXIT(FUNC,X,R) do { \
245   q = 12345; \
246   if (__builtin_##FUNC((X), 1, &q) != 0 || q != (R)) \
247     link_error (__LINE__); \
248 } while (0)
249   
250   if (sizeof(int)*__CHAR_BIT__ <= __FLT_MANT_DIG__)
251   {
252     MAXIT(remquof, __INT_MAX__-1.0F, __INT_MAX__-1);
253     MAXIT(remquof, __INT_MAX__+0.0F, __INT_MAX__);
254     MAXIT(remquof, __INT_MAX__+1.0F, 0);
255     MAXIT(remquof, __INT_MAX__+2.0F, 1);
256
257     MAXIT(remquof, -(__INT_MAX__-1.0F), -(__INT_MAX__-1));
258     MAXIT(remquof, -(__INT_MAX__+0.0F), -__INT_MAX__);
259     MAXIT(remquof, -(__INT_MAX__+1.0F), 0);
260     MAXIT(remquof, -(__INT_MAX__+2.0F), -1);
261   }
262
263   if (sizeof(int)*__CHAR_BIT__ <= __DBL_MANT_DIG__)
264   {
265     MAXIT(remquo, __INT_MAX__-1.0, __INT_MAX__-1);
266     MAXIT(remquo, __INT_MAX__+0.0, __INT_MAX__);
267     MAXIT(remquo, __INT_MAX__+1.0, 0);
268     MAXIT(remquo, __INT_MAX__+2.0, 1);
269
270     MAXIT(remquo, -(__INT_MAX__-1.0), -(__INT_MAX__-1));
271     MAXIT(remquo, -(__INT_MAX__+0.0), -__INT_MAX__);
272     MAXIT(remquo, -(__INT_MAX__+1.0), 0);
273     MAXIT(remquo, -(__INT_MAX__+2.0), -1);
274   }
275
276   if (sizeof(int)*__CHAR_BIT__ <= __LDBL_MANT_DIG__)
277   {
278     MAXIT(remquo, __INT_MAX__-1.0L, __INT_MAX__-1);
279     MAXIT(remquo, __INT_MAX__+0.0L, __INT_MAX__);
280     MAXIT(remquo, __INT_MAX__+1.0L, 0);
281     MAXIT(remquo, __INT_MAX__+2.0L, 1);
282
283     MAXIT(remquol, -(__INT_MAX__-1.0L), -(__INT_MAX__-1));
284     MAXIT(remquol, -(__INT_MAX__+0.0L), -__INT_MAX__);
285     MAXIT(remquol, -(__INT_MAX__+1.0L), 0);
286     MAXIT(remquol, -(__INT_MAX__+2.0L), -1);
287   }
288
289   /* These tests rely on propagating the variable sg which contains
290      signgam.  This happens only when optimization is turned on.  */
291   TESTIT_LGAMMA_REENT_R (lgamma, -2.5, -0.06, -0.05, -1); /* lgamma_r(-2.5) == -0.056... */
292   TESTIT_LGAMMA_REENT_R (lgamma, -1.5, 0.86, 0.87, 1); /* lgamma_r(-1.5) == 0.860... */
293   TESTIT_LGAMMA_REENT_R (lgamma, -0.5, 1.26, 1.27, -1); /* lgamma_r(-0.5) == 1.265... */
294   TESTIT_LGAMMA_REENT_R (lgamma, 0.5, 0.57, 0.58, 1); /* lgamma_r(0.5) == 0.572... */
295   TESTIT_LGAMMA_REENT (lgamma, 1.0, 0.0, 1); /* lgamma_r(1) == 0 */
296   TESTIT_LGAMMA_REENT_R (lgamma, 1.5, -0.13, -0.12, 1); /* lgamma_r(1.5) == -0.120... */
297   TESTIT_LGAMMA_REENT (lgamma, 2.0, 0.0, 1); /* lgamma_r(2) == 0 */
298   TESTIT_LGAMMA_REENT_R (lgamma, 2.5, 0.28, 0.29, 1); /* lgamma_r(2.5) == 0.284... */
299
300   TESTIT_LGAMMA_REENT_R (gamma, -2.5, -0.06, -0.05, -1); /* gamma_r(-2.5) == -0.056... */
301   TESTIT_LGAMMA_REENT_R (gamma, -1.5, 0.86, 0.87, 1); /* gamma_r(-1.5) == 0.860... */
302   TESTIT_LGAMMA_REENT_R (gamma, -0.5, 1.26, 1.27, -1); /* gamma_r(-0.5) == 1.265... */
303   TESTIT_LGAMMA_REENT_R (gamma, 0.5, 0.57, 0.58, 1); /* gamma_r(0.5) == 0.572... */
304   TESTIT_LGAMMA_REENT (gamma, 1.0, 0.0, 1); /* gamma_r(1) == 0 */
305   TESTIT_LGAMMA_REENT_R (gamma, 1.5, -0.13, -0.12, 1); /* gamma_r(1.5) == -0.120... */
306   TESTIT_LGAMMA_REENT (gamma, 2.0, 0.0, 1); /* gamma_r(2) == 0 */
307   TESTIT_LGAMMA_REENT_R (gamma, 2.5, 0.28, 0.29, 1); /* gamma_r(2.5) == 0.284... */
308 #endif
309   
310   return 0;
311 }