diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fc3ea262e3dfce066de1f688eb4ba23e3f165a1f..b2f0ee11ab96a2f58a152c69d8af130c2f9b0e91 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-03-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * gcc.dg/torture/builtin-convert-1.c: New test. + 2004-03-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * gcc.dg/torture/builtin-integral-1.c: Also check for `rint'. diff --git a/gcc/testsuite/gcc.dg/torture/builtin-convert-1.c b/gcc/testsuite/gcc.dg/torture/builtin-convert-1.c new file mode 100644 index 0000000000000000000000000000000000000000..d66d634071a398c03e75142d7284c1e65df93679 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/builtin-convert-1.c @@ -0,0 +1,116 @@ +/* Copyright (C) 2004 Free Software Foundation. + + Verify that built-in math function conversion to smaller FP types + is correctly performed by the compiler. + + Written by Kaveh Ghazi, 2004-03-17. */ + +/* { dg-do link } */ +/* { dg-options "-ffast-math" } */ + +#include "../builtins-config.h" + +/* This check is necessary when converting to a C99 function. */ +#ifdef HAVE_C99_RUNTIME +#define C99CODE(CODE) (CODE) +#define MAYBEC99(CODE, C99) (CODE) +#else +#define C99CODE(CODE) 0 +#define MAYBEC99(CODE, C99) (!(C99) && (CODE)) +#endif + +#define PROTOTYPE1(FN) extern double FN(double); extern float FN##f(float); \ + extern long double FN##l(long double); + +void test(double d1, float f1, long double ld1) +{ + /* Test converting math builtins to narrower FP types based on a + narrowing cast on the outside of the call. MATHFN is the + function to test, and C99 is 0/1 depending on whether the + `double' version of MATHFN is a C99 function. The optimization + is only performed if the replacement function is actually + narrower in width, so check that first. */ +#define OUTER_CAST1(MATHFN, C99) \ + PROTOTYPE1 (MATHFN) \ + extern void link_failure_outer_##MATHFN##l_##MATHFN##_1(void); \ + extern void link_failure_outer_##MATHFN##l_##MATHFN##_2(void); \ + extern void link_failure_outer_##MATHFN##l_##MATHFN##f_1(void); \ + extern void link_failure_outer_##MATHFN##l_##MATHFN##f_2(void); \ + extern void link_failure_outer_##MATHFN##_##MATHFN##f_1(void); \ + extern void link_failure_outer_##MATHFN##_##MATHFN##f_2(void); \ + if (sizeof (long double) > sizeof (double) \ + && MAYBEC99 ((double) MATHFN##l((double)ld1) != MATHFN(ld1), C99)) \ + link_failure_outer_##MATHFN##l_##MATHFN##_1(); \ + if (sizeof (long double) > sizeof (double) \ + && MAYBEC99 ((double) MATHFN##l(d1) != MATHFN(d1), C99)) \ + link_failure_outer_##MATHFN##l_##MATHFN##_1(); \ + if (sizeof (long double) > sizeof (double) \ + && MAYBEC99 ((double) MATHFN##l(f1) != MATHFN(f1), C99)) \ + link_failure_outer_##MATHFN##l_##MATHFN##_2(); \ + if (sizeof (long double) > sizeof (float) \ + && C99CODE ((float) MATHFN##l((float) ld1) != MATHFN##f(ld1))) \ + link_failure_outer_##MATHFN##l_##MATHFN##f_1(); \ + if (sizeof (long double) > sizeof (float) \ + && C99CODE ((float) MATHFN##l((float) d1) != MATHFN##f(d1))) \ + link_failure_outer_##MATHFN##l_##MATHFN##f_1(); \ + if (sizeof (long double) > sizeof (float) \ + && C99CODE ((float) MATHFN##l(f1) != MATHFN##f(f1))) \ + link_failure_outer_##MATHFN##l_##MATHFN##f_2(); \ + if (sizeof (double) > sizeof (float) \ + && C99CODE ((float) MATHFN((float) ld1) != MATHFN##f(ld1))) \ + link_failure_outer_##MATHFN##_##MATHFN##f_1(); \ + if (sizeof (double) > sizeof (float) \ + && C99CODE ((float) MATHFN((float) d1) != MATHFN##f(d1))) \ + link_failure_outer_##MATHFN##_##MATHFN##f_1(); \ + if (sizeof (double) > sizeof (float) \ + && C99CODE ((float) MATHFN(f1) != MATHFN##f(f1))) \ + link_failure_outer_##MATHFN##_##MATHFN##f_2() + + /* Test converting math builtins to narrower FP types based on if + the argument is a narrower type (perhaps implicitly) cast to a + wider one. */ +#define INNER_CAST1(MATHFN, C99) \ + PROTOTYPE1 (MATHFN) \ + extern void link_failure_inner_##MATHFN##l_##MATHFN(void); \ + extern void link_failure_inner_##MATHFN##l_##MATHFN##f(void); \ + extern void link_failure_inner_##MATHFN##_##MATHFN##f(void); \ + if (sizeof (long double) > sizeof (double) \ + && MAYBEC99 (MATHFN##l(d1) != (long double) MATHFN(d1), C99)) \ + link_failure_inner_##MATHFN##l_##MATHFN(); \ + if (sizeof (long double) > sizeof (float) \ + && C99CODE (MATHFN##l(f1) != (long double) MATHFN##f(f1))) \ + link_failure_inner_##MATHFN##l_##MATHFN##f(); \ + if (sizeof (long double) > sizeof (float) \ + && C99CODE (MATHFN##l((double)f1) != (long double) MATHFN##f(f1))) \ + link_failure_inner_##MATHFN##l_##MATHFN##f(); \ + if (sizeof (double) > sizeof (float) \ + && C99CODE (MATHFN(f1) != (double) MATHFN##f(f1))) \ + link_failure_inner_##MATHFN##_##MATHFN##f() + + +#ifdef __OPTIMIZE__ + OUTER_CAST1 (cos, /*C99=*/ 0); + OUTER_CAST1 (exp, /*C99=*/ 0); + OUTER_CAST1 (log, /*C99=*/ 0); + OUTER_CAST1 (sin, /*C99=*/ 0); + OUTER_CAST1 (sqrt, /*C99=*/ 0); + + INNER_CAST1 (ceil, /*C99=*/ 0); + OUTER_CAST1 (ceil, /*C99=*/ 0); + INNER_CAST1 (floor, /*C99=*/ 0); + OUTER_CAST1 (floor, /*C99=*/ 0); + INNER_CAST1 (nearbyint, /*C99=*/ 1); + OUTER_CAST1 (nearbyint, /*C99=*/ 1); + INNER_CAST1 (rint, /*C99=*/ 1); + OUTER_CAST1 (rint, /*C99=*/ 1); + INNER_CAST1 (round, /*C99=*/ 1); + OUTER_CAST1 (round, /*C99=*/ 1); + INNER_CAST1 (trunc, /*C99=*/ 1); + OUTER_CAST1 (trunc, /*C99=*/ 1); +#endif /* __OPTIMIZE__ */ +} + +int main (void) +{ + return 0; +}