diff options
author | Roger Sayle <roger@eyesopen.com> | 2003-05-06 03:14:10 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2003-05-06 03:14:10 +0000 |
commit | e82a312b55f88fc3d035e0c24409c71e043e9633 (patch) | |
tree | 2a99b03c08d036a34af9b1b5c844c11e3d67a3af /gcc/builtins.c | |
parent | d7b4a590279f012756741c12f2027d714ea776c4 (diff) | |
download | gcc-e82a312b55f88fc3d035e0c24409c71e043e9633.zip gcc-e82a312b55f88fc3d035e0c24409c71e043e9633.tar.gz gcc-e82a312b55f88fc3d035e0c24409c71e043e9633.tar.bz2 |
real.c (real_powi): New function to calculate the value of a real raised to an integer power, i.e.
* real.c (real_powi): New function to calculate the value of
a real raised to an integer power, i.e. pow(x,n) for int n.
(real_sqrt): Convert to using the faster do_add, do_multiply
and do_divide API for consistency with the rest of real.c.
* real.h (real_powi): Prototype here.
* builtins.c (fold_builtin): Avoid local variable mode when
evaluating sqrt at compile time. Attempt to evaluate pow at
compile-time, by checking for an integral exponent.
* gcc.dg/builtins-14.c: New test case.
From-SVN: r66515
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index feee531..c309997 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -5011,12 +5011,10 @@ fold_builtin (exp) if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) { - enum machine_mode mode; REAL_VALUE_TYPE r, x; x = TREE_REAL_CST (arg); - mode = TYPE_MODE (type); - if (real_sqrt (&r, mode, &x) + if (real_sqrt (&r, TYPE_MODE (type), &x) || (!flag_trapping_math && !flag_errno_math)) return build_real (type, r); } @@ -5229,6 +5227,28 @@ fold_builtin (exp) return build_function_call_expr (sqrtfn, arglist); } } + + /* Attempt to evaluate pow at compile-time. */ + if (TREE_CODE (arg0) == REAL_CST + && ! TREE_CONSTANT_OVERFLOW (arg0)) + { + REAL_VALUE_TYPE cint; + HOST_WIDE_INT n; + + n = real_to_integer(&c); + real_from_integer (&cint, VOIDmode, n, + n < 0 ? -1 : 0, 0); + if (real_identical (&c, &cint)) + { + REAL_VALUE_TYPE x; + bool inexact; + + x = TREE_REAL_CST (arg0); + inexact = real_powi (&x, TYPE_MODE (type), &x, n); + if (flag_unsafe_math_optimizations || !inexact) + return build_real (type, x); + } + } } /* Optimize pow(exp(x),y) = exp(x*y). */ |