re PR middle-end/28473 (with -O, casting result of round(x) to uint64_t produces wrong values for x > INT_MAX)

PR middle-end/28473
	* convert.c (convert_to_integer): When transforming (T)foo(x) into
	bar(x) check that bar's result type can represent all the values of T.

	* gcc.dg/fold-convround-1.c: New test case.

From-SVN: r115742
This commit is contained in:
Roger Sayle 2006-07-25 23:21:56 +00:00 committed by Roger Sayle
parent cdc30c4579
commit 738764ef1e
4 changed files with 66 additions and 13 deletions

View File

@ -1,3 +1,9 @@
2006-07-25 Roger Sayle <roger@eyesopen.com>
PR middle-end/28473
* convert.c (convert_to_integer): When transforming (T)foo(x) into
bar(x) check that bar's result type can represent all the values of T.
2006-07-25 Zdenek Dvorak <dvorakz@suse.cz>
* tree-chrec.c (chrec_convert_aggressive): Return NULL on failure.

View File

@ -388,27 +388,36 @@ convert_to_integer (tree type, tree expr)
/* Only convert in ISO C99 mode. */
if (!TARGET_C99_FUNCTIONS)
break;
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
else
if (outprec < TYPE_PRECISION (long_integer_type_node)
|| (outprec == TYPE_PRECISION (long_integer_type_node)
&& !TYPE_UNSIGNED (type)))
fn = mathfn_built_in (s_intype, BUILT_IN_LCEIL);
else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
&& !TYPE_UNSIGNED (type))
fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
break;
CASE_FLT_FN (BUILT_IN_FLOOR):
/* Only convert in ISO C99 mode. */
if (!TARGET_C99_FUNCTIONS)
break;
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR);
else
if (outprec < TYPE_PRECISION (long_integer_type_node)
|| (outprec == TYPE_PRECISION (long_integer_type_node)
&& !TYPE_UNSIGNED (type)))
fn = mathfn_built_in (s_intype, BUILT_IN_LFLOOR);
else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
&& !TYPE_UNSIGNED (type))
fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR);
break;
CASE_FLT_FN (BUILT_IN_ROUND):
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND);
else
if (outprec < TYPE_PRECISION (long_integer_type_node)
|| (outprec == TYPE_PRECISION (long_integer_type_node)
&& !TYPE_UNSIGNED (type)))
fn = mathfn_built_in (s_intype, BUILT_IN_LROUND);
else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
&& !TYPE_UNSIGNED (type))
fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND);
break;
CASE_FLT_FN (BUILT_IN_RINT):
@ -417,10 +426,13 @@ convert_to_integer (tree type, tree expr)
break;
/* ... Fall through ... */
CASE_FLT_FN (BUILT_IN_NEARBYINT):
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT);
else
fn = mathfn_built_in (s_intype, BUILT_IN_LRINT);
if (outprec < TYPE_PRECISION (long_integer_type_node)
|| (outprec == TYPE_PRECISION (long_integer_type_node)
&& !TYPE_UNSIGNED (type)))
fn = mathfn_built_in (s_intype, BUILT_IN_LRINT);
else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
&& !TYPE_UNSIGNED (type))
fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT);
break;
CASE_FLT_FN (BUILT_IN_TRUNC):

View File

@ -1,3 +1,8 @@
2006-07-25 Roger Sayle <roger@eyesopen.com>
PR middle-end/28473
* gcc.dg/fold-convround-1.c: New test case.
2006-07-24 Steven G. Kargl <kargls@comcast.net>
* gfortran.dg/arithmetic_if.f90: Fix comments.

View File

@ -0,0 +1,30 @@
/* PR middle-end/28473. */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-original" } */
extern double round(double);
extern double floor(double);
extern double ceil(double);
unsigned long long test1(double x)
{
return (unsigned long long) round(x);
}
unsigned long long test2(double x)
{
return (unsigned long long) floor(x);
}
unsigned long long test3(double x)
{
return (unsigned long long) ceil(x);
}
/* { dg-final { scan-tree-dump-times "__builtin_lround" 0 "original" } } */
/* { dg-final { scan-tree-dump-times "__builtin_llround" 0 "original" } } */
/* { dg-final { scan-tree-dump-times "__builtin_lfloor" 0 "original" } } */
/* { dg-final { scan-tree-dump-times "__builtin_llfloor" 0 "original" } } */
/* { dg-final { scan-tree-dump-times "__builtin_lceil" 0 "original" } } */
/* { dg-final { scan-tree-dump-times "__builtin_llceil" 0 "original" } } */
/* { dg-final { cleanup-tree-dump "original" } } */