summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2009-06-18 11:35:38 +0000
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2009-06-18 11:35:38 +0000
commitab60f4744c30010543431a65dd47d34870f9bb43 (patch)
tree904a11ef4efd2cdd11a40d4bba5529efb85e3085
parent969eb27fc91e04a938f05afb7279769fc9e28b83 (diff)
downloadgcc-ab60f4744c30010543431a65dd47d34870f9bb43.tar.gz
* convert.c (convert_to_integer): Convert (int)logb() into ilogb().
testsuite/ChangeLog: * gcc.dg/builtins-65.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@148653 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/convert.c31
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/builtins-65.c39
4 files changed, 78 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ca88155904f..01d2a0d8b54 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2009-06-18 Uros Bizjak <ubizjak@gmail.com>
+
+ * convert.c (convert_to_integer): Convert (int)logb() into ilogb().
+
2009-06-17 Olivier Hainque <hainque@adacore.com>
* collect2.c (main): Use CONST_CAST2 to perform char ** to
diff --git a/gcc/convert.c b/gcc/convert.c
index b6a9d3dc531..8245e1647fb 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -482,6 +482,37 @@ convert_to_integer (tree type, tree expr)
}
}
+ /* Convert (int)logb(d) -> ilogb(d). */
+ if (optimize
+ && flag_unsafe_math_optimizations
+ && !flag_trapping_math && !flag_errno_math && flag_finite_math_only
+ && integer_type_node
+ && (outprec > TYPE_PRECISION (integer_type_node)
+ || (outprec == TYPE_PRECISION (integer_type_node)
+ && !TYPE_UNSIGNED (type))))
+ {
+ tree s_expr = strip_float_extensions (expr);
+ tree s_intype = TREE_TYPE (s_expr);
+ const enum built_in_function fcode = builtin_mathfn_code (s_expr);
+ tree fn = 0;
+
+ switch (fcode)
+ {
+ CASE_FLT_FN (BUILT_IN_LOGB):
+ fn = mathfn_built_in (s_intype, BUILT_IN_ILOGB);
+ break;
+
+ default:
+ break;
+ }
+
+ if (fn)
+ {
+ tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
+ return convert_to_integer (type, newexpr);
+ }
+ }
+
switch (TREE_CODE (intype))
{
case POINTER_TYPE:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c16ecd04795..e0d1f6f421c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2009-06-18 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.dg/builtins-65.c: New test.
+
2009-06-18 Janus Weil <janus@gcc.gnu.org>
PR fortran/40451
diff --git a/gcc/testsuite/gcc.dg/builtins-65.c b/gcc/testsuite/gcc.dg/builtins-65.c
new file mode 100644
index 00000000000..7c6aa20bd84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtins-65.c
@@ -0,0 +1,39 @@
+/* { dg-do link } */
+/* { dg-options "-O2 -ffast-math" } */
+
+extern int ilogbf (float);
+extern float logbf (float);
+extern int ilogb (double);
+extern double logb (double);
+extern int ilogbl (long double);
+extern long double logbl (long double);
+
+extern void link_error(void);
+
+void testf(float x)
+{
+ if ((int) logbf (x) != ilogbf (x))
+ link_error ();
+}
+
+void test(double x)
+{
+ if ((int) logb (x) != ilogb (x))
+ link_error ();
+}
+
+void testl(long double x)
+{
+ if ((int) logbl (x) != ilogbl (x))
+ link_error ();
+}
+
+int main()
+{
+ testf (2.0f);
+ test (2.0);
+ testl (2.0l);
+
+ return 0;
+}
+