real.c (real_floor, real_ceil): Tweak to allow input and output arguments to overlap.
* real.c (real_floor, real_ceil): Tweak to allow input and output arguments to overlap. (real_round): New function to implement round(3m) semantics. * real.h (real_round): Prototype here. * builtins.c (fold_builtin_round): New function to constant fold round, roundf and roundl. (fold_builtin): Call fold_builtin_round for BUILT_IN_ROUND{,F,L}. * gcc.dg/builtins-29.c: New test case. From-SVN: r76428
This commit is contained in:
parent
69f2de23b2
commit
25348c94e7
4 changed files with 75 additions and 8 deletions
|
@ -1,3 +1,15 @@
|
|||
2004-01-23 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* real.c (real_floor, real_ceil): Tweak to allow input and output
|
||||
arguments to overlap.
|
||||
(real_round): New function to implement round(3m) semantics.
|
||||
* real.h (real_round): Prototype here.
|
||||
* builtins.c (fold_builtin_round): New function to constant fold
|
||||
round, roundf and roundl.
|
||||
(fold_builtin): Call fold_builtin_round for BUILT_IN_ROUND{,F,L}.
|
||||
|
||||
* gcc.dg/builtins-29.c: New test case.
|
||||
|
||||
2004-01-23 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
PR optimization/13819
|
||||
|
|
|
@ -156,6 +156,7 @@ static tree fold_builtin_cabs (tree, tree, tree);
|
|||
static tree fold_builtin_trunc (tree);
|
||||
static tree fold_builtin_floor (tree);
|
||||
static tree fold_builtin_ceil (tree);
|
||||
static tree fold_builtin_round (tree);
|
||||
static tree fold_builtin_bitop (tree);
|
||||
static tree fold_builtin_memcpy (tree);
|
||||
static tree fold_builtin_mempcpy (tree);
|
||||
|
@ -5923,6 +5924,38 @@ fold_builtin_ceil (tree exp)
|
|||
return fold_trunc_transparent_mathfn (exp);
|
||||
}
|
||||
|
||||
/* Fold function call to builtin round, roundf or roundl. Return
|
||||
NULL_TREE if no simplification can be made. */
|
||||
|
||||
static tree
|
||||
fold_builtin_round (tree exp)
|
||||
{
|
||||
tree arglist = TREE_OPERAND (exp, 1);
|
||||
tree arg;
|
||||
|
||||
if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
|
||||
return 0;
|
||||
|
||||
/* Optimize ceil of constant value. */
|
||||
arg = TREE_VALUE (arglist);
|
||||
if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
|
||||
{
|
||||
REAL_VALUE_TYPE x;
|
||||
|
||||
x = TREE_REAL_CST (arg);
|
||||
if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
|
||||
{
|
||||
tree type = TREE_TYPE (exp);
|
||||
REAL_VALUE_TYPE r;
|
||||
|
||||
real_round (&r, TYPE_MODE (type), &x);
|
||||
return build_real (type, r);
|
||||
}
|
||||
}
|
||||
|
||||
return fold_trunc_transparent_mathfn (exp);
|
||||
}
|
||||
|
||||
/* Fold function call to builtin ffs, clz, ctz, popcount and parity
|
||||
and their long and long long variants (i.e. ffsl and ffsll).
|
||||
Return NULL_TREE if no simplification can be made. */
|
||||
|
@ -6868,6 +6901,8 @@ fold_builtin (tree exp)
|
|||
case BUILT_IN_ROUND:
|
||||
case BUILT_IN_ROUNDF:
|
||||
case BUILT_IN_ROUNDL:
|
||||
return fold_builtin_round (exp);
|
||||
|
||||
case BUILT_IN_NEARBYINT:
|
||||
case BUILT_IN_NEARBYINTF:
|
||||
case BUILT_IN_NEARBYINTL:
|
||||
|
|
32
gcc/real.c
32
gcc/real.c
|
@ -4539,11 +4539,13 @@ void
|
|||
real_floor (REAL_VALUE_TYPE *r, enum machine_mode mode,
|
||||
const REAL_VALUE_TYPE *x)
|
||||
{
|
||||
do_fix_trunc (r, x);
|
||||
if (! real_identical (r, x) && r->sign)
|
||||
do_add (r, r, &dconstm1, 0);
|
||||
REAL_VALUE_TYPE t;
|
||||
|
||||
do_fix_trunc (&t, x);
|
||||
if (! real_identical (&t, x) && x->sign)
|
||||
do_add (&t, &t, &dconstm1, 0);
|
||||
if (mode != VOIDmode)
|
||||
real_convert (r, mode, r);
|
||||
real_convert (r, mode, &t);
|
||||
}
|
||||
|
||||
/* Round X to the smallest integer not less then argument, i.e. round
|
||||
|
@ -4553,9 +4555,25 @@ void
|
|||
real_ceil (REAL_VALUE_TYPE *r, enum machine_mode mode,
|
||||
const REAL_VALUE_TYPE *x)
|
||||
{
|
||||
do_fix_trunc (r, x);
|
||||
if (! real_identical (r, x) && ! r->sign)
|
||||
do_add (r, r, &dconst1, 0);
|
||||
REAL_VALUE_TYPE t;
|
||||
|
||||
do_fix_trunc (&t, x);
|
||||
if (! real_identical (&t, x) && ! x->sign)
|
||||
do_add (&t, &t, &dconst1, 0);
|
||||
if (mode != VOIDmode)
|
||||
real_convert (r, mode, &t);
|
||||
}
|
||||
|
||||
/* Round X to the nearest integer, but round halfway cases away from
|
||||
zero. */
|
||||
|
||||
void
|
||||
real_round (REAL_VALUE_TYPE *r, enum machine_mode mode,
|
||||
const REAL_VALUE_TYPE *x)
|
||||
{
|
||||
do_add (r, x, &dconsthalf, x->sign);
|
||||
do_fix_trunc (r, r);
|
||||
if (mode != VOIDmode)
|
||||
real_convert (r, mode, r);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Definitions of floating-point access for GNU compiler.
|
||||
Copyright (C) 1989, 1991, 1994, 1996, 1997, 1998, 1999,
|
||||
2000, 2002, 2003 Free Software Foundation, Inc.
|
||||
2000, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
@ -372,5 +372,7 @@ extern void real_floor (REAL_VALUE_TYPE *, enum machine_mode,
|
|||
const REAL_VALUE_TYPE *);
|
||||
extern void real_ceil (REAL_VALUE_TYPE *, enum machine_mode,
|
||||
const REAL_VALUE_TYPE *);
|
||||
extern void real_round (REAL_VALUE_TYPE *, enum machine_mode,
|
||||
const REAL_VALUE_TYPE *);
|
||||
|
||||
#endif /* ! GCC_REAL_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue