2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-04-15 13:41:13 +08:00

re PR tree-optimization/27039 (Unable to determine # of iterations for a simple loop)

2006-06-04  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/27039
	* fold-const.c (fold_comparison): Handle pointer comparison
	again for all comparison codes.  Compare offsets in signed
	size type.
	(fold_binary): Move code from here.

	* gcc.dg/tree-ssa/loop-17.c: New testcase.

From-SVN: r114357
This commit is contained in:
Richard Guenther 2006-06-04 12:59:40 +00:00 committed by Richard Biener
parent 0701ea2e18
commit 7ec434b841
4 changed files with 67 additions and 28 deletions
gcc

@ -1,3 +1,11 @@
2006-06-04 Richard Guenther <rguenther@suse.de>
PR tree-optimization/27039
* fold-const.c (fold_comparison): Handle pointer comparison
again for all comparison codes. Compare offsets in signed
size type.
(fold_binary): Move code from here.
2006-06-03 Roger Sayle <roger@eyesopen.com>
PR target/26223

@ -7764,6 +7764,41 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
return fold_build2 (code, type, variable, lhs);
}
/* If this is a comparison of two exprs that look like an ARRAY_REF of the
same object, then we can fold this to a comparison of the two offsets in
signed size type. This is possible because pointer arithmetic is
restricted to retain within an object and overflow on pointer differences
is undefined as of 6.5.6/8 and /9 with respect to the signed ptrdiff_t. */
if (POINTER_TYPE_P (TREE_TYPE (arg0))
&& !flag_wrapv && !flag_trapv)
{
tree base0, offset0, base1, offset1;
if (extract_array_ref (arg0, &base0, &offset0)
&& extract_array_ref (arg1, &base1, &offset1)
&& operand_equal_p (base0, base1, 0))
{
tree signed_size_type_node;
signed_size_type_node = signed_type_for (size_type_node);
/* By converting to signed size type we cover middle-end pointer
arithmetic which operates on unsigned pointer types of size
type size and ARRAY_REF offsets which are properly sign or
zero extended from their type in case it is narrower than
size type. */
if (offset0 == NULL_TREE)
offset0 = build_int_cst (signed_size_type_node, 0);
else
offset0 = fold_convert (signed_size_type_node, offset0);
if (offset1 == NULL_TREE)
offset1 = build_int_cst (signed_size_type_node, 0);
else
offset1 = fold_convert (signed_size_type_node, offset1);
return fold_build2 (code, type, offset0, offset1);
}
}
if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
{
tree targ0 = strip_float_extensions (arg0);
@ -10539,34 +10574,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
tem, build_int_cst (TREE_TYPE (tem), 0));
}
/* If this is a comparison of two exprs that look like an
ARRAY_REF of the same object, then we can fold this to a
comparison of the two offsets. This is only safe for
EQ_EXPR and NE_EXPR because of overflow issues. */
{
tree base0, offset0, base1, offset1;
if (extract_array_ref (arg0, &base0, &offset0)
&& extract_array_ref (arg1, &base1, &offset1)
&& operand_equal_p (base0, base1, 0))
{
/* Handle no offsets on both sides specially. */
if (offset0 == NULL_TREE && offset1 == NULL_TREE)
return fold_build2 (code, type, integer_zero_node,
integer_zero_node);
if (!offset0 || !offset1
|| TREE_TYPE (offset0) == TREE_TYPE (offset1))
{
if (offset0 == NULL_TREE)
offset0 = build_int_cst (TREE_TYPE (offset1), 0);
if (offset1 == NULL_TREE)
offset1 = build_int_cst (TREE_TYPE (offset0), 0);
return fold_build2 (code, type, offset0, offset1);
}
}
}
if (integer_zerop (arg1)
&& tree_expr_nonzero_p (arg0))
{

@ -1,3 +1,8 @@
2006-06-04 Richard Guenther <rguenther@suse.de>
PR tree-optimization/27039
* gcc.dg/tree-ssa/loop-17.c: New testcase.
2006-06-03 Roger Sayle <roger@eyesopen.com>
PR target/26223

@ -0,0 +1,19 @@
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-sccp-details" } */
/* To determine the number of iterations in this loop we need to fold
p_4 + 4B > p_4 + 8B to false. This transformation has caused
troubles in the past due to overflow issues. */
int foo (int *p)
{
int i = 0, *x;
for (x = p; x < p + 2; x++)
i++;
return i;
}
/* { dg-final { scan-tree-dump "set_nb_iterations_in_loop = 2" "sccp" } } */
/* { dg-final { cleanup-tree-dump "sccp" } } */