Commit ca3df643 by Kaveh R. Ghazi Committed by Kaveh Ghazi

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
parent 3c2d6797
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
......
......@@ -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:
......
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
......
/* 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;
}
......@@ -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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment