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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2025-08-02
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org
             Status|UNCONFIRMED                 |ASSIGNED

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
FRE1 gets to see

  struct s3 * t;
  struct s1 tmp;
  struct s2 c;
  int _1;
  int _2;

  __BB(2):
  tmp.t = a_4(D);
  tmp.t1 = b_6(D);
  __MEM <struct s3> ((struct s3 *)&c).t = tmp;  (*)
  tmp ={v} _Literal (struct s1) {CLOBBER(eos)};
  _1 = c.t.t.t1;
  _2 = c.t.t.t;
  f (_2, _1);
  c ={v} _Literal (struct s2) {CLOBBER(eos)};

and when at (*) we try to match up

{component_ref<t1>,component_ref<t>,component_ref<t>,mem_ref<0B>,addr_expr<&c>}

with

{component_ref<t>,mem_ref<0B>,addr_expr<&c>}

and the only match we have is the addr_expr, so we didn't fully consume
__MEM <struct s3> ((struct s3 *)&c).t, meaning that's not a base of
the reference looked up.

The

      /* ???  The innermost op should always be a MEM_REF and we already
         checked that the assignment to the lhs kills vr.  Thus for
         aggregate copies using char[] types the vn_reference_op_eq
         may fail when comparing types for compatibility.  But we really
         don't care here - further lookups with the rewritten operands
         will simply fail if we messed up types too badly.  */
      poly_int64 extra_off = 0;
      if (j == 0 && i >= 0
          && lhs_ops[0].opcode == MEM_REF
          && maybe_ne (lhs_ops[0].off, -1))
        {
          if (known_eq (lhs_ops[0].off, vr->operands[i].off))
            i--, j--;
          else if (vr->operands[i].opcode == MEM_REF
                   && maybe_ne (vr->operands[i].off, -1))
            {
              extra_off = vr->operands[i].off - lhs_ops[0].off;
              i--, j--;
            }
        }

code looks a bit confused.  I'll have to check what I added this for...

But in essence we can try to match up a sequence of zero-offset components
in a more relaxed way, and appearantly with extra_off even more.  I have
to re-familiarize myself with this.

Reply via email to