Small ChangeLog tweak.
[official-gcc.git] / gcc / testsuite / gcc.dg / torture / builtin-math-4.c
blobd47e13933f22a87307c1e93bb89b7b574f57de7e
1 /* Copyright (C) 2007 Free Software Foundation.
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.
7 Origin: Kaveh R. Ghazi, April 23, 2007. */
9 /* { dg-do link } */
11 /* All references to link_error should go away at compile-time. */
12 extern void link_error(int);
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)))
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)
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)
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)
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)
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)
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)
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)
142 int main (void)
144 #ifdef __OPTIMIZE__
145 int q;
146 #endif
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... */
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... */
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 */
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 */
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... */
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... */
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... */
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... */
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... */
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... */
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... */
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... */
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... */
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 */
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 */
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 */
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 */
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. */
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)
250 if (sizeof(int)*__CHAR_BIT__ <= __FLT_MANT_DIG__)
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);
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);
263 if (sizeof(int)*__CHAR_BIT__ <= __DBL_MANT_DIG__)
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);
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);
276 if (sizeof(int)*__CHAR_BIT__ <= __LDBL_MANT_DIG__)
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);
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);
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... */
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
310 return 0;