This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: PR middle-end/33007: builtin lround doesn't work
- From: "H.J. Lu" <hjl at lucon dot org>
- To: gcc-patches at gcc dot gnu dot org
- Cc: ghazi at caip dot rutgers dot edu
- Date: Tue, 7 Aug 2007 11:02:43 -0700
- Subject: PATCH: PR middle-end/33007: builtin lround doesn't work
fold_fixed_mathfn may turn builtin lround into FIX_TRUNC_EXPR. But
expand_builtin_int_roundingfn_2 isn't prepared to deal with it. This
patch checks return from expand_expr and handle FIX_TRUNC_EXPR.
H.J.
-----
gcc/
2007-05-13 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/33007
* builtins.c (expand_builtin_int_roundingfn_2): Handle NOP_EXPR
and FIX_TRUNC_EXPR return from expand_expr.
gcc/testsuite/
2007-05-13 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/33007
* gcc.dg/torture/builtin-rounding-2.c: New.
--- gcc/builtins.c.round 2007-07-29 13:18:40.000000000 -0700
+++ gcc/builtins.c 2007-08-07 09:58:46.000000000 -0700
@@ -2689,6 +2689,16 @@ expand_builtin_int_roundingfn_2 (tree ex
start_sequence ();
+ if (TREE_CODE (exp) == NOP_EXPR)
+ switch (TREE_CODE (TREE_OPERAND (exp, 0)))
+ {
+ case FIX_TRUNC_EXPR:
+ builtin_optab = sfixtrunc_optab;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
if (expand_sfix_optab (target, op0, builtin_optab))
{
/* Output the entire sequence. */
@@ -2698,6 +2708,8 @@ expand_builtin_int_roundingfn_2 (tree ex
return target;
}
+ gcc_assert (TREE_CODE (exp) == CALL_EXPR);
+
/* If we were unable to expand via the builtin, stop the sequence
(without outputting the insns) and call to the library function
with the stabilized argument list. */
--- gcc/testsuite/gcc.dg/torture/builtin-rounding-2.c.round 2007-08-07 10:07:05.000000000 -0700
+++ gcc/testsuite/gcc.dg/torture/builtin-rounding-2.c 2007-08-07 10:35:40.000000000 -0700
@@ -0,0 +1,169 @@
+/* Copyright (C) 2007 Free Software Foundation.
+
+ Check that integer folding of the rounding math functions doesn't
+ break anything and produces the expected results. */
+
+/* { dg-do run } */
+/* { dg-options "-ffast-math -ftrapping-math" } */
+
+#define TEST(i) \
+ if (test1 (i) != i) \
+ abort (); \
+ \
+ if (test2 (i) != i) \
+ abort (); \
+ \
+ if (test3 (i) != i) \
+ abort (); \
+ \
+ if (test4 (i) != i) \
+ abort (); \
+ \
+ if (test5 (i) != i) \
+ abort (); \
+ \
+ if (test6 (i) != i) \
+ abort (); \
+ \
+ if (test7 (i) != i) \
+ abort (); \
+ \
+ if (test8 (i) != i) \
+ abort (); \
+ \
+ if (test9 (i) != i) \
+ abort (); \
+ \
+ if (test10 (i) != i) \
+ abort (); \
+ \
+ if (test11 (i) != i) \
+ abort (); \
+ \
+ if (test12 (i) != i) \
+ abort ();
+
+extern void abort();
+
+long
+__attribute__ ((__noinline__))
+test1 (short i)
+{
+ float x;
+ x = i;
+ return __builtin_lround (x);
+}
+
+long
+__attribute__ ((__noinline__))
+test2 (int i)
+{
+ float x;
+ x = i;
+ return __builtin_lround (x);
+}
+
+long
+__attribute__ ((__noinline__))
+test3 (long long i)
+{
+ float x;
+ x = i;
+ return __builtin_lround (x);
+}
+
+long
+__attribute__ ((__noinline__))
+test4 (short i)
+{
+ double x;
+ x = i;
+ return __builtin_lround (x);
+}
+
+long
+__attribute__ ((__noinline__))
+test5 (int i)
+{
+ double x;
+ x = i;
+ return __builtin_lround (x);
+}
+
+long
+__attribute__ ((__noinline__))
+test6 (long long i)
+{
+ double x;
+ x = i;
+ return __builtin_lround (x);
+}
+
+long long
+__attribute__ ((__noinline__))
+test7 (short i)
+{
+ float x;
+ x = i;
+ return __builtin_llround (x);
+}
+
+long long
+__attribute__ ((__noinline__))
+test8 (int i)
+{
+ float x;
+ x = i;
+ return __builtin_llround (x);
+}
+
+long long
+__attribute__ ((__noinline__))
+test9 (long long i)
+{
+ float x;
+ x = i;
+ return __builtin_llround (x);
+}
+
+long long
+__attribute__ ((__noinline__))
+test10 (short i)
+{
+ double x;
+ x = i;
+ return __builtin_llround (x);
+}
+
+long long
+__attribute__ ((__noinline__))
+test11 (int i)
+{
+ double x;
+ x = i;
+ return __builtin_llround (x);
+}
+
+long long
+__attribute__ ((__noinline__))
+test12 (long long i)
+{
+ double x;
+ x = i;
+ return __builtin_llround (x);
+}
+
+int
+main (void)
+{
+ TEST (0);
+ TEST (1);
+ TEST (2);
+ TEST (3);
+ TEST (6);
+ TEST (-1);
+ TEST (-2);
+ TEST (-3);
+ TEST (-6);
+ return 0;
+}