[PATCH MIDDLE-END]: Use mpc_pow to fold builtin cpow

Richard Guenther richard.guenther@gmail.com
Tue Jul 14 22:03:00 GMT 2009


On Tue, Jul 14, 2009 at 9:39 PM, Kaveh R. GHAZI<ghazi@caip.rutgers.edu> wrote:
> This patch utilizes mpc_pow to fold builtin cpow.
>
> The mpc_pow function is available in the MPC repository (i.e. not in
> mpc-0.6) but it will be in the next official MPC release.  So for now, I
> have added cpp version checks before using mpc_pow.  These will go away
> once the new MPC is released and I upgrade the version used in gcc's
> configure.  (This is the same strategy I used for mpc_pow in the fortran
> frontend.)
>
> I added a testsuite check for mpc_pow support.  Using this effective
> target for builtin-math-6.c as a side-effect fixes PR40544.
>
> I also fixed the spu float cases.  So this patch supercedes this:
> http://gcc.gnu.org/ml/gcc-patches/2009-05/msg01412.html
> which never got reviewed.
>
> Patch tested on x86_64-unknown-linux-gnu without MPC, with mpc-0.6 and
> with the most recent svn MPC.  No regressions for all three cases.
>
> Okay for mainline?

The middle-end parts are ok, the testsuite parts need separate approval.

Thanks,
Richard.

