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

            Bug ID: 120329
           Summary: Combine temporarily creates paradoxical mem subregs
                    for strict-alignment targets
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dimitar at gcc dot gnu.org
  Target Milestone: ---

Investigation for PR119966 uncovered an unusual behaviour in combine.
Paradoxical mem subregs are created for aarch64 target.  But since
aarch64 is both a strict-alignment target and defines INSN_SCHEDULING,
it does not seem valid to create such paradoxical mem subregs.

To illustrate, compile the following C snippet with -O2 for aarch64:
  struct S {
    unsigned char c1;
    unsigned char c2;
  };
  unsigned test(struct S *p)
  {
    return p->c1 | p->c2;
  }

Function expand_compound_operation is called with the following insn:
  (gdb) pr x
  (zero_extend:SI (mem:QI (reg/f:SI 105 [ p ]) [0 p_5(D)->c1+0 S1 A8]))

Then the insn is transformed into paradoxical mem subreg, which does not seem
correct
for strict-alignment targets like aarch64:

  (gdb) list
  7411          tem = gen_lowpart (mode, XEXP (x, 0));
  7412          if (!tem || GET_CODE (tem) == CLOBBER)
  7413            return x;
  7414          tem = simplify_shift_const (NULL_RTX, ASHIFT, mode,
  7415                                      tem, modewidth - pos - len);
  7416          tem = simplify_shift_const (NULL_RTX, unsignedp ? LSHIFTRT :
ASHIFTRT,
  7417                                      mode, tem, modewidth - len);
  (gdb) pr tem
  (subreg:SI (mem:QI (reg/f:SI 105 [ p ]) [0 p_5(D)->c1+0 S1 A8]) 0)

This is all benign because function combine_simplify_rtx invoked in subst
eventually simplifies the paradoxical mem subreg back to zero_extend:
  (gdb) list
  5656          /* If X is sufficiently simple, don't bother trying to do
anything
  5657             with it.  */
  5658          if (code != CONST_INT && code != REG && code != CLOBBER)
  5659            x = combine_simplify_rtx (x, op0_mode, in_dest, in_cond);
  5660
  5661          if (GET_CODE (x) == code)
  5662            break;
  5663
  (gdb) pr x
  (set (reg:SI 101 [ p_5(D)->c1 ])
      (subreg:SI (mem:QI (reg/f:SI 105 [ p ]) [0 p_5(D)->c1+0 S1 A8]) 0))
  (gdb) next
  5661          if (GET_CODE (x) == code)
  (gdb) pr x
  (set (reg:SI 101 [ p_5(D)->c1 ])
      (zero_extend:SI (mem:QI (reg/f:SI 105 [ p ]) [0 p_5(D)->c1+0 S1 A8])))

Reply via email to