Kaveh R. GHAZI - [PATCH]: Add folding of builtin frexp (original) (raw)
This is the mail archive of the gcc-patches@gcc.gnu.orgmailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
- From: "Kaveh R. GHAZI"
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 22 Feb 2007 10:22:28 -0500 (EST)
- Subject: [PATCH]: Add folding of builtin frexp
This patch folds builtin frexp where thet first argument is constant.
Tested on sparc-sun-solaris2.10, no regressions.
Okay for mainline?
Thanks,
--Kaveh
2007-02-21 Kaveh R. Ghazi ghazi@caip.rutgers.edu
* builtins.c (fold_builtin_frexp): New.
(fold_builtin_2): Use it.
testsuite: * gcc.dg/torture/builtin-frexp-1.c: New test.
diff -rup orig/egcc-SVN20070220/gcc/builtins.c egcc-SVN20070220/gcc/builtins.c --- orig/egcc-SVN20070220/gcc/builtins.c 2007-02-20 20:02:30.000000000 -0500 +++ egcc-SVN20070220/gcc/builtins.c 2007-02-21 21:50:19.870945237 -0500 @@ -9017,6 +9017,63 @@ fold_builtin_carg (tree arg, tree type) return NULL_TREE; }
+/* Fold a call to builtin frexp, we can assume the base is 2. */ + +static tree +fold_builtin_frexp (tree arg0, tree arg1, tree rettype) +{
if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, POINTER_TYPE))
{
STRIP_NOPS (arg0);
if (TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0))
{
arg1 = build_fold_indirect_ref (arg1);
/* Proceed if a valid pointer type was passed in. */
if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
{
const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
tree frac, exp;
switch (value->cl)
{
case rvc_zero:
/* For +-0, return (*exp = 0, +-0). */
exp = integer_zero_node;
frac = arg0;
break;
case rvc_nan:
case rvc_inf:
/* For +-NaN or +-Inf, *exp is unspecified, return arg0. */
return omit_one_operand (rettype, arg0, arg1);
case rvc_normal:
{
/* Since the frexp function always expects base 2,
and in GCC normalized significands are already in
the range [0.5, 1.0), we have exactly what frexp
wants. */
REAL_VALUE_TYPE frac_rvt = *value;
SET_REAL_EXP (&frac_rvt, 0);
frac = build_real (rettype, frac_rvt);
exp = build_int_cst (NULL_TREE, REAL_EXP (value));
}
break;
default:
gcc_unreachable ();
}
/* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1, exp);
TREE_SIDE_EFFECTS (arg1) = 1;
return fold_build2 (COMPOUND_EXPR, rettype, arg1, frac);
}
}
}
return NULL_TREE; +}
/* Fold a call to builtin ldexp or scalbn/scalbln. If LDEXP is true then we can assume the base is two. If it's false, then we have to check the mode of the TYPE parameter in certain cases. */ @@ -9544,6 +9601,9 @@ fold_builtin_2 (tree fndecl, tree arg0, CASE_FLT_FN (BUILT_IN_SCALBLN): return fold_builtin_load_exponent (arg0, arg1, type, /ldexp=/false);
CASE_FLT_FN (BUILT_IN_FREXP):
return fold_builtin_frexp (arg0, arg1, type);
case BUILT_IN_BZERO: return fold_builtin_bzero (arg0, arg1, ignore);
diff -rup orig/egcc-SVN20070220/gcc/testsuite/gcc.dg/torture/builtin-frexp-1.c egcc-SVN20070220/gcc/testsuite/gcc.dg/torture/builtin-frexp-1.c --- orig/egcc-SVN20070220/gcc/testsuite/gcc.dg/torture/builtin-frexp-1.c 2007-02-21 21:58:09.481950576 -0500 +++ egcc-SVN20070220/gcc/testsuite/gcc.dg/torture/builtin-frexp-1.c 2007-02-21 21:49:46.565888014 -0500 @@ -0,0 +1,118 @@ +/* Copyright (C) 2007 Free Software Foundation. +
- Verify that built-in folding of frexp is correctly performed by the
- compiler.
- Origin: Kaveh R. Ghazi, February 21, 2007. */
- +/* { dg-do link } */
- +extern void link_error(int);
- +/* Return TRUE if the sign of X != sign of Y. This is important when
- comparing signed zeros. */ +#define CKSGN_F(X,Y) \
- (__builtin_copysignf(1.0F,(X)) != __builtin_copysignf(1.0F,(Y))) +#define CKSGN(X,Y) \
- (__builtin_copysign(1.0,(X)) != __builtin_copysign(1.0,(Y))) +#define CKSGN_L(X,Y) \
- (__builtin_copysignl(1.0L,(X)) != __builtin_copysignl(1.0L,(Y)))
- +/* We can only check the exponent when optimizing since we rely on
- other optimizations to propagate the value. TRUE means an error
- occurred. */ +#ifdef OPTIMIZE +#define CKEXP(X,Y) X != Y +#else +#define CKEXP(X,Y) 0 +#endif
- +/* Test that frexp(ARG,&i) == RES && i == EXP. Check the sign in
- case we get -0.0. */ +#define TESTIT_FREXP(ARG,RES,EXP) do { \
- int i = 123456; \
- if (__builtin_frexpf(ARG##f,&i) != RES##f \
|| CKEXP(i,EXP) \
|| CKSGN_F(__builtin_frexpf(ARG##f,&i),RES##f)) \
- link_error(LINE); \
- i = 123456; \
- if (__builtin_frexp(ARG,&i) != RES \
|| CKEXP(i,EXP) \
|| CKSGN(__builtin_frexp(ARG,&i),RES)) \
- link_error(LINE); \
- i = 123456; \
- if (__builtin_frexpl(ARG##l,&i) != RES##l \
|| CKEXP(i,EXP) \
|| CKSGN_L(__builtin_frexpl(ARG##l,&i),RES##l)) \
- link_error(LINE); \
- } while (0)
- +/* Test that FUNCRES(frexp(NEG FUNCARG(ARGARG),&i)) is false. Check
- the sign as well. Ensure side-effects are evaluated in i. */ +#define TESTIT_FREXP2(NEG,FUNCARG,ARGARG,FUNCRES) do { \
- int i=5; \
- if (!_builtin##FUNCRES##f(__builtin_frexpf(NEG _builtin##FUNCARG##f(ARGARG),&i)) \
|| CKSGN_F(__builtin_frexpf(NEG __builtin_##FUNCARG##f(ARGARG),(i++,&i)), NEG __builtin_##FUNCARG##f(ARGARG)) \
|| CKEXP(i,6)) \
- link_error(LINE); \
- if (!_builtin##FUNCRES(__builtin_frexp(NEG _builtin##FUNCARG(ARGARG),&i)) \
|| CKSGN(__builtin_frexp(NEG __builtin_##FUNCARG(ARGARG),(i++,&i)), NEG __builtin_##FUNCARG(ARGARG)) \
|| CKEXP(i,7)) \
- link_error(LINE); \
- if (!_builtin##FUNCRES##l(__builtin_frexpl(NEG _builtin##FUNCARG##l(ARGARG),&i)) \
|| CKSGN_L(__builtin_frexpl(NEG __builtin_##FUNCARG##l(ARGARG),(i++,&i)), NEG __builtin_##FUNCARG##l(ARGARG)) \
|| CKEXP(i,8)) \
- link_error(LINE); \
- } while (0)
- +void attribute ((noinline)) +foo(void) +{
- /* Test that frexp(ARG1,&i) -> ARG2 && i == ARG3. */
- TESTIT_FREXP (-0x1p40, -0.5, 41);
- TESTIT_FREXP (-0x1p30, -0.5, 31);
- TESTIT_FREXP (-0x1p20, -0.5, 21);
- TESTIT_FREXP (-0x1p10, -0.5, 11);
- TESTIT_FREXP (-0x1p5, -0.5, 6);
- TESTIT_FREXP (-100/3.0, -100/192.0, 6);
- TESTIT_FREXP (-1.5, -0.75, 1);
- TESTIT_FREXP (-1.0, -0.5, 1);
- TESTIT_FREXP (-1/3.0, -2/3.0, -1);
- TESTIT_FREXP (-1/9.0, -8/9.0, -3);
- TESTIT_FREXP (-0x1p-5, -0.5, -4);
- TESTIT_FREXP (-0x1p-10, -0.5, -9);
- TESTIT_FREXP (-0x1p-20, -0.5, -19);
- TESTIT_FREXP (-0x1p-30, -0.5, -29);
- TESTIT_FREXP (-0x1p-40, -0.5, -39);
- TESTIT_FREXP (-0.0, -0.0, 0);
- TESTIT_FREXP (0.0, 0.0, 0);
- TESTIT_FREXP (0x1p-40, 0.5, -39);
- TESTIT_FREXP (0x1p-30, 0.5, -29);
- TESTIT_FREXP (0x1p-20, 0.5, -19);
- TESTIT_FREXP (0x1p-10, 0.5, -9);
- TESTIT_FREXP (0x1p-5, 0.5, -4);
- TESTIT_FREXP (1/9.0, 8/9.0, -3);
- TESTIT_FREXP (1/3.0, 2/3.0, -1);
- TESTIT_FREXP (1.0, 0.5, 1);
- TESTIT_FREXP (1.5, 0.75, 1);
- TESTIT_FREXP (100/3.0, 100/192.0, 6);
- TESTIT_FREXP (0x1p5, 0.5, 6);
- TESTIT_FREXP (0x1p10, 0.5, 11);
- TESTIT_FREXP (0x1p20, 0.5, 21);
- TESTIT_FREXP (0x1p30, 0.5, 31);
- TESTIT_FREXP (0x1p40, 0.5, 41);
- /* Test for frexp(+-Inf,&i) -> +-Inf and frexp(+-NaN,&i) -> +-NaN.
Exponent is left unspecified, but we test for side-effects. */
- TESTIT_FREXP2 ( ,inf, , isinf);
- TESTIT_FREXP2 (- ,inf, , isinf);
- TESTIT_FREXP2 ( ,nan, "", isnan);
- TESTIT_FREXP2 (- ,nan, "", isnan); +}
- +int main() +{
- foo ();
- return 0; +}
- Follow-Ups:
- Re: [PATCH]: Add folding of builtin frexp
* From: Richard Guenther
- Re: [PATCH]: Add folding of builtin frexp
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |