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
|
the vn_reference ops differ by adjusting those indexes to
|
||||||
appropriate constants. */
|
appropriate constants. */
|
||||||
poly_int64 off = 0;
|
poly_int64 off = 0;
|
||||||
|
bool oob_index = false;
|
||||||
for (unsigned i = result->length (); i > start; --i)
|
for (unsigned i = result->length (); i > start; --i)
|
||||||
{
|
{
|
||||||
auto &op = (*result)[i-1];
|
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
|
if ((op.opcode == ARRAY_REF
|
||||||
|| op.opcode == ARRAY_RANGE_REF)
|
|| op.opcode == ARRAY_RANGE_REF)
|
||||||
&& TREE_CODE (op.op0) == SSA_NAME)
|
&& TREE_CODE (op.op0) == SSA_NAME)
|
||||||
|
@ -1162,12 +1182,19 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
|
||||||
}
|
}
|
||||||
else
|
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;
|
off += op.off * BITS_PER_UNIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flag_checking)
|
if (flag_checking && !oob_index)
|
||||||
{
|
{
|
||||||
ao_ref r;
|
ao_ref r;
|
||||||
if (start != 0)
|
if (start != 0)
|
||||||
|
|
Loading…
Add table
Reference in a new issue