Commit d977cb9c by Richard Guenther Committed by Richard Biener

re PR c/43007 (No longer folds (unsigned int) ((long long unsigned int) spi_bias / 1008))

2010-02-10  Richard Guenther  <rguenther@suse.de>

	PR c/43007
	* tree.c (get_unwidened): Handle constants.
	* convert.c (convert_to_integer): Handle TRUNC_DIV_EXPR.

	* gcc.c-torture/execute/20100209-1.c: New testcase.
	* gcc.dg/fold-div-3.c: Likewise.

From-SVN: r156653
parent 563cb662
2010-02-10 Richard Guenther <rguenther@suse.de>
PR c/43007
* tree.c (get_unwidened): Handle constants.
* convert.c (convert_to_integer): Handle TRUNC_DIV_EXPR.
2010-02-10 Martin Jambor <mjambor@suse.cz>
PR lto/42985
......
......@@ -673,6 +673,31 @@ convert_to_integer (tree type, tree expr)
}
break;
case TRUNC_DIV_EXPR:
{
tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
/* Don't distribute unless the output precision is at least as big
as the actual inputs and it has the same signedness. */
if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
&& outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
/* If signedness of arg0 and arg1 don't match,
we can't necessarily find a type to compare them in. */
&& (TYPE_UNSIGNED (TREE_TYPE (arg0))
== TYPE_UNSIGNED (TREE_TYPE (arg1)))
/* Do not change the sign of the division. */
&& (TYPE_UNSIGNED (TREE_TYPE (expr))
== TYPE_UNSIGNED (TREE_TYPE (arg0)))
/* Either require unsigned division or a division by
a constant that is not -1. */
&& (TYPE_UNSIGNED (TREE_TYPE (arg0))
|| (TREE_CODE (arg1) == INTEGER_CST
&& !integer_all_onesp (arg1))))
goto trunc1;
break;
}
case MAX_EXPR:
case MIN_EXPR:
case MULT_EXPR:
......
2010-02-10 Richard Guenther <rguenther@suse.de>
PR c/43007
* gcc.c-torture/execute/20100209-1.c: New testcase.
* gcc.dg/fold-div-3.c: Likewise.
2010-02-10 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/builtin-ffs-1.c: New test.
......
int bar(int foo)
{
return (int)(((unsigned long long)(long long)foo) / 8);
}
extern void abort (void);
int main()
{
if (sizeof (long long) > sizeof (int)
&& bar(-1) != -1)
abort ();
return 0;
}
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-original" } */
unsigned int
apply_frontend_param (unsigned int spi_bias)
{
static const int ppm = 8000;
spi_bias /= 1000ULL + ppm/1000;
return spi_bias;
}
/* Make sure we perform the division in the narrower type. */
/* { dg-final { scan-tree-dump "spi_bias = spi_bias / 1008;" "original" } } */
/* { dg-final { cleanup-tree-dump "original" } } */
......@@ -7623,6 +7623,14 @@ get_unwidened (tree op, tree for_type)
}
}
/* If we finally reach a constant see if it fits in for_type and
in that case convert it. */
if (for_type
&& TREE_CODE (win) == INTEGER_CST
&& TREE_TYPE (win) != for_type
&& int_fits_type_p (win, for_type))
win = fold_convert (for_type, win);
return win;
}
......
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