1/* Copyright (C) 2003, 2005  Free Software Foundation.
2
3   Verify that the `const' function attribute is applied to various
4   builtins and that these functions are optimized away by the
5   compiler under the appropriate circumstances.
6
7   Written by Kaveh Ghazi, 2003-08-04.  */
8
9/* { dg-do link } */
10/* { dg-options "-ffast-math" } */
11
12/* These are helper macros to test combinations of functions.  We test
13   foo() != foo() with the same arguments, and expect the compiler to
14   optimize away these tests of const functions.  */
15
16/* Just test the __builtin_ functions.  */
17#define BUILTIN_TEST1(FN, TYPE) \
18extern void link_failure_builtin_##FN(void); \
19void test_builtin_##FN(TYPE x) \
20{ if (__builtin_##FN(x) != __builtin_##FN(x)) link_failure_builtin_##FN(); }
21
22/* Just test the __builtin_ functions.  */
23#define BUILTIN_TEST2(FN, TYPE) \
24extern void link_failure_builtin_##FN(void); \
25void test_builtin_##FN(TYPE x, TYPE y) \
26{ if (__builtin_##FN(x,y) != __builtin_##FN(x,y)) link_failure_builtin_##FN(); }
27
28/* Also test the regular (non-__builtin_) function.  */
29#define TEST1(FN, TYPE, RTYPE) \
30BUILTIN_TEST1(FN, TYPE) \
31extern void link_failure_##FN(void); \
32extern RTYPE FN(TYPE); \
33void test_##FN(TYPE x) { if (FN(x) != FN(x)) link_failure_##FN(); }
34
35/* Test the __builtin_ functions taking void arguments (with the "f"
36   and "l" variants).  */
37#define BUILTIN_FPTEST0(FN) \
38extern void link_failure_builtin_##FN(void); \
39extern void link_failure_builtin_##FN##f(void); \
40extern void link_failure_builtin_##FN##l(void); \
41void test_builtin_##FN(void) \
42{ if (__builtin_##FN() != __builtin_##FN()) link_failure_builtin_##FN(); } \
43void test_builtin_##FN##f(void) \
44{ if (__builtin_##FN##f() != __builtin_##FN##f()) link_failure_builtin_##FN##f(); } \
45void test_builtin_##FN##l(void) \
46{ if (__builtin_##FN##l() != __builtin_##FN##l()) link_failure_builtin_##FN##l(); }
47
48/* Test the __builtin_ functions taking one FP argument (with the "f"
49   and "l" variants).  */
50#define BUILTIN_FPTEST1(FN) \
51extern void link_failure_builtin_##FN(void); \
52extern void link_failure_builtin_##FN##f(void); \
53extern void link_failure_builtin_##FN##l(void); \
54void test_builtin_##FN(double d) \
55{ if (__builtin_##FN(d) != __builtin_##FN(d)) link_failure_builtin_##FN(); } \
56void test_builtin_##FN##f(float f) \
57{ if (__builtin_##FN##f(f) != __builtin_##FN##f(f)) link_failure_builtin_##FN##f(); } \
58void test_builtin_##FN##l(long double ld) \
59{ if (__builtin_##FN##l(ld) != __builtin_##FN##l(ld)) link_failure_builtin_##FN##l(); }
60
61/* Test the __builtin_ functions taking one argument of supplied type
62   (with the "f" and "l" variants).  */
63#define BUILTIN_FPTEST1ARG(FN, TYPE) \
64extern void link_failure_builtin_##FN(void); \
65extern void link_failure_builtin_##FN##f(void); \
66extern void link_failure_builtin_##FN##l(void); \
67void test_builtin_##FN(TYPE x) \
68{ if (__builtin_##FN(x) != __builtin_##FN(x)) link_failure_builtin_##FN(); } \
69void test_builtin_##FN##f(TYPE x) \
70{ if (__builtin_##FN##f(x) != __builtin_##FN##f(x)) link_failure_builtin_##FN##f(); } \
71void test_builtin_##FN##l(TYPE x) \
72{ if (__builtin_##FN##l(x) != __builtin_##FN##l(x)) link_failure_builtin_##FN##l(); }
73
74/* Test the __builtin_ functions taking two FP arguments (with the "f"
75   and "l" variants).  */
76#define BUILTIN_FPTEST2(FN) \
77extern void link_failure_builtin_##FN(void); \
78extern void link_failure_builtin_##FN##f(void); \
79extern void link_failure_builtin_##FN##l(void); \
80void test_builtin_##FN(double d1, double d2) \
81{ if (__builtin_##FN(d1,d2) != __builtin_##FN(d1,d2)) link_failure_builtin_##FN(); } \
82void test_builtin_##FN##f(float f1, float f2) \
83{ if (__builtin_##FN##f(f1,f2) != __builtin_##FN##f(f1,f2)) link_failure_builtin_##FN##f(); } \
84void test_builtin_##FN##l(long double ld1, long double ld2) \
85{ if (__builtin_##FN##l(ld1,ld2) != __builtin_##FN##l(ld1,ld2)) link_failure_builtin_##FN##l(); }
86
87/* Test the __builtin_ functions taking two arguments, the first one
88   is of a supplied type and the second one one is of FP type (with
89   the "f" and "l" variants).  */
90#define BUILTIN_FPTEST2ARG1(FN, TYPE) \
91extern void link_failure_builtin_##FN(void); \
92extern void link_failure_builtin_##FN##f(void); \
93extern void link_failure_builtin_##FN##l(void); \
94void test_builtin_##FN(TYPE x, double d) \
95{ if (__builtin_##FN(x,d) != __builtin_##FN(x,d)) link_failure_builtin_##FN(); } \
96void test_builtin_##FN##f(TYPE x, float f) \
97{ if (__builtin_##FN##f(x,f) != __builtin_##FN##f(x,f)) link_failure_builtin_##FN##f(); } \
98void test_builtin_##FN##l(TYPE x, long double ld) \
99{ if (__builtin_##FN##l(x,ld) != __builtin_##FN##l(x,ld)) link_failure_builtin_##FN##l(); }
100
101/* Test the __builtin_ functions taking two arguments, the first one
102   is of FP type and the second one one is of a supplied type (with
103   the "f" and "l" variants).  */
104#define BUILTIN_FPTEST2ARG2(FN, TYPE) \
105extern void link_failure_builtin_##FN(void); \
106extern void link_failure_builtin_##FN##f(void); \
107extern void link_failure_builtin_##FN##l(void); \
108void test_builtin_##FN(double d, TYPE x) \
109{ if (__builtin_##FN(d,x) != __builtin_##FN(d,x)) link_failure_builtin_##FN(); } \
110void test_builtin_##FN##f(float f, TYPE x) \
111{ if (__builtin_##FN##f(f,x) != __builtin_##FN##f(f,x)) link_failure_builtin_##FN##f(); } \
112void test_builtin_##FN##l(long double ld, TYPE x) \
113{ if (__builtin_##FN##l(ld,x) != __builtin_##FN##l(ld,x)) link_failure_builtin_##FN##l(); }
114
115/* Test the __builtin_ functions taking three FP arguments (with the
116   "f" and "l" variants).  */
117#define BUILTIN_FPTEST3(FN) \
118extern void link_failure_builtin_##FN(void); \
119extern void link_failure_builtin_##FN##f(void); \
120extern void link_failure_builtin_##FN##l(void); \
121void test_builtin_##FN(double d1, double d2, double d3) \
122{ if (__builtin_##FN(d1,d2,d3) != __builtin_##FN(d1,d2,d3)) link_failure_builtin_##FN(); } \
123void test_builtin_##FN##f(float f1, float f2, float f3) \
124{ if (__builtin_##FN##f(f1,f2,f3) != __builtin_##FN##f(f1,f2,f3)) link_failure_builtin_##FN##f(); } \
125void test_builtin_##FN##l(long double ld1, long double ld2, long double ld3) \
126{ if (__builtin_##FN##l(ld1,ld2,ld3) != __builtin_##FN##l(ld1,ld2,ld3)) link_failure_builtin_##FN##l(); }
127
128/* Test the __builtin_ functions taking one complex argument (with the
129   "f" and "l" variants).  */
130#define BUILTIN_CPTEST1(FN) \
131extern void link_failure_builtin_##FN(void); \
132extern void link_failure_builtin_##FN##f(void); \
133extern void link_failure_builtin_##FN##l(void); \
134void test_builtin_##FN(_Complex double d) \
135{ if (__builtin_##FN(d) != __builtin_##FN(d)) link_failure_builtin_##FN(); } \
136void test_builtin_##FN##f(_Complex float f) \
137{ if (__builtin_##FN##f(f) != __builtin_##FN##f(f)) link_failure_builtin_##FN##f(); } \
138void test_builtin_##FN##l(_Complex long double ld) \
139{ if (__builtin_##FN##l(ld) != __builtin_##FN##l(ld)) link_failure_builtin_##FN##l(); }
140
141/* Test the __builtin_ functions taking two complex arguments (with
142   the "f" and "l" variants).  */
143#define BUILTIN_CPTEST2(FN) \
144extern void link_failure_builtin_##FN(void); \
145extern void link_failure_builtin_##FN##f(void); \
146extern void link_failure_builtin_##FN##l(void); \
147void test_builtin_##FN(_Complex double d1, _Complex double d2) \
148{ if (__builtin_##FN(d1,d2) != __builtin_##FN(d1,d2)) link_failure_builtin_##FN(); } \
149void test_builtin_##FN##f(_Complex float f1, _Complex float f2) \
150{ if (__builtin_##FN##f(f1,f2) != __builtin_##FN##f(f1,f2)) link_failure_builtin_##FN##f(); } \
151void test_builtin_##FN##l(_Complex long double ld1, _Complex long double ld2) \
152{ if (__builtin_##FN##l(ld1,ld2) != __builtin_##FN##l(ld1,ld2)) link_failure_builtin_##FN##l(); }
153
154/* These macros additionally test the non-__builtin_ functions.  */
155
156/* Test the functions taking one FP argument (with the "f" and "l"
157   variants) and returning that type.  */
158#define FPTEST1(FN) \
159BUILTIN_FPTEST1(FN) \
160extern void link_failure_##FN(void); \
161extern void link_failure_##FN##f(void); \
162extern void link_failure_##FN##l(void); \
163extern double FN(double); \
164extern float FN##f(float); \
165extern long double FN##l(long double); \
166void test_##FN(double d) \
167{ if (FN(d) != FN(d)) link_failure_##FN(); } \
168void test_##FN##f(float f) \
169{ if (FN##f(f) != FN##f(f)) link_failure_##FN##f(); } \
170void test_##FN##l(long double ld) \
171{ if (FN##l(ld) != FN##l(ld)) link_failure_##FN##l(); }
172
173/* Test the functions taking one FP argument (with the "f" and "l"
174   variants) and returning TYPE.  */
175#define FPTEST1T(FN, TYPE) \
176BUILTIN_FPTEST1(FN) \
177extern void link_failure_##FN(void); \
178extern void link_failure_##FN##f(void); \
179extern void link_failure_##FN##l(void); \
180extern TYPE FN(double); \
181extern TYPE FN##f(float); \
182extern TYPE FN##l(long double); \
183void test_##FN(double d) \
184{ if (FN(d) != FN(d)) link_failure_##FN(); } \
185void test_##FN##f(float f) \
186{ if (FN##f(f) != FN##f(f)) link_failure_##FN##f(); } \
187void test_##FN##l(long double ld) \
188{ if (FN##l(ld) != FN##l(ld)) link_failure_##FN##l(); }
189
190/* Test the functions taking two FP arguments (with the "f" and "l"
191   variants).  */
192#define FPTEST2(FN) \
193BUILTIN_FPTEST2(FN) \
194extern void link_failure_##FN(void); \
195extern void link_failure_##FN##f(void); \
196extern void link_failure_##FN##l(void); \
197extern double FN(double, double); \
198extern float FN##f(float, float); \
199extern long double FN##l(long double, long double); \
200void test_##FN(double d1, double d2) \
201{ if (FN(d1,d2) != FN(d1,d2)) link_failure_##FN(); } \
202void test_##FN##f(float f1, float f2) \
203{ if (FN##f(f1,f2) != FN##f(f1,f2)) link_failure_##FN##f(); } \
204void test_##FN##l(long double ld1, long double ld2) \
205{ if (FN##l(ld1,ld2) != FN##l(ld1,ld2)) link_failure_##FN##l(); }
206
207/* Test the functions taking two arguments, the first one is of a
208   supplied type and the second one one is of FP type (with the "f"
209   and "l" variants).  */
210#define FPTEST2ARG1(FN, TYPE) \
211BUILTIN_FPTEST2ARG1(FN, TYPE) \
212extern void link_failure_##FN(void); \
213extern void link_failure_##FN##f(void); \
214extern void link_failure_##FN##l(void); \
215extern double FN(TYPE, double); \
216extern float FN##f(TYPE, float); \
217extern long double FN##l(TYPE, long double); \
218void test_##FN(TYPE x, double d) \
219{ if (FN(x,d) != FN(x,d)) link_failure_##FN(); } \
220void test_##FN##f(TYPE x, float f) \
221{ if (FN##f(x,f) != FN##f(x,f)) link_failure_##FN##f(); } \
222void test_##FN##l(TYPE x, long double ld) \
223{ if (FN##l(x,ld) != FN##l(x,ld)) link_failure_##FN##l(); }
224
225/* Test the functions taking two arguments, the first one is of FP
226   type and the second one one is of a supplied type (with the "f" and
227   "l" variants).  */
228#define FPTEST2ARG2(FN, TYPE) \
229BUILTIN_FPTEST2ARG2(FN, TYPE) \
230extern void link_failure_##FN(void); \
231extern void link_failure_##FN##f(void); \
232extern void link_failure_##FN##l(void); \
233extern double FN(double, TYPE); \
234extern float FN##f(float, TYPE); \
235extern long double FN##l(long double, TYPE); \
236void test_##FN(double d, TYPE x) \
237{ if (FN(d,x) != FN(d,x)) link_failure_##FN(); } \
238void test_##FN##f(float f, TYPE x) \
239{ if (FN##f(f,x) != FN##f(f,x)) link_failure_##FN##f(); } \
240void test_##FN##l(long double ld, TYPE x) \
241{ if (FN##l(ld,x) != FN##l(ld,x)) link_failure_##FN##l(); }
242
243/* Test the functions taking three FP arguments (with the "f" and "l"
244   variants).  */
245#define FPTEST3(FN) \
246BUILTIN_FPTEST3(FN) \
247extern void link_failure_##FN(void); \
248extern void link_failure_##FN##f(void); \
249extern void link_failure_##FN##l(void); \
250extern double FN(double, double, double); \
251extern float FN##f(float, float, float); \
252extern long double FN##l(long double, long double, long double); \
253void test_##FN(double d1, double d2, double d3) \
254{ if (FN(d1,d2,d3) != FN(d1,d2,d3)) link_failure_##FN(); } \
255void test_##FN##f(float f1, float f2, float f3) \
256{ if (FN##f(f1,f2,f3) != FN##f(f1,f2,f3)) link_failure_##FN##f(); } \
257void test_##FN##l(long double ld1, long double ld2, long double ld3) \
258{ if (FN##l(ld1,ld2,ld3) != FN##l(ld1,ld2,ld3)) link_failure_##FN##l(); }
259
260/* Test the functions taking one complex argument (with the "f" and
261   "l" variants) and returning that type.  */
262#define CPTEST1(FN) \
263BUILTIN_CPTEST1(FN) \
264extern void link_failure_##FN(void); \
265extern void link_failure_##FN##f(void); \
266extern void link_failure_##FN##l(void); \
267extern _Complex double FN(_Complex double); \
268extern _Complex float FN##f(_Complex float); \
269extern _Complex long double FN##l(_Complex long double); \
270void test_##FN(_Complex double d) \
271{ if (FN(d) != FN(d)) link_failure_##FN(); } \
272void test_##FN##f(_Complex float f) \
273{ if (FN##f(f) != FN##f(f)) link_failure_##FN##f(); } \
274void test_##FN##l(_Complex long double ld) \
275{ if (FN##l(ld) != FN##l(ld)) link_failure_##FN##l(); }
276
277/* Test the functions taking one complex argument (with the "f" and
278   "l" variants) and returning the real type.  */
279#define CPTEST1R(FN) \
280BUILTIN_CPTEST1(FN) \
281extern void link_failure_##FN(void); \
282extern void link_failure_##FN##f(void); \
283extern void link_failure_##FN##l(void); \
284extern double FN(_Complex double); \
285extern float FN##f(_Complex float); \
286extern long double FN##l(_Complex long double); \
287void test_##FN(_Complex double d) \
288{ if (FN(d) != FN(d)) link_failure_##FN(); } \
289void test_##FN##f(_Complex float f) \
290{ if (FN##f(f) != FN##f(f)) link_failure_##FN##f(); } \
291void test_##FN##l(_Complex long double ld) \
292{ if (FN##l(ld) != FN##l(ld)) link_failure_##FN##l(); }
293
294/* Test the functions taking two complex arguments (with the "f" and
295   "l" variants).  */
296#define CPTEST2(FN) \
297BUILTIN_CPTEST2(FN) \
298extern void link_failure_##FN(void); \
299extern void link_failure_##FN##f(void); \
300extern void link_failure_##FN##l(void); \
301extern _Complex double FN(_Complex double, _Complex double); \
302extern _Complex float FN##f(_Complex float, _Complex float); \
303extern _Complex long double FN##l(_Complex long double, _Complex long double); \
304void test_##FN(_Complex double d1, _Complex double d2) \
305{ if (FN(d1,d2) != FN(d1,d2)) link_failure_##FN(); } \
306void test_##FN##f(_Complex float f1, _Complex float f2) \
307{ if (FN##f(f1,f2) != FN##f(f1,f2)) link_failure_##FN##f(); } \
308void test_##FN##l(_Complex long double ld1, _Complex long double ld2) \
309{ if (FN##l(ld1,ld2) != FN##l(ld1,ld2)) link_failure_##FN##l(); }
310
311
312/* Test the math builtins.  */
313FPTEST1            (acos)
314FPTEST1            (acosh)
315FPTEST1            (asin)
316FPTEST1            (asinh)
317FPTEST1            (atan)
318FPTEST2            (atan2)
319FPTEST1            (atanh)
320FPTEST1            (cbrt)
321FPTEST1            (ceil)
322FPTEST2            (copysign)
323FPTEST1            (cos)
324FPTEST1            (cosh)
325FPTEST2            (drem)
326FPTEST1            (erf)
327FPTEST1            (erfc)
328FPTEST1            (exp)
329FPTEST1            (exp10)
330FPTEST1            (exp2)
331FPTEST1            (expm1)
332FPTEST1            (fabs)
333FPTEST2            (fdim)
334FPTEST1            (floor)
335FPTEST3            (fma)
336FPTEST2            (fmax)
337FPTEST2            (fmin)
338FPTEST2            (fmod)
339BUILTIN_FPTEST0    (huge_val)
340FPTEST2            (hypot)
341FPTEST1T           (ilogb, int)
342BUILTIN_FPTEST0    (inf) /* { dg-warning "does not support infinity" "INF unsupported" { target vax-*-* pdp11-*-* spu-*-* } } */
343FPTEST1            (j0)
344FPTEST1            (j1)
345FPTEST2ARG1        (jn, int)
346FPTEST2ARG2        (ldexp, int)
347BUILTIN_FPTEST1    (llceil)
348BUILTIN_FPTEST1    (llfloor)
349FPTEST1T           (llrint, long long)
350FPTEST1T           (llround, long long)
351FPTEST1            (log)
352FPTEST1            (log10)
353FPTEST1            (log1p)
354FPTEST1            (log2)
355FPTEST1            (logb)
356BUILTIN_FPTEST1    (lceil)
357BUILTIN_FPTEST1    (lfloor)
358FPTEST1T           (lrint, long)
359FPTEST1T           (lround, long)
360BUILTIN_FPTEST1ARG (nan, char *)
361BUILTIN_FPTEST1ARG (nans, char *)
362FPTEST1            (nearbyint)
363FPTEST2            (nextafter)
364FPTEST2ARG2        (nexttoward, long double)
365FPTEST2            (pow)
366FPTEST1            (pow10)
367FPTEST2            (remainder)
368FPTEST1            (rint)
369FPTEST1            (round)
370FPTEST2            (scalb)
371FPTEST2ARG2        (scalbn, int)
372FPTEST2ARG2        (scalbln, long int)
373FPTEST1            (significand)
374FPTEST1            (sin)
375FPTEST1            (sinh)
376FPTEST1            (sqrt)
377FPTEST1            (tan)
378FPTEST1            (tanh)
379FPTEST1            (tgamma)
380FPTEST1            (trunc)
381FPTEST1            (y0)
382FPTEST1            (y1)
383FPTEST2ARG1        (yn, int)
384
385/* Test the complex math builtins.  */
386/*CPTEST1 (cabs) See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00040.html */
387CPTEST1 (cacos)
388CPTEST1 (cacosh)
389CPTEST1R (carg)
390CPTEST1 (casin)
391CPTEST1 (casinh)
392CPTEST1 (catan)
393CPTEST1 (catanh)
394CPTEST1 (ccos)
395CPTEST1 (ccosh)
396CPTEST1 (cexp)
397CPTEST1R (cimag)
398CPTEST1 (clog)
399CPTEST1 (conj)
400CPTEST2 (cpow)
401CPTEST1 (cproj)
402CPTEST1R (creal)
403CPTEST1 (csin)
404CPTEST1 (csinh)
405CPTEST1 (csqrt)
406CPTEST1 (ctan)
407CPTEST1 (ctanh)
408
409typedef __INTMAX_TYPE__ intmax_t;
410
411/* Various other const builtins.  */
412TEST1         (abs, int, int)
413BUILTIN_TEST1 (clz, int)
414BUILTIN_TEST1 (clzl, long)
415BUILTIN_TEST1 (clzll, long long)
416BUILTIN_TEST1 (ctz, int)
417BUILTIN_TEST1 (ctzl, long)
418BUILTIN_TEST1 (ctzll, long long)
419TEST1         (ffs, int, int)
420TEST1         (ffsl, long, int)
421TEST1         (ffsll, long long, int)
422TEST1         (imaxabs, intmax_t, intmax_t)
423TEST1         (labs, long, long)
424TEST1         (llabs, long long, long long)
425BUILTIN_TEST1 (parity, int)
426BUILTIN_TEST1 (parityl, long)
427BUILTIN_TEST1 (parityll, long long)
428BUILTIN_TEST1 (popcount, int)
429BUILTIN_TEST1 (popcountl, long)
430BUILTIN_TEST1 (popcountll, long long)
431
432int main(void)
433{
434  return 0;
435}
436