aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2003-05-06 03:14:10 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2003-05-06 03:14:10 +0000
commite82a312b55f88fc3d035e0c24409c71e043e9633 (patch)
tree2a99b03c08d036a34af9b1b5c844c11e3d67a3af /gcc/builtins.c
parentd7b4a590279f012756741c12f2027d714ea776c4 (diff)
downloadgcc-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.c26
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). */