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])))