[Neither Andrew nor I are familiar with the SCEV code. We treat it as a black box :). So we could use a SCEV expert here.]
In bounds_of_var_in_loop, evolution_part_in_loop_num is returning NULL: step = evolution_part_in_loop_num (chrec, loop->num); and we ICE while trying to calculate the range for STEP. This is for: (gdb) dd stmt qx.0_3 = PHI <qx.0_1(3)> (gdb) dd var qx.0_3 It looks like NULL is a perfectly valid response from evolution_part_in_loop_num. Should we just bail if NULL? If bailing is the correct solution, the following patch fixes the PR and passes tests. Thanks. Aldy gcc/ChangeLog: PR tree-optimization/97396 * vr-values.c (bounds_of_var_in_loop): Bail on no step. gcc/testsuite/ChangeLog: * gcc.dg/pr97396.c: New test. --- gcc/testsuite/gcc.dg/pr97396.c | 23 +++++++++++++++++++++++ gcc/vr-values.c | 2 ++ 2 files changed, 25 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr97396.c diff --git a/gcc/testsuite/gcc.dg/pr97396.c b/gcc/testsuite/gcc.dg/pr97396.c new file mode 100644 index 00000000000..d992c11f238 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr97396.c @@ -0,0 +1,23 @@ +// { dg-do compile } +// { dg-options "-O1 -ftree-vrp" } +// { dg-additional-options "-m32" { target { i?86-*-* x86_64-*-* } } } + +unsigned int +po (char *os, unsigned int al) +{ + for (;;) + { + int qx = 0; + + while (al < 1) + { + char *cw; + + cw = os + qx; + if (cw) + return al + qx; + + qx += sizeof *cw; + } + } +} diff --git a/gcc/vr-values.c b/gcc/vr-values.c index da0b249278b..16f6c629f29 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -1827,6 +1827,8 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query, init = initial_condition_in_loop_num (chrec, loop->num); step = evolution_part_in_loop_num (chrec, loop->num); + if (step == NULL_TREE) + return false; /* If INIT is an SSA with a singleton range, set INIT to said singleton, otherwise leave INIT alone. */ -- 2.25.4