diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ba80a32fd4b..3e6a75f2a15 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-07-16 Kaveh R. Ghazi + + * builtins.c (do_mpc_arg2): New. + (fold_builtin_2): Fold builtin cpow. + * real.h (HAVE_mpc_pow): New. + 2009-07-16 Bingfeng Mei * modulo-sched.c (sms_schedule): stage_count <= 1 as correct comparison diff --git a/gcc/builtins.c b/gcc/builtins.c index a5f41fc91f8..a94a37901a7 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -60,6 +60,9 @@ along with GCC; see the file COPYING3. If not see #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. */ @@ -10647,6 +10650,16 @@ fold_builtin_2 (tree fndecl, tree arg0, tree arg1, bool ignore) 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): @@ -13715,6 +13728,64 @@ do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t)) 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 --git a/gcc/real.h b/gcc/real.h index 0fc915cae5b..884a663c83f 100644 --- a/gcc/real.h +++ b/gcc/real.h @@ -26,6 +26,9 @@ #include #ifdef HAVE_mpc #include +# if MPC_VERSION >= MPC_VERSION_NUM(0,6,1) +# define HAVE_mpc_pow +# endif #endif #endif #include "machmode.h" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 558a0b9bb9c..989f5772fab 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2009-07-16 Kaveh R. Ghazi + + * 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. + 2009-07-16 Richard Henderson * g++.dg/opt/eh4.C: New test. diff --git a/gcc/testsuite/gcc.dg/torture/builtin-math-5.c b/gcc/testsuite/gcc.dg/torture/builtin-math-5.c index d266e50aff0..259164107d8 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-math-5.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-math-5.c @@ -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 --git a/gcc/testsuite/gcc.dg/torture/builtin-math-6.c b/gcc/testsuite/gcc.dg/torture/builtin-math-6.c index 7fd1f729e2c..2c9b02b63d1 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-math-6.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-math-6.c @@ -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_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_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_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 (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_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_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 (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 (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 (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 --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index d34f4156f7a..306e78fcbb1 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -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(); + } + }] +}