After r17-3298-g6cda72b8bd6 removed the abnormal-PHI restriction from
gimple_range_ssa_p, recursive fold evaluation can reach ssa_range_in_phi
for a PHI whose block differs from curr_bb(), making prev_bb() invalid
and find_edge() return NULL.
This causes bootstrap failure on riscv64-unknown-linux-gnu (ICE
compiling glibc locale/programs/ld-collate.c at -O2 during GIMPLE
pass thread), blocking the master branch toolchain build.
This is just a draft — it may not be the right approach and is not
necessarily meant for upstream. If the original authors have a proper
fix in mind, that should take priority. However, if they do not have
time soon, this conservative fallback could serve as a stopgap to
avoid leaving the master branch build broken indefinitely.
gcc/ChangeLog:
PR tree-optimization/126876
* gimple-range-path.cc (path_range_query::ssa_range_in_phi):
Fall back to the ranger when the PHI's block != curr_bb().
gcc/testsuite/ChangeLog:
PR tree-optimization/126876
* gcc.dg/tree-ssa/ssa-thread-abnormal-phi-3.c: New test.
---
gcc/gimple-range-path.cc | 13 +++++++----
.../tree-ssa/ssa-thread-abnormal-phi-3.c | 22 +++++++++++++++++++
2 files changed, 31 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-abnormal-phi-3.c
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
index 467e321b8de..b9ad77021da 100644
--- a/gcc/gimple-range-path.cc
+++ b/gcc/gimple-range-path.cc
@@ -254,12 +254,17 @@ path_range_query::ssa_range_in_phi (vrange &r, gphi *phi)
}
basic_block bb = gimple_bb (phi);
+
+ // During recursive folding the PHI's block may not be curr_bb().
+ if (bb != curr_bb ())
+ {
+ m_ranger.range_of_expr (r, name, phi);
+ return;
+ }
+
basic_block prev = prev_bb ();
edge e_in = find_edge (prev, bb);
- // The incoming edge the path supplies is never abnormal, so the
- // argument on it is a valid value for the PHI result even when the
- // result occurs in an abnormal PHI.
- gcc_checking_assert (!(e_in->flags & EDGE_ABNORMAL));
+ gcc_checking_assert (e_in && !(e_in->flags & EDGE_ABNORMAL));
tree arg = PHI_ARG_DEF_FROM_EDGE (phi, e_in);
// Avoid using the cache for ARGs defined in this block, as
// that could create an ordering problem.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-abnormal-phi-3.c
b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-abnormal-phi-3.c
new file mode 100644
index 00000000000..ae6b5cea48f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-abnormal-phi-3.c
@@ -0,0 +1,22 @@
+/* PR tree-optimization/126876 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+/* Reduced from ktextaddons cmark-rc/blocks.c. */
+
+unsigned char *S_parser_feed_eol;
+char S_parser_feed_end;
+void
+S_parser_feed (unsigned char *buffer)
+{
+ while (buffer)
+ {
+ int chunk_len;
+ for (; S_parser_feed_eol;)
+ chunk_len = S_parser_feed_eol - buffer;
+ buffer += chunk_len;
+ if (S_parser_feed_end)
+ if (*buffer)
+ buffer++;
+ }
+}
--
2.52.0