diff options
author | Richard Biener <rguenther@suse.de> | 2024-02-05 09:44:12 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2024-02-05 11:07:07 +0100 |
commit | 42959acb8409c39e1c71c43528832611c3b71e25 (patch) | |
tree | 1cee4415d97205eb7ab55ee140e8effe0684bdb5 | |
parent | 9d139c036547a4b3b43439b82f94a9c350d4fa2f (diff) | |
download | gcc-42959acb8409c39e1c71c43528832611c3b71e25.zip gcc-42959acb8409c39e1c71c43528832611c3b71e25.tar.gz gcc-42959acb8409c39e1c71c43528832611c3b71e25.tar.bz2 |
tree-optimization/113707 - ICE with VN elimination
The following avoids different avail answers depending on how the
iteration progressed.
PR tree-optimization/113707
* tree-ssa-sccvn.cc (rpo_elim::eliminate_avail): After
checking the avail set treat out-of-region defines as
available.
* gcc.dg/torture/pr113707-1.c: New testcase.
* gcc.dg/torture/pr113707-2.c: Likewise.
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr113707-1.c | 45 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr113707-2.c | 26 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.cc | 5 |
3 files changed, 76 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr113707-1.c b/gcc/testsuite/gcc.dg/torture/pr113707-1.c new file mode 100644 index 0000000..c1a50b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr113707-1.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ + +int printf(const char *, ...); +struct a { + int b; +} n; +int a, c, d, e, f = 1, g, h, j = 1, k, l, m, o; +int main() { + struct a p; + int i; + p.b = 1; + if (!j) + goto q; + p.b = i = 0; + for (; i < 1; i++) + if (k) + while (m) + r: + q: + if (p.b) + g = 1; + while (1) { + i = 0; + for (; i < 5; i++) + ; + if (l) { + while (h) + ; + if (o) { + d = 0; + for (; d < 8; d++) + ; + } + } + for (; e; e--) + while (a) + p = n; + if (c) + goto r; + printf("0"); + if (f) + break; + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr113707-2.c b/gcc/testsuite/gcc.dg/torture/pr113707-2.c new file mode 100644 index 0000000..957e6f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr113707-2.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ + +int a, b, c, d, e, f, g, h, j, k, l; +void n() { + while (c) + if (1) { + for (h = 5; h; h--) { + int m = e % 2; + d = ~g || h ^ m / -1; + if (h > 5) + e = k; + } + return; + } +} +int main() { + if (a) + for (int i = 0; i < 2; i++) { + for (f = 1; f < 6; f++) + for (c = 7; c >= 0; c--) + if (l) + b = 0; + n(); + } + return 0; +} diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index bbcf865..8792cd0 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -7776,6 +7776,11 @@ rpo_elim::eliminate_avail (basic_block bb, tree op) av = av->next; } while (av); + /* While we prefer avail we have to fallback to using the value + directly if defined outside of the region when none of the + available defs suit. */ + if (!valnum_info->visited) + return valnum; } else if (valnum != VN_TOP) /* valnum is is_gimple_min_invariant. */ |