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