re PR tree-optimization/21959 (vrp miscompiles Ada front-end, drops loop exit test in well-defined wrap-around circumstances)
PR 21959 * tree-ssa-loop-niter.c (scev_probably_wraps_p): Handle type casts between unsigned and signed types with different size or precision. testsuite/ChangeLog PR 21959 * gcc.dg/tree-ssa/pr21959.c: New test. From-SVN: r101365
This commit is contained in:
parent
5ab2b3e44e
commit
3eca1bd776
4 changed files with 67 additions and 0 deletions
|
@ -1,3 +1,10 @@
|
|||
2005-06-27 Diego Novillo <dnovillo@redhat.com>
|
||||
|
||||
PR 21959
|
||||
* tree-ssa-loop-niter.c (scev_probably_wraps_p): Handle type
|
||||
casts between unsigned and signed types with different size
|
||||
or precision.
|
||||
|
||||
2005-06-28 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* tree-optimize.c (exercute_free_datastructures):
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2005-06-27 Diego Novillo <dnovillo@redhat.com>
|
||||
|
||||
PR 21959
|
||||
* gcc.dg/tree-ssa/pr21959.c: New test.
|
||||
|
||||
2005-06-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.c-torture/execute/builtins/lib/main.c (abort): Add prototype.
|
||||
|
|
20
gcc/testsuite/gcc.dg/tree-ssa/pr21959.c
Normal file
20
gcc/testsuite/gcc.dg/tree-ssa/pr21959.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-vrp" } */
|
||||
|
||||
unsigned char c[0xFF];
|
||||
void f(void)
|
||||
{
|
||||
unsigned char i;
|
||||
c[128] = 128;
|
||||
i = 0;
|
||||
while (1)
|
||||
{
|
||||
/* This predicate should not be folded out. */
|
||||
if (((signed char) i) < 0) break;
|
||||
c[i] = ' ';
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "Folding predicate " 0 "vrp" } } */
|
||||
/* { dg-final { cleanup-tree-dump "vrp" } } */
|
|
@ -1649,6 +1649,41 @@ scev_probably_wraps_p (tree type, tree base, tree step,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* If AT_STMT represents a cast operation, we may not be able to
|
||||
take advantage of the undefinedness of signed type evolutions.
|
||||
See PR 21959 for a test case. Essentially, given a cast
|
||||
operation
|
||||
unsigned char i;
|
||||
signed char i.0;
|
||||
...
|
||||
i.0_6 = (signed char) i_2;
|
||||
if (i.0_6 < 0)
|
||||
...
|
||||
|
||||
where i_2 and i.0_6 have the scev {0, +, 1}, we would consider
|
||||
i_2 to wrap around, but not i.0_6, because it is of a signed
|
||||
type. This causes VRP to erroneously fold the predicate above
|
||||
because it thinks that i.0_6 cannot be negative. */
|
||||
if (TREE_CODE (at_stmt) == MODIFY_EXPR)
|
||||
{
|
||||
tree rhs = TREE_OPERAND (at_stmt, 1);
|
||||
tree outer_t = TREE_TYPE (rhs);
|
||||
|
||||
if (!TYPE_UNSIGNED (outer_t)
|
||||
&& (TREE_CODE (rhs) == NOP_EXPR || TREE_CODE (rhs) == CONVERT_EXPR))
|
||||
{
|
||||
tree inner_t = TREE_TYPE (TREE_OPERAND (rhs, 0));
|
||||
|
||||
/* If the inner type is unsigned and its size and/or
|
||||
precision are smaller to that of the outer type, then the
|
||||
expression may wrap around. */
|
||||
if (TYPE_UNSIGNED (inner_t)
|
||||
&& (TYPE_SIZE (inner_t) <= TYPE_SIZE (outer_t)
|
||||
|| TYPE_PRECISION (inner_t) <= TYPE_PRECISION (outer_t)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* After having set INIT_IS_MAX, we can return false: when not using
|
||||
wrapping arithmetic, signed types don't wrap. */
|
||||
if (!flag_wrapv && !TYPE_UNSIGNED (type))
|
||||
|
|
Loading…
Add table
Reference in a new issue