https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109564
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> --- So the failure mode is different than the previous case since there's no backedge involved at all. Instead all of the VREL_EQ relations we add are for PHIs like output_73 = PHI <output_72(23), output_42(D)(37)> where we equate the result with the single (possibly) initialized argument (the other arg is always a default def). Note we refrain from doing the similar optimization in copyprop (it's not "optimistic" in this regard, unlike CCP), but historically to avoid missing uninit diagnostics. A single added relation is enough to trigger the issue. With diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index 429734f954a..fd97739140e 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "value-query.h" #include "gimple-range-op.h" #include "gimple-range.h" +#include "dbgcnt.h" // Construct a fur_source, and set the m_query field. fur_source::fur_source (range_query *q) @@ -814,7 +815,7 @@ fold_using_range::range_of_phi (vrange &r, gphi *phi, fur_source &src) single_arg = NULL; break; } - if (single_arg) + if (single_arg && dbg_cnt (treepre_insert)) src.register_relation (phi, VREL_EQ, phi_def, single_arg); } else if (src.get_operand (arg_range, single_arg) and -fdbg-cnt=treepre_insert:1-1 we see ***dbgcnt: lower limit 1 reached for treepre_insert.*** ***dbgcnt: upper limit 1 reached for treepre_insert.*** Registering value_relation (state_size_17 == _1) (bb6) at state_size_17 = PHI <state_size_35(D)(2), _1(5)> GLOBAL : UPDATE cache for state_size_17 in BB 6 : successors : : No updates! TRUE : (204) range_of_stmt (state_size_17) [irange] long int [1, 1600] NONZERO 0x7ff state_size_17 : CACHE: BB 10 DOM query for state_size_17, found [irange] long int [1, 1600] NONZERO 0x7ff at BB6 CACHE: Range for DOM returns : [irange] long int [1, 1600] NONZERO 0x7ff Filled from dominator! : [irange] long int [1, 1600] NONZERO 0x7ff Checking Equivalence ( == ) _1 CACHE: BB 10 DOM query for _1, found [irange] long int [-65536, -65536][1, 1600] at BB9 so I _think_ what goes wrong is that when we go to see if (_1 != -65536) { if (_1 in [1, 1600]) goto merge; } else goto merge; merge: state_size_17 = PHI <state_size_35(D)(2), _1(5)> we somehow arrive at state_size_17 _not_ considering _1 == -65536 because of the equivalence. That is we somehow use equivalences to "skip" edges when processing PHI merges of incoming ranges? Basically when computing the range for state_size_17 we merge the range of the equivalences but only from the edge it appears in as argument? That looks flawed. A much simplified testcase can probably be constructed.