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:
parent
0701ea2e18
commit
7ec434b841
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
|
||||
|
19
gcc/testsuite/gcc.dg/tree-ssa/loop-17.c
Normal file
19
gcc/testsuite/gcc.dg/tree-ssa/loop-17.c
Normal file
@ -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" } } */
|
Loading…
x
Reference in New Issue
Block a user