The problem here is that we're exporting a range for an SSA range that happens on the other side of a __builtin_unreachable, but the SSA does not post-dominate the definition point. This is causing ivcanon to unroll things incorrectly.
This was a snafu when converting the code from evrp. PR tree-optimization/107293 gcc/ChangeLog: * tree-ssa-dom.cc (dom_opt_dom_walker::set_global_ranges_from_unreachable_edges): Check that condition post-dominates the definition point. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr107293.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/pr107293.c | 32 ++++++++++++++++++++++++ gcc/tree-ssa-dom.cc | 6 ++++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr107293.c diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107293.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107293.c new file mode 100644 index 00000000000..724c31a11e6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107293.c @@ -0,0 +1,32 @@ +// { dg-do run } +// { dg-options "-w -Os" } + +short a; +int b[1]; + +int c(int p) { + return (p < 0) ? 0 : 10 + ((p / 100 - 16) / 4); +} + +void f(int n) { + while (1) { + int m = n; + while ((m ) ) + m /= 2; + break; + } +} + +void g() { + int h = a = 0; + for (; h + a <= 0; a++) { + if (b[c(a - 6)]) + break; + f(a); + } +} +int main() { + g(); + if (a != 1) + __builtin_abort (); +} diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc index e6b8dace5e9..c7f095d79fc 100644 --- a/gcc/tree-ssa-dom.cc +++ b/gcc/tree-ssa-dom.cc @@ -1367,7 +1367,11 @@ dom_opt_dom_walker::set_global_ranges_from_unreachable_edges (basic_block bb) tree name; gori_compute &gori = m_ranger->gori (); FOR_EACH_GORI_EXPORT_NAME (gori, pred_e->src, name) - if (all_uses_feed_or_dominated_by_stmt (name, stmt)) + if (all_uses_feed_or_dominated_by_stmt (name, stmt) + // The condition must post-dominate the definition point. + && (SSA_NAME_IS_DEFAULT_DEF (name) + || (gimple_bb (SSA_NAME_DEF_STMT (name)) + == pred_e->src))) { Value_Range r (TREE_TYPE (name)); -- 2.37.3