https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97953

--- Comment #17 from Richard Biener <rguenth at gcc dot gnu.org> ---
The issue is a bogus jump threading done in VRP2 caused by bogus range info on
the hoisted gimple_code (use->stmt).

tree-ssa-loop-ivopts.c.137t.pre-  # PT = nonlocal escaped null 
tree-ssa-loop-ivopts.c.137t.pre-  pretmp_252 = use_79(D)->stmt;
tree-ssa-loop-ivopts.c.137t.pre:  pretmp_31 = MEM[(const struct gimple
*)pretmp_252].code;
tree-ssa-loop-ivopts.c.137t.pre-  if (_1 == 4)

the if is the cand->pos == IP_ORIGINAL check.  Now after dom3
suddenly we have

tree-ssa-loop-ivopts.c.188t.dom3-  # PT = nonlocal escaped null 
tree-ssa-loop-ivopts.c.188t.dom3-  pretmp_252 = use_79(D)->stmt;
tree-ssa-loop-ivopts.c.188t.dom3-  # RANGE [6, 6] NONZERO 6
tree-ssa-loop-ivopts.c.188t.dom3:  pretmp_31 = MEM[(const struct gimple
*)pretmp_252].code;
tree-ssa-loop-ivopts.c.188t.dom3-  if (_1 == 4)

before DOM the check is below

  <bb 26> [local count: 972093932]:
  # PT = nonlocal escaped null
  # prephitmp_179 = PHI <pretmp_252(5), pretmp_252(6), pretmp_250(23),
pretmp_216(25), pretmp_210(21)>
  _164 = MEM[(const struct gimple *)prephitmp_179].code;
  # DEBUG g => NULL
  if (_164 == 6)
    goto <bb 34>; [26.31%]

where DOM seems to CSE the load with the earlier (correct) but then
even though it pops the recorded range on pretmp_31 it never backs out
the SSA_NAME_RANGE_INFO?  It's set here:

#0  set_range_info_raw (name=<ssa_name 0x7fffefc9cd38 31>, range_type=VR_RANGE,
min=..., max=...)
    at /home/rguenther/src/trunk/gcc/tree-ssanames.c:359
#1  0x0000000001b1d0f8 in set_range_info (name=<ssa_name 0x7fffefc9cd38 31>,
range_type=VR_RANGE, min=..., max=...)
    at /home/rguenther/src/trunk/gcc/tree-ssanames.c:405
#2  0x00000000027a4d91 in evrp_range_analyzer::set_ssa_range_info
(this=0x7fffffffd100, lhs=<ssa_name 0x7fffefc9cd38 31>, 
    vr=0x444dcd0) at
/home/rguenther/src/trunk/gcc/gimple-ssa-evrp-analyze.c:113
#3  0x00000000027a5597 in evrp_range_analyzer::record_ranges_from_incoming_edge
(this=0x7fffffffd100, 
    bb=<basic_block 0x7fffefca7208 (8)>) at
/home/rguenther/src/trunk/gcc/gimple-ssa-evrp-analyze.c:223
#4  0x00000000027a4ad5 in evrp_range_analyzer::enter (this=0x7fffffffd100,
bb=<basic_block 0x7fffefca7208 (8)>)
    at /home/rguenther/src/trunk/gcc/gimple-ssa-evrp-analyze.c:75
#5  0x00000000019643fb in dom_opt_dom_walker::before_dom_children
(this=0x7fffffffd0d0, bb=<basic_block 0x7fffefca7208 (8)>)
    at /home/rguenther/src/trunk/gcc/tree-ssa-dom.c:1420
#6  0x0000000002736350 in dom_walker::walk (this=0x7fffffffd0d0,
bb=<basic_block 0x7fffefca7208 (8)>)
    at /home/rguenther/src/trunk/gcc/domwalk.c:309
#7  0x0000000001962a54 in (anonymous namespace)::pass_dominator::execute
(this=0x3f2d540, fun=0x7ffff112fb80)
    at /home/rguenther/src/trunk/gcc/tree-ssa-dom.c:724

so we have m_update_global_ranges set here.

218                   push_value_range (vrs[i].first, vrs[i].second);
219                   if (is_fallthru
220                       && m_update_global_ranges
221                       && all_uses_feed_or_dominated_by_stmt (vrs[i].first,
stmt))
222                     {
223                       set_ssa_range_info (vrs[i].first, vrs[i].second);
224                       maybe_set_nonzero_bits (pred_e, vrs[i].first);

but obviously this all_uses_feed_or_dominated_by_stmt doesn't tell us the
whole story:

(gdb) p debug_immediate_uses_for($12)
pretmp_31 : --> single use.
if (pretmp_31 != 6)

in the IL we have not yet updated

  _164 = MEM[(const struct gimple *)prephitmp_179].code;
  # DEBUG g => NULL
  if (_164 == 6)
    goto <bb 34>; [26.31%]
  else
    goto <bb 27>; [73.69%]

to reflect the CSE of this load to pretmp_31!


So we have basically

  _1 = *p;
  if (...)
    {
      if (_1 != 6)
        gcc_unreachable ();  // from the assert
    }
  _2 = *p;
  if (_2 != 6)
    ...

and DOM happily records [6, 6] on _1 based on its single-use and after
that DOM itself CSEs the load and optimizes the second test.

I think all_uses_feed_or_dominated_by_stmt cannot work on its own.
IIRC we have another duplicate of this somewhere.
We have to make sure that the definition is post-dominated by the
condition as well.

Reply via email to