[PATCH, middle-end]: Convert (int)logb() into ilogb().

Uros Bizjak ubizjak@gmail.com
Thu Jun 18 10:23:00 GMT 2009


Hello!

Just an old middle-end patch I have found while cleaning my patch
archive. While it uses old infrastructure for conversion, it actually
converts in the same way as e.g. (long)round(d) -> lround(d) a couple
of lines above.

While  this particular conversion does its job pretty well, I'm not
interested in fixing the conversion infrastructure itself. This can be
fixed in future for all FP->int functions, including newly introduced
ilogb conversion.

2009-06-18  Uros Bizjak  <ubizjak@gmail.com>

	* convert.c (convert_to_integer): Convert (int)logb() into ilogb().

testsuite/ChangeLog:

2009-06-18  Uros Bizjak  <ubizjak@gmail.com>

	* gcc.dg/builtins-65.c: New test.

The patch was bootstrapped and regression tested on
x86_64-pc-linuc-gnu. OK for mainline?

Uros.
-------------- next part --------------
Index: testsuite/gcc.dg/builtins-65.c
===================================================================
--- testsuite/gcc.dg/builtins-65.c	(revision 0)
+++ testsuite/gcc.dg/builtins-65.c	(revision 0)
@@ -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;
+}
+
Index: convert.c
===================================================================
--- convert.c	(revision 148650)
+++ convert.c	(working copy)
@@ -482,6 +482,36 @@ convert_to_integer (tree type, tree expr
 	}
     }
 
+  /* Convert (int)logb(d) -> ilogb(d).  */
+  if (optimize
+      && flag_unsafe_math_optimizations
+      && 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:


More information about the Gcc-patches mailing list