>                Thanks,
>                --Kaveh
>
>
> 2009-07-06  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
>
>        * builtins.c (do_mpc_arg2): New.
>        (fold_builtin_2): Fold builtin cpow.
>        * real.h (HAVE_mpc_pow): New.
>
> testsuite:
>        * gcc.dg/torture/builtin-math-5.c: Add more cases.
>        * gcc.dg/torture/builtin-math-6.c: Likewise.  Depend on
>        effective target "mpc_pow".
>        * lib/target-supports.exp (check_effective_target_mpc_pow): New.
>
> diff -rup orig/egcc-SVN20090714/gcc/builtins.c egcc-SVN20090714/gcc/builtins.c
> --- orig/egcc-SVN20090714/gcc/builtins.c        2009-06-29 02:02:21.000000000 +0200
> +++ egcc-SVN20090714/gcc/builtins.c     2009-07-14 17:35:52.000000000 +0200
> @@ -60,6 +60,9 @@ along with GCC; see the file COPYING3.
>  #endif
>  #ifdef HAVE_mpc
>  static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
> +#ifdef HAVE_mpc_pow
> +static tree do_mpc_arg2 (tree, tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t));
> +#endif
>  #endif
>
>  /* Define the names of the builtin function types and codes.  */
> @@ -10638,6 +10641,16 @@ fold_builtin_2 (tree fndecl, tree arg0,
>     CASE_FLT_FN (BUILT_IN_HYPOT):
>       return fold_builtin_hypot (fndecl, arg0, arg1, type);
>
> +#ifdef HAVE_mpc_pow
> +    CASE_FLT_FN (BUILT_IN_CPOW):
> +      if (validate_arg (arg0, COMPLEX_TYPE)
> +         && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
> +         && validate_arg (arg1, COMPLEX_TYPE)
> +         && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE)
> +       return do_mpc_arg2 (arg0, arg1, type, mpc_pow);
> +    break;
> +#endif
> +
>     CASE_FLT_FN (BUILT_IN_LDEXP):
>       return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/true);
>     CASE_FLT_FN (BUILT_IN_SCALBN):
> @@ -13706,6 +13719,64 @@ do_mpc_arg1 (tree arg, tree type, int (*
>
>   return result;
>  }
> +
> +/* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument
> +   mpc function FUNC on it and return the resulting value as a tree
> +   with type TYPE.  The mpfr precision is set to the precision of
> +   TYPE.  We assume that function FUNC returns zero if the result
> +   could be calculated exactly within the requested precision.  */
> +
> +#ifdef HAVE_mpc_pow
> +static tree
> +do_mpc_arg2 (tree arg0, tree arg1, tree type,
> +            int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t))
> +{
> +  tree result = NULL_TREE;
> +
> +  STRIP_NOPS (arg0);
> +  STRIP_NOPS (arg1);
> +
> +  /* To proceed, MPFR must exactly represent the target floating point
> +     format, which only happens when the target base equals two.  */
> +  if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0)
> +      && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
> +      && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1)
> +      && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE
> +      && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2)
> +    {
> +      const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
> +      const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
> +      const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1));
> +      const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1));
> +
> +      if (real_isfinite (re0) && real_isfinite (im0)
> +         && real_isfinite (re1) && real_isfinite (im1))
> +        {
> +         const struct real_format *const fmt =
> +           REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
> +         const int prec = fmt->p;
> +         const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
> +         const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
> +         int inexact;
> +         mpc_t m0, m1;
> +
> +         mpc_init2 (m0, prec);
> +         mpc_init2 (m1, prec);
> +         mpfr_from_real (mpc_realref(m0), re0, rnd);
> +         mpfr_from_real (mpc_imagref(m0), im0, rnd);
> +         mpfr_from_real (mpc_realref(m1), re1, rnd);
> +         mpfr_from_real (mpc_imagref(m1), im1, rnd);
> +         mpfr_clear_flags ();
> +         inexact = func (m0, m0, m1, crnd);
> +         result = do_mpc_ckconv (m0, type, inexact);
> +         mpc_clear (m0);
> +         mpc_clear (m1);
> +       }
> +    }
> +
> +  return result;
> +}
> +# endif
>  #endif /* HAVE_mpc */
>
>  /* FIXME tuples.
> diff -rup orig/egcc-SVN20090714/gcc/real.h egcc-SVN20090714/gcc/real.h
> --- orig/egcc-SVN20090714/gcc/real.h    2009-05-16 02:01:58.000000000 +0200
> +++ egcc-SVN20090714/gcc/real.h 2009-07-14 17:35:52.000000000 +0200
> @@ -26,6 +26,9 @@
>  #include <mpfr.h>
>  #ifdef HAVE_mpc
>  #include <mpc.h>
> +# if MPC_VERSION >= MPC_VERSION_NUM(0,6,1)
> +#  define HAVE_mpc_pow
> +# endif
>  #endif
>  #endif
>  #include "machmode.h"
> diff -rup orig/egcc-SVN20090714/gcc/testsuite/gcc.dg/torture/builtin-math-5.c egcc-SVN20090714/gcc/testsuite/gcc.dg/torture/builtin-math-5.c
> --- orig/egcc-SVN20090714/gcc/testsuite/gcc.dg/torture/builtin-math-5.c 2009-05-16 02:01:55.000000000 +0200
> +++ egcc-SVN20090714/gcc/testsuite/gcc.dg/torture/builtin-math-5.c      2009-07-14 18:16:58.000000000 +0200
> @@ -18,6 +18,12 @@ extern void fool (_Complex long double);
>   fool (__builtin_##FUNC##l (ARG##L)); \
>  } while (0)
>
> +#define TESTIT2(FUNC, ARG0, ARG1) do { \
> +  foof (__builtin_##FUNC##f (ARG0##F, ARG1##F)); \
> +  foo (__builtin_##FUNC (ARG0, ARG1)); \
> +  fool (__builtin_##FUNC##l (ARG0##L, ARG1##L)); \
> +} while (0)
> +
>  void bar()
>  {
>   /* An argument of NaN is not evaluated at compile-time.  */
> @@ -38,9 +44,80 @@ void bar()
>  #endif
>   foo (__builtin_csqrt (-__builtin_inf()));
>   fool (__builtin_csqrtl (-__builtin_infl()));
> +
> +  /* Check for overflow/underflow.  */
> +  TESTIT (cexp, 1e20);
> +  TESTIT (cexp, -1e20);
> +
> +  /* An argument of NaN is not evaluated at compile-time.  */
> +#ifndef __SPU__
> +  foof (__builtin_cpowf (__builtin_nanf(""), 2.5F));
> +#endif
> +  foo (__builtin_cpow (__builtin_nan(""), 2.5));
> +  fool (__builtin_cpowl (__builtin_nanl(""), 2.5L));
> +#ifndef __SPU__
> +  foof (__builtin_cpowf (2.5F, __builtin_nanf("")));
> +#endif
> +  foo (__builtin_cpow (2.5, __builtin_nan("")));
> +  fool (__builtin_cpowl (2.5L, __builtin_nanl("")));
> +
> +  /* An argument of Inf/-Inf is not evaluated at compile-time.  */
> +#ifndef __SPU__
> +  foof (__builtin_cpowf (__builtin_inff(), 2.5F));
> +#endif
> +  foo (__builtin_cpow (__builtin_inf(), 2.5));
> +  fool (__builtin_cpowl (__builtin_infl(), 2.5L));
> +#ifndef __SPU__
> +  foof (__builtin_cpowf (-__builtin_inff(), 2.5F));
> +#endif
> +  foo (__builtin_cpow (-__builtin_inf(), 2.5));
> +  fool (__builtin_cpowl (-__builtin_infl(), 2.5L));
> +#ifndef __SPU__
> +  foof (__builtin_cpowf (2.5F, __builtin_inff()));
> +#endif
> +  foo (__builtin_cpow (2.5, __builtin_inf()));
> +  fool (__builtin_cpowl (2.5L, __builtin_infl()));
> +#ifndef __SPU__
> +  foof (__builtin_cpowf (2.5F, -__builtin_inff()));
> +#endif
> +  foo (__builtin_cpow (2.5, -__builtin_inf()));
> +  fool (__builtin_cpowl (2.5L, -__builtin_infl()));
> +
> +  /* Check for Inv/NaN return values.  */
> +  TESTIT2 (cpow, -0.0, -4.5); /* Returns Inf */
> +  TESTIT2 (cpow, 0.0, -4.5); /* Returns Inf */
> +
> +  /* Check for overflow/underflow.  */
> +  foof (__builtin_cpowf (__FLT_MAX__, 3.5F));
> +  foof (__builtin_cpowf (__FLT_MAX__ * 1.FI, 3.5F));
> +  foo (__builtin_cpow (__DBL_MAX__, 3.5));
> +  foo (__builtin_cpow (__DBL_MAX__ * 1.I, 3.5));
> +  fool (__builtin_cpowl (__LDBL_MAX__, 3.5L));
> +  fool (__builtin_cpowl (__LDBL_MAX__ * 1.LI, 3.5L));
> +  TESTIT2 (cpow, 2.0, 0x1p50);
> +  TESTIT2 (cpow, 2.0, 0x1p28);
> +  TESTIT2 (cpow, 2.0, 0x1p24);
> +  foof (__builtin_cpowf (__FLT_MAX__, -3.5F));
> +  foof (__builtin_cpowf (__FLT_MAX__ * 1.FI, -3.5F));
> +  foo (__builtin_cpow (__DBL_MAX__, -3.5));
> +  foo (__builtin_cpow (__DBL_MAX__ * 1.I, -3.5));
> +  fool (__builtin_cpowl (__LDBL_MAX__, -3.5L));
> +  fool (__builtin_cpowl (__LDBL_MAX__ * 1.LI, -3.5L));
> +  TESTIT2 (cpow, 2.0, -0x1p50);
> +  TESTIT2 (cpow, 2.0, -0x1p28);
> +  TESTIT2 (cpow, 2.0, -0x1p24);
> +
>  }
>
> -/* { dg-final { scan-tree-dump-times "csqrtf" 3 "original" } } */
> +/* { dg-final { scan-tree-dump-times "csqrtf" 3 "original" { target { ! { spu*-*-* } } } } } */
> +/* { dg-final { scan-tree-dump-times "csqrtf" 0 "original" { target { spu*-*-* } } } } */
>  /* { dg-final { scan-tree-dump-times "csqrt " 3 "original" } } */
>  /* { dg-final { scan-tree-dump-times "csqrtl" 3 "original" } } */
> +/* { dg-final { scan-tree-dump-times "cexpf" 2 "original" } } */
> +/* { dg-final { scan-tree-dump-times "cexp " 2 "original" } } */
> +/* { dg-final { scan-tree-dump-times "cexpl" 2 "original" } } */
> +/* { dg-final { scan-tree-dump-times "cpowf" 18 "original" { target { ! { spu*-*-* } } } } } */
> +/* { dg-final { scan-tree-dump-times "cpowf" 12 "original" { target { spu*-*-* } } } } */
> +/* { dg-final { scan-tree-dump-times "cpow " 18 "original" } } */
> +/* { dg-final { scan-tree-dump-times "cpowl" 18 "original" } } */
>  /* { dg-final { cleanup-tree-dump "original" } } */
> diff -rup orig/egcc-SVN20090714/gcc/testsuite/gcc.dg/torture/builtin-math-6.c egcc-SVN20090714/gcc/testsuite/gcc.dg/torture/builtin-math-6.c
> --- orig/egcc-SVN20090714/gcc/testsuite/gcc.dg/torture/builtin-math-6.c 2009-06-16 06:32:59.000000000 +0200
> +++ egcc-SVN20090714/gcc/testsuite/gcc.dg/torture/builtin-math-6.c      2009-07-14 18:09:05.000000000 +0200
> @@ -6,11 +6,13 @@
>    Origin: Kaveh R. Ghazi,  January 28, 2009.  */
>
>  /* { dg-do link } */
> -/* { dg-require-effective-target mpc } */
> +/* { dg-require-effective-target mpc_pow } */
>
>  /* All references to link_error should go away at compile-time.  */
>  extern void link_error(int);
>
> +#define CONJ(X) __builtin_conjf(X)
> +
>  /* Return TRUE if the signs of floating point values X and Y are not
>    equal.  This is important when comparing signed zeros.  */
>  #define CKSGN_F(X,Y) \
> @@ -42,6 +44,59 @@ extern void link_error(int);
>       link_error(__LINE__); \
>   } while (0)
>
> +/* For complex numbers, call the TESTIT_COMPLEX macro for all
> +   combinations of neg and conj.  */
> +#define TESTIT_COMPLEX_ALLNEG(FUNC, ARG, RES1, RES2, RES3, RES4) do { \
> +  TESTIT_COMPLEX(FUNC, (_Complex float)(ARG), RES1); \
> +  TESTIT_COMPLEX(FUNC, -CONJ(ARG), RES2); \
> +  TESTIT_COMPLEX(FUNC, CONJ(ARG), RES3); \
> +  TESTIT_COMPLEX(FUNC, -(_Complex float)(ARG), RES4); \
> +} while (0)
> +
> +/* For complex numbers, call the TESTIT_COMPLEX_R macro for all
> +   combinations of neg and conj.  */
> +#define TESTIT_COMPLEX_R_ALLNEG(FUNC, ARG, RES1, RES2, RES3, RES4) do { \
> +  TESTIT_COMPLEX_R(FUNC, (_Complex float)(ARG), RES1); \
> +  TESTIT_COMPLEX_R(FUNC, -CONJ(ARG), RES2); \
> +  TESTIT_COMPLEX_R(FUNC, CONJ(ARG), RES3); \
> +  TESTIT_COMPLEX_R(FUNC, -(_Complex float)(ARG), RES4); \
> +} while (0)
> +
> +/* For complex numbers, test that FUNC(ARG0, ARG1) == (RES).  */
> +#define TESTIT_COMPLEX2(FUNC, ARG0, ARG1, RES) do { \
> +  if (__builtin_##FUNC##f(ARG0, ARG1) != (RES) \
> +    || COMPLEX_CKSGN_F(__builtin_##FUNC##f(ARG0, ARG1), (RES))) \
> +      link_error(__LINE__); \
> +  if (__builtin_##FUNC(ARG0, ARG1) != (RES) \
> +    || COMPLEX_CKSGN(__builtin_##FUNC(ARG0, ARG1), (RES))) \
> +      link_error(__LINE__); \
> +  if (__builtin_##FUNC##l(ARG0, ARG1) != (RES) \
> +    || COMPLEX_CKSGN_L(__builtin_##FUNC##l(ARG0, ARG1), (RES))) \
> +      link_error(__LINE__); \
> +  } while (0)
> +
> +/* For complex numbers, call the TESTIT_COMPLEX2 macro for all
> +   combinations of neg and conj.  */
> +#define TESTIT_COMPLEX2_ALLNEG(FUNC, ARG0, ARG1, RES1, RES2, RES3, RES4, RES5,\
> + RES6, RES7, RES8, RES9, RES10, RES11, RES12, RES13, RES14, RES15, RES16) do{ \
> +  TESTIT_COMPLEX2(FUNC, (_Complex float)(ARG0),(_Complex float)(ARG1), RES1);\
> +  TESTIT_COMPLEX2(FUNC, (_Complex float)(ARG0),CONJ(ARG1), RES2); \
> +  TESTIT_COMPLEX2(FUNC, (_Complex float)(ARG0),-(_Complex float)(ARG1), RES3); \
> +  TESTIT_COMPLEX2(FUNC, (_Complex float)(ARG0),-CONJ(ARG1), RES4); \
> +  TESTIT_COMPLEX2(FUNC, -(_Complex float)(ARG0),(_Complex float)(ARG1), RES5); \
> +  TESTIT_COMPLEX2(FUNC, -(_Complex float)(ARG0),CONJ(ARG1), RES6); \
> +  TESTIT_COMPLEX2(FUNC, -(_Complex float)(ARG0),-(_Complex float)(ARG1), RES7); \
> +  TESTIT_COMPLEX2(FUNC, -(_Complex float)(ARG0),-CONJ(ARG1), RES8); \
> +  TESTIT_COMPLEX2(FUNC, CONJ(ARG0),(_Complex float)(ARG1), RES9); \
> +  TESTIT_COMPLEX2(FUNC, CONJ(ARG0),CONJ(ARG1), RES10); \
> +  TESTIT_COMPLEX2(FUNC, CONJ(ARG0),-(_Complex float)(ARG1), RES11); \
> +  TESTIT_COMPLEX2(FUNC, CONJ(ARG0),-CONJ(ARG1), RES12); \
> +  TESTIT_COMPLEX2(FUNC, -CONJ(ARG0),(_Complex float)(ARG1), RES13); \
> +  TESTIT_COMPLEX2(FUNC, -CONJ(ARG0),CONJ(ARG1), RES14); \
> +  TESTIT_COMPLEX2(FUNC, -CONJ(ARG0),-(_Complex float)(ARG1), RES15); \
> +  TESTIT_COMPLEX2(FUNC, -CONJ(ARG0),-CONJ(ARG1), RES16); \
> +} while (0)
> +
>  /* Return TRUE if X differs from EXPECTED by more than 1%.  If
>    EXPECTED is zero, then any difference may return TRUE.  We don't
>    worry about signed zeros.  */
> @@ -81,87 +136,126 @@ extern void link_error(int);
>     link_error(__LINE__); \
>   } while (0)
>
> +/* Range test, for complex numbers check that FUNC(ARG0, ARG1) is
> +   within 1% of RES.  This is NOT a test for accuracy to the last-bit,
> +   we're merely checking that we get relatively sane results.
> +   I.e. the GCC builtin is hooked up to the correct MPC function call.
> +   We first check the magnitude and then the sign.  */
> +#define TESTIT_COMPLEX_R2(FUNC, ARG0, ARG1, RES) do { \
> +  if (COMPLEX_DIFF1PCT_F (__builtin_##FUNC##f(ARG0, ARG1), (RES)) \
> +      || COMPLEX_CKSGN_F (__builtin_##FUNC##f(ARG0, ARG1), (RES))) \
> +    link_error(__LINE__); \
> +  if (COMPLEX_DIFF1PCT (__builtin_##FUNC(ARG0, ARG1), (RES)) \
> +      || COMPLEX_CKSGN (__builtin_##FUNC(ARG0, ARG1), (RES))) \
> +    link_error(__LINE__); \
> +  if (COMPLEX_DIFF1PCT_L (__builtin_##FUNC##l(ARG0, ARG1), (RES)) \
> +      || COMPLEX_CKSGN_L (__builtin_##FUNC##l(ARG0, ARG1), (RES))) \
> +    link_error(__LINE__); \
> +  } while (0)
> +
> +/* For complex numbers, call the TESTIT_COMPLEX_R2 macro for all
> +   combinations of neg and conj.  */
> +#define TESTIT_COMPLEX_R2_ALLNEG(FUNC, ARG0, ARG1, RES1, RES2, RES3, RES4, RES5,\
> + RES6, RES7, RES8, RES9, RES10, RES11, RES12, RES13, RES14, RES15, RES16) do{ \
> +  TESTIT_COMPLEX_R2(FUNC, (_Complex float)(ARG0),(_Complex float)(ARG1), RES1);\
> +  TESTIT_COMPLEX_R2(FUNC, (_Complex float)(ARG0),CONJ(ARG1), RES2); \
> +  TESTIT_COMPLEX_R2(FUNC, (_Complex float)(ARG0),-(_Complex float)(ARG1), RES3); \
> +  TESTIT_COMPLEX_R2(FUNC, (_Complex float)(ARG0),-CONJ(ARG1), RES4); \
> +  TESTIT_COMPLEX_R2(FUNC, -(_Complex float)(ARG0),(_Complex float)(ARG1), RES5); \
> +  TESTIT_COMPLEX_R2(FUNC, -(_Complex float)(ARG0),CONJ(ARG1), RES6); \
> +  TESTIT_COMPLEX_R2(FUNC, -(_Complex float)(ARG0),-(_Complex float)(ARG1), RES7); \
> +  TESTIT_COMPLEX_R2(FUNC, -(_Complex float)(ARG0),-CONJ(ARG1), RES8); \
> +  TESTIT_COMPLEX_R2(FUNC, CONJ(ARG0),(_Complex float)(ARG1), RES9); \
> +  TESTIT_COMPLEX_R2(FUNC, CONJ(ARG0),CONJ(ARG1), RES10); \
> +  TESTIT_COMPLEX_R2(FUNC, CONJ(ARG0),-(_Complex float)(ARG1), RES11); \
> +  TESTIT_COMPLEX_R2(FUNC, CONJ(ARG0),-CONJ(ARG1), RES12); \
> +  TESTIT_COMPLEX_R2(FUNC, -CONJ(ARG0),(_Complex float)(ARG1), RES13); \
> +  TESTIT_COMPLEX_R2(FUNC, -CONJ(ARG0),CONJ(ARG1), RES14); \
> +  TESTIT_COMPLEX_R2(FUNC, -CONJ(ARG0),-(_Complex float)(ARG1), RES15); \
> +  TESTIT_COMPLEX_R2(FUNC, -CONJ(ARG0),-CONJ(ARG1), RES16); \
> +} while (0)
> +
>  int main (void)
>  {
> -  TESTIT_COMPLEX (csin, 0.0F, 0.0F);
> -  TESTIT_COMPLEX (csin, -0.0F, -0.0F);
> -  TESTIT_COMPLEX (csin, __builtin_conjf(0.0F), __builtin_conjf(0.0F));
> -  TESTIT_COMPLEX (csin, __builtin_conjf(-0.0F), __builtin_conjf(-0.0F));
> -
> -  TESTIT_COMPLEX_R (csin, 3.45678F + 2.34567FI, -1.633059F - 4.917448FI);
> -  TESTIT_COMPLEX_R (csin, 3.45678F - 2.34567FI, -1.633059F + 4.917448FI);
> -  TESTIT_COMPLEX_R (csin, -3.45678F + 2.34567FI, 1.633059F - 4.917448FI);
> -  TESTIT_COMPLEX_R (csin, -3.45678F - 2.34567FI, 1.633059F + 4.917448FI);
> -
> -  TESTIT_COMPLEX (ccos, 0.0F, __builtin_conjf(1.0F));
> -  TESTIT_COMPLEX (ccos, -0.0F, 1.0F);
> -  TESTIT_COMPLEX (ccos, __builtin_conjf(0.0F), 1.0F);
> -  TESTIT_COMPLEX (ccos, __builtin_conjf(-0.0F), __builtin_conjf(1.0F));
> -
> -  TESTIT_COMPLEX_R (ccos, 3.45678F + 2.34567FI, -5.008512F + 1.603367FI);
> -  TESTIT_COMPLEX_R (ccos, 3.45678F - 2.34567FI, -5.008512F - 1.603367FI);
> -  TESTIT_COMPLEX_R (ccos, -3.45678F + 2.34567FI, -5.008512F - 1.603367FI);
> -  TESTIT_COMPLEX_R (ccos, -3.45678F - 2.34567FI, -5.008512F + 1.603367FI);
> -
> -  TESTIT_COMPLEX (ctan, 0.0F, 0.0F);
> -  TESTIT_COMPLEX (ctan, -0.0F, -0.0F);
> -  TESTIT_COMPLEX (ctan, __builtin_conjf(0.0F), __builtin_conjf(0.0F));
> -  TESTIT_COMPLEX (ctan, __builtin_conjf(-0.0F), __builtin_conjf(-0.0F));
> -
> -  TESTIT_COMPLEX_R (ctan, 3.45678F + 2.34567FI, 0.010657F + 0.985230FI);
> -  TESTIT_COMPLEX_R (ctan, 3.45678F - 2.34567FI, 0.010657F - 0.985230FI);
> -  TESTIT_COMPLEX_R (ctan, -3.45678F + 2.34567FI, -0.010657F + 0.985230FI);
> -  TESTIT_COMPLEX_R (ctan, -3.45678F - 2.34567FI, -0.010657F - 0.985230FI);
> -
> -  TESTIT_COMPLEX (csinh, 0.0F, 0.0F);
> -  TESTIT_COMPLEX (csinh, -0.0F, -0.0F);
> -  TESTIT_COMPLEX (csinh, __builtin_conjf(0.0F), __builtin_conjf(0.0F));
> -  TESTIT_COMPLEX (csinh, __builtin_conjf(-0.0F), __builtin_conjf(-0.0F));
> -
> -  TESTIT_COMPLEX_R (csinh, 3.45678F + 2.34567FI, -11.083178F + 11.341487FI);
> -  TESTIT_COMPLEX_R (csinh, 3.45678F - 2.34567FI, -11.083178F - 11.341487FI);
> -  TESTIT_COMPLEX_R (csinh, -3.45678F + 2.34567FI, 11.083178F + 11.341487FI);
> -  TESTIT_COMPLEX_R (csinh, -3.45678F - 2.34567FI, 11.083178F - 11.341487FI);
> -
> -  TESTIT_COMPLEX (ccosh, 0.0F, 1.0F);
> -  TESTIT_COMPLEX (ccosh, -0.0F, __builtin_conjf(1.0F));
> -  TESTIT_COMPLEX (ccosh, __builtin_conjf(0.0F), __builtin_conjf(1.0F));
> -  TESTIT_COMPLEX (ccosh, __builtin_conjf(-0.0F), 1.0F);
> -
> -  TESTIT_COMPLEX_R (ccosh, 3.45678F + 2.34567FI, -11.105238F + 11.318958FI);
> -  TESTIT_COMPLEX_R (ccosh, 3.45678F - 2.34567FI, -11.105238F - 11.318958FI);
> -  TESTIT_COMPLEX_R (ccosh, -3.45678F + 2.34567FI, -11.105238F - 11.318958FI);
> -  TESTIT_COMPLEX_R (ccosh, -3.45678F - 2.34567FI, -11.105238F + 11.318958FI);
> -
> -  TESTIT_COMPLEX (ctanh, 0.0F, 0.0F);
> -  TESTIT_COMPLEX (ctanh, -0.0F, -0.0F);
> -  TESTIT_COMPLEX (ctanh, __builtin_conjf(0.0F), __builtin_conjf(0.0F));
> -  TESTIT_COMPLEX (ctanh, __builtin_conjf(-0.0F), __builtin_conjf(-0.0F));
> -
> -  TESTIT_COMPLEX_R (ctanh, 3.45678F + 2.34567FI, 1.000040F - 0.001988FI);
> -  TESTIT_COMPLEX_R (ctanh, 3.45678F - 2.34567FI, 1.000040F + 0.001988FI);
> -  TESTIT_COMPLEX_R (ctanh, -3.45678F + 2.34567FI, -1.000040F - 0.001988FI);
> -  TESTIT_COMPLEX_R (ctanh, -3.45678F - 2.34567FI, -1.000040F + 0.001988FI);
> -
> -  TESTIT_COMPLEX (clog, 1.0F, 0.0F);
> -  TESTIT_COMPLEX_R (clog, -1.0F, 3.141593FI);
> -  TESTIT_COMPLEX (clog, __builtin_conjf(1.0F), __builtin_conjf(0.0F)); /* Fails with mpc-0.6.  */
> -  TESTIT_COMPLEX_R (clog, __builtin_conjf(-1.0F), __builtin_conjf(3.141593FI)); /* Fails with mpc-0.6.  */
> -
> -  TESTIT_COMPLEX_R (clog, 3.45678F + 2.34567FI, 1.429713F + 0.596199FI);
> -  TESTIT_COMPLEX_R (clog, 3.45678F - 2.34567FI, 1.429713F - 0.596199FI);
> -  TESTIT_COMPLEX_R (clog, -3.45678F + 2.34567FI, 1.429713F + 2.545394FI);
> -  TESTIT_COMPLEX_R (clog, -3.45678F - 2.34567FI, 1.429713F - 2.545394FI);
> -
> -  TESTIT_COMPLEX (csqrt, 0.0F, 0.0F);
> -  TESTIT_COMPLEX (csqrt, -0.0F, 0.0F);
> -  TESTIT_COMPLEX (csqrt, __builtin_conjf(0.0F), __builtin_conjf(0.0F));
> -  TESTIT_COMPLEX (csqrt, __builtin_conjf(-0.0F), __builtin_conjf(0.0F));
> -
> -  TESTIT_COMPLEX_R (csqrt, 3.45678F + 2.34567FI, 1.953750F + 0.600299FI);
> -  TESTIT_COMPLEX_R (csqrt, 3.45678F - 2.34567FI, 1.953750F - 0.600299FI);
> -  TESTIT_COMPLEX_R (csqrt, -3.45678F + 2.34567FI, 0.600299F + 1.953750FI);
> -  TESTIT_COMPLEX_R (csqrt, -3.45678F - 2.34567FI, 0.600299F - 1.953750FI);
> +  TESTIT_COMPLEX_ALLNEG (csin, 0,
> +                        0, -0.F,
> +                        CONJ(0), CONJ(-0.F));
> +  TESTIT_COMPLEX_R_ALLNEG (csin, 3.45678F + 2.34567FI,
> +                          -1.633059F - 4.917448FI, 1.633059F - 4.917448FI,
> +                          -1.633059F + 4.917448FI, 1.633059F + 4.917448FI);
> +
> +  TESTIT_COMPLEX_ALLNEG (ccos, 0,
> +                        CONJ(1), 1, 1, CONJ(1));
> +  TESTIT_COMPLEX_R_ALLNEG (ccos, 3.45678F + 2.34567FI,
> +                          -5.008512F + 1.603367FI, -5.008512F - 1.603367FI,
> +                          -5.008512F - 1.603367FI, -5.008512F + 1.603367FI);
> +
> +  TESTIT_COMPLEX_ALLNEG (ctan, 0,
> +                        0, -0.F, CONJ(0), CONJ(-0.F));
> +  TESTIT_COMPLEX_R_ALLNEG (ctan, 3.45678F + 2.34567FI,
> +                          0.010657F + 0.985230FI, -0.010657F + 0.985230FI,
> +                          0.010657F - 0.985230FI, -0.010657F - 0.985230FI);
> +
> +  TESTIT_COMPLEX_ALLNEG (csinh, 0,
> +                        0, -0.F, CONJ(0), CONJ(-0.F));
> +  TESTIT_COMPLEX_R_ALLNEG (csinh, 3.45678F + 2.34567FI,
> +                          -11.083178F + 11.341487FI, 11.083178F +11.341487FI,
> +                          -11.083178F - 11.341487FI, 11.083178F -11.341487FI);
> +
> +  TESTIT_COMPLEX_ALLNEG (ccosh, 0,
> +                        1, CONJ(1), CONJ(1), 1);
> +  TESTIT_COMPLEX_R_ALLNEG (ccosh, 3.45678F + 2.34567FI,
> +                          -11.105238F + 11.318958FI,-11.105238F -11.318958FI,
> +                          -11.105238F - 11.318958FI,-11.105238F +11.318958FI);
> +
> +  TESTIT_COMPLEX_ALLNEG (ctanh, 0,
> +                        0, -0.F, CONJ(0), CONJ(-0.F));
> +  TESTIT_COMPLEX_R_ALLNEG (ctanh, 3.45678F + 2.34567FI,
> +                          1.000040F - 0.001988FI, -1.000040F - 0.001988FI,
> +                          1.000040F + 0.001988FI, -1.000040F + 0.001988FI);
> +
> +  TESTIT_COMPLEX (clog, 1, 0);
> +  TESTIT_COMPLEX_R (clog, -1, 3.141593FI);
> +  TESTIT_COMPLEX (clog, CONJ(1), CONJ(0)); /* Fails with mpc-0.6.  */
> +  TESTIT_COMPLEX_R (clog, CONJ(-1), CONJ(3.141593FI)); /* Fails with mpc-0.6.  */
> +  TESTIT_COMPLEX_R_ALLNEG (clog, 3.45678F + 2.34567FI,
> +                          1.429713F + 0.596199FI, 1.429713F + 2.545394FI,
> +                          1.429713F - 0.596199FI, 1.429713F - 2.545394FI);
> +
> +  TESTIT_COMPLEX_ALLNEG (csqrt, 0,
> +                        0, 0, CONJ(0), CONJ(0));
> +  TESTIT_COMPLEX_R_ALLNEG (csqrt, 3.45678F + 2.34567FI,
> +                          1.953750F + 0.600299FI, 0.600299F + 1.953750FI,
> +                          1.953750F - 0.600299FI, 0.600299F - 1.953750FI);
> +
> +  TESTIT_COMPLEX2_ALLNEG (cpow, 1, 0,
> +                         1, 1, CONJ(1), CONJ(1), 1, CONJ(1), 1, 1,
> +                         CONJ(1), CONJ(1), 1, 1, 1, 1, CONJ(1), 1);
> +  TESTIT_COMPLEX2_ALLNEG (cpow, 1.FI, 0,
> +                         1, 1, CONJ(1), 1, 1, CONJ(1), 1, 1,
> +                         1, CONJ(1), 1, 1, 1, 1, CONJ(1), 1);
> +  TESTIT_COMPLEX_R2_ALLNEG (cpow, 2, 3,
> +                           8, 8, CONJ(1/8.F), 1/8.F, CONJ(-8), -8, -1/8.F, -1/8.F,
> +                           8, CONJ(8), 1/8.F, 1/8.F, -8, -8, -1/8.F, CONJ(-1/8.F));
> +  TESTIT_COMPLEX_R2_ALLNEG (cpow, 3, 4,
> +                           81, 81, CONJ(1/81.F), 1/81.F, 81, 81, CONJ(1/81.F), 1/81.F,
> +                           81, CONJ(81), 1/81.F, 1/81.F, 81, CONJ(81), 1/81.F, 1/81.F);
> +  TESTIT_COMPLEX_R2_ALLNEG (cpow, 3, 5,
> +                           243, 243, CONJ(1/243.F), 1/243.F, CONJ(-243), -243, -1/243.F, -1/243.F,
> +                           243, CONJ(243), 1/243.F, 1/243.F, -243, -243, -1/243.F, CONJ(-1/243.F));
> +  TESTIT_COMPLEX_R2_ALLNEG (cpow, 4, 2,
> +                           16, 16, CONJ(1/16.F), 1/16.F, 16, 16, CONJ(1/16.F), 1/16.F,
> +                           16, CONJ(16), 1/16.F, 1/16.F, 16, CONJ(16), 1/16.F, 1/16.F);
> +  TESTIT_COMPLEX_R2_ALLNEG (cpow, 1.5, 3,
> +                           3.375F, 3.375F, CONJ(1/3.375F), 1/3.375F, CONJ(-3.375F), -3.375F, -1/3.375F, -1/3.375F,
> +                           3.375F, CONJ(3.375F), 1/3.375F, 1/3.375F, -3.375F, -3.375F, -1/3.375F, CONJ(-1/3.375F));
> +
> +  TESTIT_COMPLEX2 (cpow, 16, 0.25F, 2);
>
> +  TESTIT_COMPLEX_R2 (cpow, 3.45678F + 2.34567FI, 1.23456 + 4.56789FI, 0.212485F + 0.319304FI);
> +  TESTIT_COMPLEX_R2 (cpow, 3.45678F - 2.34567FI, 1.23456 + 4.56789FI, 78.576402F + -41.756208FI);
> +  TESTIT_COMPLEX_R2 (cpow, -1.23456F + 2.34567FI, 2.34567 - 1.23456FI, -110.629847F + -57.021655FI);
> +  TESTIT_COMPLEX_R2 (cpow, -1.23456F - 2.34567FI, 2.34567 - 1.23456FI, 0.752336F + 0.199095FI);
> +
>   return 0;
>  }
> diff -rup orig/egcc-SVN20090714/gcc/testsuite/lib/target-supports.exp egcc-SVN20090714/gcc/testsuite/lib/target-supports.exp
> --- orig/egcc-SVN20090714/gcc/testsuite/lib/target-supports.exp 2009-07-07 02:01:39.000000000 +0200
> +++ egcc-SVN20090714/gcc/testsuite/lib/target-supports.exp      2009-07-14 18:08:25.000000000 +0200
> @@ -2998,3 +2998,16 @@ proc check_effective_target_mpc { } {
>        }
>     }]
>  }
> +
> +# Return 1 if the MPC library with mpc_pow is integrated with GCC, 0 otherwise.
> +
> +proc check_effective_target_mpc_pow { } {
> +    return [check_no_compiler_messages mpc executable {
> +       extern void link_error(void);
> +       int main ()
> +       {
> +         if (__builtin_cpow(1,1) != 1)
> +           link_error();
> +       }
> +    }]
> +}
>



More information about the Gcc-patches mailing list