Skip to content

Commit 5fd1cbf

Browse files
committed
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.
1 parent 7f3d900 commit 5fd1cbf

File tree

4 files changed

+66
-2
lines changed

4 files changed

+66
-2
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* { dg-do compile } */
2+
3+
extern void d(int);
4+
int a[2][4], b;
5+
int main() {
6+
while (b) {
7+
int c;
8+
d(a[b][c]);
9+
for (c = 0; c < 7; c++)
10+
;
11+
}
12+
return 0;
13+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* { dg-do compile } */
2+
3+
extern void f();
4+
char a[1][1], b;
5+
int main() {
6+
int c = -1U;
7+
if (b)
8+
f(a[c][b]);
9+
return 0;
10+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* { dg-do compile } */
2+
3+
long a, b, c;
4+
int d;
5+
long e[2][1];
6+
int f() {
7+
if (c == a)
8+
c = b;
9+
}
10+
void g() {
11+
int h, i = 0;
12+
for (; f() + d + i; i++)
13+
e[h][i] = 4;
14+
}

gcc/tree-ssa-sccvn.cc

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,9 +1107,29 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
11071107
the vn_reference ops differ by adjusting those indexes to
11081108
appropriate constants. */
11091109
poly_int64 off = 0;
1110+
bool oob_index = false;
11101111
for (unsigned i = result->length (); i > start; --i)
11111112
{
11121113
auto &op = (*result)[i-1];
1114+
if (flag_checking
1115+
&& op.opcode == ARRAY_REF
1116+
&& TREE_CODE (op.op0) == INTEGER_CST)
1117+
{
1118+
/* The verifier below chokes on inconsistencies of handling
1119+
out-of-bound accesses so disable it in that case. */
1120+
tree atype = (*result)[i].type;
1121+
if (TREE_CODE (atype) == ARRAY_TYPE)
1122+
if (tree dom = TYPE_DOMAIN (atype))
1123+
if ((TYPE_MIN_VALUE (dom)
1124+
&& TREE_CODE (TYPE_MIN_VALUE (dom)) == INTEGER_CST
1125+
&& (wi::to_widest (op.op0)
1126+
< wi::to_widest (TYPE_MIN_VALUE (dom))))
1127+
|| (TYPE_MAX_VALUE (dom)
1128+
&& TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST
1129+
&& (wi::to_widest (op.op0)
1130+
> wi::to_widest (TYPE_MAX_VALUE (dom)))))
1131+
oob_index = true;
1132+
}
11131133
if ((op.opcode == ARRAY_REF
11141134
|| op.opcode == ARRAY_RANGE_REF)
11151135
&& TREE_CODE (op.op0) == SSA_NAME)
@@ -1162,12 +1182,19 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
11621182
}
11631183
else
11641184
{
1165-
gcc_assert (known_ne (op.off, -1));
1185+
gcc_assert (known_ne (op.off, -1)
1186+
/* Out-of-bound indices can compute to
1187+
a known -1 offset. */
1188+
|| ((op.opcode == ARRAY_REF
1189+
|| op.opcode == ARRAY_RANGE_REF)
1190+
&& poly_int_tree_p (op.op0)
1191+
&& poly_int_tree_p (op.op1)
1192+
&& TREE_CODE (op.op2) == INTEGER_CST));
11661193
off += op.off * BITS_PER_UNIT;
11671194
}
11681195
}
11691196
}
1170-
if (flag_checking)
1197+
if (flag_checking && !oob_index)
11711198
{
11721199
ao_ref r;
11731200
if (start != 0)

0 commit comments

Comments
 (0)