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

--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
The issue is how we value-number for tail-merging.  We do

Processing block 1: BB4
Value numbering stmt = MEM[(long int *)_3] = 2;
RHS 2 simplified to 2
No store match
Value numbering store MEM[(long int *)_3] to 2
Setting value number of .MEM_12 to .MEM_12 (changed)
marking outgoing edge 4 -> 5 executable
Processing block 2: BB3
Value numbering stmt = *_3 = 2;
RHS 2 simplified to 2
Setting value number of .MEM_11 to .MEM_12 (changed)
marking outgoing edge 3 -> 5 executable
Processing block 3: BB5
Value numbering stmt = .MEM_10 = PHI <.MEM_11(3), .MEM_12(4)>
Setting value number of .MEM_10 to .MEM_12 (changed)
Value numbering stmt = _9 = *p_5(D);
Setting value number of _9 to 1 (changed)

oops.  So we figure that the two stores from '2' are "redundant" which causes
us to only consider one (the wrong one) when later looking up *p_5(D).

That's

  if (!resultsame)
    {
      /* Only perform the following when being called from PRE
         which embeds tail merging.  */
      if (default_vn_walk_kind == VN_WALK)
        {
          assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
          vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false);
          if (vnresult)
            {
              VN_INFO (vdef)->visited = true;
              return set_ssa_val_to (vdef, vnresult->result_vdef);
            }

that's a case I never understood fully (and that seems wrong).  That
visited flag set is also odd.

I'm testing a patch.

Reply via email to