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:
Richard Biener 2024-02-16 10:08:43 +01:00
parent 7f3d900684
commit 5fd1cbfd65
4 changed files with 66 additions and 2 deletions

View 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;
}

View 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;
}

View 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;
}

View file

@ -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)