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
This commit is contained in:
parent
3c2d679772
commit
ca3df64369
5 changed files with 153 additions and 15 deletions
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
56
gcc/testsuite/gcc.dg/torture/builtin-convert-3.c
Normal file
56
gcc/testsuite/gcc.dg/torture/builtin-convert-3.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue