aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>2004-05-02 02:53:05 +0000
committerKaveh Ghazi <ghazi@gcc.gnu.org>2004-05-02 02:53:05 +0000
commitca3df643698b0f67b6376a88aa9b4f586d4b9a00 (patch)
treea34c7202f1576f9f79461bbdb36fc625107a225c /gcc
parent3c2d6797727df4540c7b5b3f5ca826d14370b17c (diff)
downloadgcc-ca3df643698b0f67b6376a88aa9b4f586d4b9a00.zip
gcc-ca3df643698b0f67b6376a88aa9b4f586d4b9a00.tar.gz
gcc-ca3df643698b0f67b6376a88aa9b4f586d4b9a00.tar.bz2
builtins.c (fold_fixed_mathfn): New function.
* builtins.c (fold_fixed_mathfn): New function. (fold_builtin_lround, fold_builtin): Use it. testsuite: * gcc.dg/torture/builtin-integral-1.c: Reorg and add more cases. * gcc.dg/torture/builtin-convert-3.c: New test. From-SVN: r81403
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/builtins.c49
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-convert-3.c56
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-integral-1.c53
5 files changed, 153 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 353e6b0..9fa5652 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2004-05-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (fold_fixed_mathfn): New function.
+ (fold_builtin_lround, fold_builtin): Use it.
+
2004-05-01 Jakub Jelinek <jakub@redhat.com>
* config/sparc/linux64.h (TARGET_DEFAULT): Make 64-bit by default
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 0d04f03..96d365a 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -6075,6 +6075,45 @@ fold_trunc_transparent_mathfn (tree exp)
return 0;
}
+/* EXP is assumed to be builtin call which can narrow the FP type of
+ the argument, for instance lround((double)f) -> lroundf (f). */
+
+static tree
+fold_fixed_mathfn (tree exp)
+{
+ tree fndecl = get_callee_fndecl (exp);
+ tree arglist = TREE_OPERAND (exp, 1);
+ enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+ tree arg;
+
+ if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ return 0;
+
+ arg = TREE_VALUE (arglist);
+
+ /* If argument is already integer valued, and we don't need to worry
+ about setting errno, there's no need to perform rounding. */
+ if (! flag_errno_math && integer_valued_real_p (arg))
+ return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
+
+ if (optimize)
+ {
+ tree ftype = TREE_TYPE (arg);
+ tree arg0 = strip_float_extensions (arg);
+ tree newtype = TREE_TYPE (arg0);
+ tree decl;
+
+ if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
+ && (decl = mathfn_built_in (newtype, fcode)))
+ {
+ arglist =
+ build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
+ return build_function_call_expr (decl, arglist);
+ }
+ }
+ return 0;
+}
+
/* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
is the argument list and TYPE is the return type. Return
NULL_TREE if no if no simplification can be made. */
@@ -6307,7 +6346,7 @@ fold_builtin_lround (tree exp)
}
}
- return 0;
+ return fold_fixed_mathfn (exp);
}
/* Fold function call to builtin ffs, clz, ctz, popcount and parity
@@ -7420,6 +7459,14 @@ fold_builtin (tree exp)
case BUILT_IN_LLROUNDL:
return fold_builtin_lround (exp);
+ case BUILT_IN_LRINT:
+ case BUILT_IN_LRINTF:
+ case BUILT_IN_LRINTL:
+ case BUILT_IN_LLRINT:
+ case BUILT_IN_LLRINTF:
+ case BUILT_IN_LLRINTL:
+ return fold_fixed_mathfn (exp);
+
case BUILT_IN_FFS:
case BUILT_IN_FFSL:
case BUILT_IN_FFSLL:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 596e8ed..822cb30 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-05-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.dg/torture/builtin-integral-1.c: Reorg and add more cases.
+ * gcc.dg/torture/builtin-convert-3.c: New test.
+
2004-05-01 Ulrich Weigand <uweigand@de.ibm.com>
PR middle-end/15054
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-convert-3.c b/gcc/testsuite/gcc.dg/torture/builtin-convert-3.c
new file mode 100644
index 0000000..9901cec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/builtin-convert-3.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 2004 Free Software Foundation.
+
+ Verify that builtin math functions (with fixed point return types)
+ are converted to smaller FP types correctly by the compiler.
+
+ Written by Kaveh Ghazi, 2004-05-01. */
+
+/* { dg-do link } */
+/* { dg-options "-ffast-math" } */
+
+#include "../builtins-config.h"
+
+#define PROTOTYPE1_RET(FN, RET) \
+ extern RET FN(double); \
+ extern RET FN##f(float); \
+ extern RET FN##l(long double);
+
+/* Test converting math builtins to narrower FP types based on if the
+ argument is a narrower type (perhaps implicitly) cast to a wider
+ one. */
+#define INNER_CAST1(MATHFN, RET) \
+ PROTOTYPE1_RET (MATHFN, RET); \
+ extern void link_failure_inner_##MATHFN##l_##MATHFN(void); \
+ extern void link_failure_inner_##MATHFN##l_##MATHFN##f(void); \
+ extern void link_failure_inner_##MATHFN##_##MATHFN##f(void); \
+ if (sizeof (long double) > sizeof (double) \
+ && MATHFN##l(d1) != MATHFN(d1)) \
+ link_failure_inner_##MATHFN##l_##MATHFN(); \
+ if (sizeof (long double) > sizeof (float) \
+ && MATHFN##l(f1) != MATHFN##f(f1)) \
+ link_failure_inner_##MATHFN##l_##MATHFN##f(); \
+ if (sizeof (long double) > sizeof (float) \
+ && MATHFN##l((double)f1) != MATHFN##f(f1)) \
+ link_failure_inner_##MATHFN##l_##MATHFN##f(); \
+ if (sizeof (double) > sizeof (float) \
+ && MATHFN(f1) != MATHFN##f(f1)) \
+ link_failure_inner_##MATHFN##_##MATHFN##f()
+
+void __attribute__ ((__noinline__)) test (double d1, float f1)
+{
+#ifdef __OPTIMIZE__
+#ifdef HAVE_C99_RUNTIME
+ /* We're converting to implicitly generated C99 functions. */
+ INNER_CAST1 (lround, long);
+ INNER_CAST1 (llround, long long);
+ INNER_CAST1 (lrint, long);
+ INNER_CAST1 (llrint, long long);
+#endif /* HAVE_C99_RUNTIME */
+#endif /* __OPTIMIZE__ */
+}
+
+int main (void)
+{
+ test (1, 2);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-integral-1.c b/gcc/testsuite/gcc.dg/torture/builtin-integral-1.c
index 1f2990d..0aeb7ff 100644
--- a/gcc/testsuite/gcc.dg/torture/builtin-integral-1.c
+++ b/gcc/testsuite/gcc.dg/torture/builtin-integral-1.c
@@ -9,33 +9,57 @@
#define PROTOTYPE1(FN) extern double FN(double); extern float FN##f(float); \
extern long double FN##l(long double);
+#define PROTOTYPE1_RET(FN, RET) extern RET FN(double); extern RET FN##f(float); \
+ extern RET FN##l(long double);
+#define PROTOTYPE_LINK_FAILURE(FN) extern void link_failure_##FN(void); \
+ extern void link_failure_##FN##f(void); \
+ extern void link_failure_##FN##l(void); \
PROTOTYPE1(fabs)
+PROTOTYPE1(ceil)
+PROTOTYPE1(floor)
+PROTOTYPE1(nearbyint)
+PROTOTYPE1(rint)
+PROTOTYPE1(round)
+PROTOTYPE1(trunc)
+PROTOTYPE1_RET(lround, long)
+PROTOTYPE1_RET(llround, long long)
+PROTOTYPE1_RET(lrint, long)
+PROTOTYPE1_RET(llrint, long long)
-void test(int i1, int i2)
-{
- /* Test that the various FP truncation builtins detect integral
- arguments. */
+/* Test that the various FP truncation builtins detect integral
+ arguments. */
#define CHECK_FN(MATHFN) \
- PROTOTYPE1 (MATHFN) \
- extern void link_failure_##MATHFN(void); \
- extern void link_failure_##MATHFN##f(void); \
- extern void link_failure_##MATHFN##l(void); \
+ PROTOTYPE_LINK_FAILURE(MATHFN); \
if (MATHFN(i1) != i1) link_failure_##MATHFN(); \
if (MATHFN##f(i1) != i1) link_failure_##MATHFN##f(); \
- if (MATHFN##l(i1) != i1) link_failure_##MATHFN##l(); \
+ if (MATHFN##l(i1) != i1) link_failure_##MATHFN##l();
+
+#define CHECK_FN_RET(MATHFN, RET) \
+ PROTOTYPE_LINK_FAILURE(MATHFN); \
+ if (MATHFN(i1) != (RET)(double)i1) link_failure_##MATHFN(); \
+ if (MATHFN##f(i1) != (RET)(float)i1) link_failure_##MATHFN##f(); \
+ if (MATHFN##l(i1) != (RET)(long double)i1) link_failure_##MATHFN##l();
+
+ /* Check that various other integral expressions are detected. */
+#define CHECK_EXPR(EXPR,NAME) \
+ extern void link_failure_FP_##NAME(void); \
+ extern void link_failure_fixed_##NAME(void); \
+ if (ceill(EXPR) != (EXPR)) link_failure_FP_##NAME(); \
+ if (lroundl(EXPR) != (long)(long double)(EXPR)) link_failure_fixed_##NAME();
+void __attribute__ ((__noinline__)) test (int i1, int i2)
+{
CHECK_FN(ceil);
CHECK_FN(floor);
CHECK_FN(nearbyint);
CHECK_FN(rint);
CHECK_FN(round);
CHECK_FN(trunc);
-
- /* Check that various other integral expressions are detected. */
-#define CHECK_EXPR(EXPR,NAME) \
- extern void link_failure_##NAME(void); \
- if (ceill(EXPR) != (EXPR)) link_failure_##NAME(); \
+ CHECK_FN_RET(lround, long);
+ CHECK_FN_RET(llround, long long);
+ CHECK_FN_RET(lrint, long);
+ CHECK_FN_RET(llrint, long long);
CHECK_EXPR (5.0, REAL_CST);
CHECK_EXPR (5.0F, REAL_CSTf);
@@ -54,5 +78,6 @@ void test(int i1, int i2)
int main (void)
{
+ test (1, 2);
return 0;
}