re PR middle-end/29335 (transcendental functions with constant arguments should be resolved at compile-time)
PR middle-end/29335 * builtins.c (do_mpfr_sincos): New. (fold_builtin_1): Use it to fold builtin sincos. testsuite: * gcc.dg/torture/builtin-math-3.c: Fix semicolons. (TESTIT_2P, TESTIT_2P_R): New macros. Test sincos. From-SVN: r118409
This commit is contained in:
parent
1d07712df0
commit
b68bcfff54
@ -1,3 +1,9 @@
|
||||
2006-11-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
PR middle-end/29335
|
||||
* builtins.c (do_mpfr_sincos): New.
|
||||
(fold_builtin_1): Use it to fold builtin sincos.
|
||||
|
||||
2006-11-01 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* config/darwin.h (CPP_SPEC): Handle -pthread, transforming
|
||||
|
@ -207,6 +207,7 @@ static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
|
||||
const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
|
||||
static tree do_mpfr_arg2 (tree, tree, tree,
|
||||
int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
|
||||
static tree do_mpfr_sincos (tree, tree, tree);
|
||||
|
||||
/* Return true if NODE should be considered for inline expansion regardless
|
||||
of the optimization level. This means whenever a function is invoked with
|
||||
@ -9184,6 +9185,12 @@ fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
|
||||
CASE_FLT_FN (BUILT_IN_TAN):
|
||||
return fold_builtin_tan (arglist, type);
|
||||
|
||||
CASE_FLT_FN (BUILT_IN_SINCOS):
|
||||
if (validate_arglist (arglist, REAL_TYPE, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
|
||||
return do_mpfr_sincos (TREE_VALUE (arglist), TREE_VALUE (TREE_CHAIN (arglist)),
|
||||
TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))));
|
||||
break;
|
||||
|
||||
CASE_FLT_FN (BUILT_IN_SINH):
|
||||
if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
|
||||
return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sinh,
|
||||
@ -11594,3 +11601,58 @@ do_mpfr_arg2 (tree arg1, tree arg2, tree type,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
|
||||
the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
|
||||
The type is taken from the type of ARG and is used for setting the
|
||||
precision of the calculation and results. */
|
||||
|
||||
static tree
|
||||
do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
|
||||
{
|
||||
tree result = NULL_TREE;
|
||||
|
||||
STRIP_NOPS (arg);
|
||||
|
||||
if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
|
||||
{
|
||||
const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
|
||||
|
||||
if (!real_isnan (ra) && !real_isinf (ra))
|
||||
{
|
||||
tree const type = TREE_TYPE (arg);
|
||||
const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
|
||||
tree result_s, result_c;
|
||||
int inexact;
|
||||
mpfr_t m, ms, mc;
|
||||
|
||||
mpfr_inits2 (prec, m, ms, mc, NULL);
|
||||
mpfr_from_real (m, ra);
|
||||
mpfr_clear_flags();
|
||||
inexact = mpfr_sin_cos (ms, mc, m, GMP_RNDN);
|
||||
result_s = do_mpfr_ckconv (ms, type, inexact);
|
||||
result_c = do_mpfr_ckconv (mc, type, inexact);
|
||||
mpfr_clears (m, ms, mc, NULL);
|
||||
if (result_s && result_c)
|
||||
{
|
||||
/* Dereference the sin/cos pointer arguments. */
|
||||
arg_sinp = build_fold_indirect_ref (arg_sinp);
|
||||
arg_cosp = build_fold_indirect_ref (arg_cosp);
|
||||
/* Proceed if valid pointer type were passed in. */
|
||||
if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
|
||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
|
||||
{
|
||||
/* Set the values. */
|
||||
result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp, result_s);
|
||||
TREE_SIDE_EFFECTS (result_s) = 1;
|
||||
result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp, result_c);
|
||||
TREE_SIDE_EFFECTS (result_c) = 1;
|
||||
/* Combine the assignments into a compound expr. */
|
||||
result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
|
||||
result_s, result_c));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
2006-11-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* gcc.dg/torture/builtin-math-3.c: Fix semicolons.
|
||||
(TESTIT_2P, TESTIT_2P_R): New macros. Test sincos.
|
||||
|
||||
2006-11-01 Adam Nemet <anemet@caviumnetworks.com>
|
||||
|
||||
* gcc.dg/fold-mod-1.c: Match the leading 0x for the
|
||||
|
@ -21,7 +21,7 @@ extern void link_error(int);
|
||||
link_error(__LINE__); \
|
||||
if (__builtin_##FUNC##l(ARG##L) != RES##L) \
|
||||
link_error(__LINE__); \
|
||||
} while (0);
|
||||
} while (0)
|
||||
|
||||
/* Range test, check that (LOW) < FUNC(ARG) < (HI). */
|
||||
#define TESTIT_R(FUNC,ARG,LOW,HI) do { \
|
||||
@ -31,7 +31,7 @@ extern void link_error(int);
|
||||
link_error(__LINE__); \
|
||||
if (__builtin_##FUNC##l(ARG) <= (LOW) || __builtin_##FUNC##l(ARG) >= (HI)) \
|
||||
link_error(__LINE__); \
|
||||
} while (0);
|
||||
} while (0)
|
||||
|
||||
/* Test that FUNC(ARG1, ARG2) == (RES). */
|
||||
#define TESTIT2(FUNC,ARG1,ARG2,RES) do { \
|
||||
@ -41,7 +41,7 @@ extern void link_error(int);
|
||||
link_error(__LINE__); \
|
||||
if (__builtin_##FUNC##l(ARG1##L, ARG2##L) != RES##L) \
|
||||
link_error(__LINE__); \
|
||||
} while (0);
|
||||
} while (0)
|
||||
|
||||
/* Range test, check that (LOW) < FUNC(ARG1,ARG2) < (HI). */
|
||||
#define TESTIT2_R(FUNC,ARG1,ARG2,LOW,HI) do { \
|
||||
@ -54,10 +54,47 @@ extern void link_error(int);
|
||||
if (__builtin_##FUNC##l(ARG1, ARG2) <= (LOW) \
|
||||
|| __builtin_##FUNC##l(ARG1, ARG2) >= (HI)) \
|
||||
link_error(__LINE__); \
|
||||
} while (0);
|
||||
} while (0)
|
||||
|
||||
/* Test that for FUNC(ARG, &ARG_S, &ARG_C);
|
||||
assert (ARG_S == RES_S && ARG_C == RES_C);. */
|
||||
#define TESTIT_2P(FUNC,ARG,ARG_S,ARG_C,RES_S,RES_C) do { \
|
||||
__builtin_##FUNC##f(ARG##F, &ARG_S##f, &ARG_C##f); \
|
||||
if (ARG_S##f != (RES_S##F) || ARG_C##f != (RES_C##F)) \
|
||||
link_error(__LINE__); \
|
||||
__builtin_##FUNC(ARG, &ARG_S, &ARG_C); \
|
||||
if (ARG_S != (RES_S) || ARG_C != (RES_C)) \
|
||||
link_error(__LINE__); \
|
||||
__builtin_##FUNC##l(ARG##L, &ARG_S##l, &ARG_C##l); \
|
||||
if (ARG_S##l != (RES_S##L) || ARG_C##l != (RES_C##L)) \
|
||||
link_error(__LINE__); \
|
||||
} while (0)
|
||||
|
||||
/* Test that for FUNC(ARG, &ARG_S, &ARG_C);
|
||||
assert (LOW_S < ARG_S < HI_S && LOW_C < ARG_C < HI_C);. */
|
||||
#define TESTIT_2P_R(FUNC,ARG,ARG_S,ARG_C,LOW_S,HI_S,LOW_C,HI_C) do { \
|
||||
__builtin_##FUNC##f(ARG##F, &ARG_S##f, &ARG_C##f); \
|
||||
if (ARG_S##f <= (LOW_S##F) || ARG_S##f >= (HI_S##F) \
|
||||
|| ARG_C##f <= (LOW_C##F) || ARG_C##f >= (HI_C##F)) \
|
||||
link_error(__LINE__); \
|
||||
__builtin_##FUNC(ARG, &ARG_S, &ARG_C); \
|
||||
if (ARG_S <= (LOW_S) || ARG_S >= (HI_S) \
|
||||
|| ARG_C <= (LOW_C) || ARG_C >= (HI_C)) \
|
||||
link_error(__LINE__); \
|
||||
__builtin_##FUNC##l(ARG##L, &ARG_S##l, &ARG_C##l); \
|
||||
if (ARG_S##l <= (LOW_S##L) || ARG_S##l >= (HI_S##L) \
|
||||
|| ARG_C##l <= (LOW_C##L) || ARG_C##l >= (HI_C##L)) \
|
||||
link_error(__LINE__); \
|
||||
} while (0)
|
||||
|
||||
int main (void)
|
||||
{
|
||||
#ifdef __OPTIMIZE__
|
||||
float sf, cf;
|
||||
double s, c;
|
||||
long double sl, cl;
|
||||
#endif
|
||||
|
||||
TESTIT_R (asin, -1.0, -3.15/2.0, -3.14/2.0); /* asin(-1) == -pi/2 */
|
||||
TESTIT (asin, 0.0, 0.0); /* asin(0) == 0 */
|
||||
TESTIT (asin, -0.0, -0.0); /* asin(-0) == -0 */
|
||||
@ -101,6 +138,15 @@ int main (void)
|
||||
TESTIT (tan, -0.0, -0.0); /* tan(-0) == -0 */
|
||||
TESTIT_R (tan, 1.0, 1.55, 1.56); /* tan(1) == 1.557... */
|
||||
|
||||
#ifdef __OPTIMIZE__
|
||||
/* These tests rely on propagating the variables s and c, which
|
||||
happens only when optimization is turned on. */
|
||||
TESTIT_2P_R (sincos, -1.0, s, c, -0.85, -0.84, 0.54, 0.55); /* (s==-0.841..., c==0.5403...) */
|
||||
TESTIT_2P (sincos, 0.0, s, c, 0.0, 1.0); /* (s==0, c==1) */
|
||||
TESTIT_2P (sincos, -0.0, s, c, -0.0, 1.0); /* (s==-0, c==1) */
|
||||
TESTIT_2P_R (sincos, 1.0, s, c, 0.84, 0.85, 0.54, 0.55); /* (s==0.841..., c==0.5403...) */
|
||||
#endif
|
||||
|
||||
TESTIT_R (sinh, -1.0, -1.18, -1.17); /* sinh(-1) == -1.175... */
|
||||
TESTIT (sinh, 0.0, 0.0); /* sinh(0) == 0 */
|
||||
TESTIT (sinh, -0.0, -0.0); /* sinh(-0) == -0 */
|
||||
@ -207,16 +253,16 @@ int main (void)
|
||||
TESTIT2 (hypot, -3.0, -4.0, 5.0); /* hypot(-3,-4) == 5 */
|
||||
TESTIT2_R (hypot, 4.0, 5.0, 6.40, 6.41); /* hypot(4,5) == 6.403... */
|
||||
|
||||
TESTIT2 (atan2, 0.0, 0.0, 0.0) /* atan2(0,0) == 0 */
|
||||
TESTIT2 (atan2, -0.0, 0.0, -0.0) /* atan2(-0,0) == -0 */
|
||||
TESTIT2_R (atan2, 0.0, -0.0, 3.14, 3.15) /* atan2(0,-0) == pi */
|
||||
TESTIT2_R (atan2, -0.0, -0.0, -3.15, -3.14) /* atan2(-0,-0) == -pi */
|
||||
TESTIT2_R (atan2, 0.0, -1.0, 3.14, 3.15) /* atan2(0,-1) == pi */
|
||||
TESTIT2_R (atan2, -0.0, -1.0, -3.15, -3.14) /* atan2(-0,-1) == -pi */
|
||||
TESTIT2 (atan2, 0.0, 1.0, 0.0) /* atan2(0,1) == 0 */
|
||||
TESTIT2 (atan2, -0.0, 1.0, -0.0) /* atan2(-0,1) == -0 */
|
||||
TESTIT2_R (atan2, -1.0, 0.0, -1.58, -1.57) /* atan2(-1,0) == -pi/2 */
|
||||
TESTIT2_R (atan2, 1.0, 0.0, 1.57, 1.58) /* atan2(1,0) == pi/2 */
|
||||
TESTIT2 (atan2, 0.0, 0.0, 0.0); /* atan2(0,0) == 0 */
|
||||
TESTIT2 (atan2, -0.0, 0.0, -0.0); /* atan2(-0,0) == -0 */
|
||||
TESTIT2_R (atan2, 0.0, -0.0, 3.14, 3.15); /* atan2(0,-0) == pi */
|
||||
TESTIT2_R (atan2, -0.0, -0.0, -3.15, -3.14); /* atan2(-0,-0) == -pi */
|
||||
TESTIT2_R (atan2, 0.0, -1.0, 3.14, 3.15); /* atan2(0,-1) == pi */
|
||||
TESTIT2_R (atan2, -0.0, -1.0, -3.15, -3.14); /* atan2(-0,-1) == -pi */
|
||||
TESTIT2 (atan2, 0.0, 1.0, 0.0); /* atan2(0,1) == 0 */
|
||||
TESTIT2 (atan2, -0.0, 1.0, -0.0); /* atan2(-0,1) == -0 */
|
||||
TESTIT2_R (atan2, -1.0, 0.0, -1.58, -1.57); /* atan2(-1,0) == -pi/2 */
|
||||
TESTIT2_R (atan2, 1.0, 0.0, 1.57, 1.58); /* atan2(1,0) == pi/2 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user