tree-optimization/113895 - consistency check fails in copy_reference_ops_from_ref
The following addresses consistency check fails in copy_reference_ops_from_ref when we are handling out-of-bound array accesses (it's almost impossible to identically mimic the get_ref_base_and_extent behavior). It also addresses the case where an out-of-bound constant offset computes to a -1 off which is the special value for "unknown". This patch basically turns off verification in those cases. PR tree-optimization/113895 * tree-ssa-sccvn.cc (copy_reference_ops_from_ref): Disable consistency checking when there are out-of-bound array accesses. Allow -1 off when from an array reference with constant index. * gcc.dg/torture/pr113895-2.c: New testcase. * gcc.dg/torture/pr113895-3.c: Likewise. * gcc.dg/torture/pr113895-4.c: Likewise.
This commit is contained in:
parent
7f3d900684
commit
5fd1cbfd65
4 changed files with 66 additions and 2 deletions
13
gcc/testsuite/gcc.dg/torture/pr113895-2.c
Normal file
13
gcc/testsuite/gcc.dg/torture/pr113895-2.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
extern void d(int);
|
||||
int a[2][4], b;
|
||||
int main() {
|
||||
while (b) {
|
||||
int c;
|
||||
d(a[b][c]);
|
||||
for (c = 0; c < 7; c++)
|
||||
;
|
||||
}
|
||||
return 0;
|
||||
}
|
10
gcc/testsuite/gcc.dg/torture/pr113895-3.c
Normal file
10
gcc/testsuite/gcc.dg/torture/pr113895-3.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
extern void f();
|
||||
char a[1][1], b;
|
||||
int main() {
|
||||
int c = -1U;
|
||||
if (b)
|
||||
f(a[c][b]);
|
||||
return 0;
|
||||
}
|
14
gcc/testsuite/gcc.dg/torture/pr113895-4.c
Normal file
14
gcc/testsuite/gcc.dg/torture/pr113895-4.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
long a, b, c;
|
||||
int d;
|
||||
long e[2][1];
|
||||
int f() {
|
||||
if (c == a)
|
||||
c = b;
|
||||
}
|
||||
void g() {
|
||||
int h, i = 0;
|
||||
for (; f() + d + i; i++)
|
||||
e[h][i] = 4;
|
||||
}
|
|
@ -1107,9 +1107,29 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
|
|||
the vn_reference ops differ by adjusting those indexes to
|
||||
appropriate constants. */
|
||||
poly_int64 off = 0;
|
||||
bool oob_index = false;
|
||||
for (unsigned i = result->length (); i > start; --i)
|
||||
{
|
||||
auto &op = (*result)[i-1];
|
||||
if (flag_checking
|
||||
&& op.opcode == ARRAY_REF
|
||||
&& TREE_CODE (op.op0) == INTEGER_CST)
|
||||
{
|
||||
/* The verifier below chokes on inconsistencies of handling
|
||||
out-of-bound accesses so disable it in that case. */
|
||||
tree atype = (*result)[i].type;
|
||||
if (TREE_CODE (atype) == ARRAY_TYPE)
|
||||
if (tree dom = TYPE_DOMAIN (atype))
|
||||
if ((TYPE_MIN_VALUE (dom)
|
||||
&& TREE_CODE (TYPE_MIN_VALUE (dom)) == INTEGER_CST
|
||||
&& (wi::to_widest (op.op0)
|
||||
< wi::to_widest (TYPE_MIN_VALUE (dom))))
|
||||
|| (TYPE_MAX_VALUE (dom)
|
||||
&& TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST
|
||||
&& (wi::to_widest (op.op0)
|
||||
> wi::to_widest (TYPE_MAX_VALUE (dom)))))
|
||||
oob_index = true;
|
||||
}
|
||||
if ((op.opcode == ARRAY_REF
|
||||
|| op.opcode == ARRAY_RANGE_REF)
|
||||
&& TREE_CODE (op.op0) == SSA_NAME)
|
||||
|
@ -1162,12 +1182,19 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
|
|||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (known_ne (op.off, -1));
|
||||
gcc_assert (known_ne (op.off, -1)
|
||||
/* Out-of-bound indices can compute to
|
||||
a known -1 offset. */
|
||||
|| ((op.opcode == ARRAY_REF
|
||||
|| op.opcode == ARRAY_RANGE_REF)
|
||||
&& poly_int_tree_p (op.op0)
|
||||
&& poly_int_tree_p (op.op1)
|
||||
&& TREE_CODE (op.op2) == INTEGER_CST));
|
||||
off += op.off * BITS_PER_UNIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag_checking)
|
||||
if (flag_checking && !oob_index)
|
||||
{
|
||||
ao_ref r;
|
||||
if (start != 0)
|
||||
|
|
Loading…
Add table
Reference in a new issue