https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93946
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
OK, so the fix works but on x86_64 with -m32 RTL opts (sched2) end up wrecking
things...
foo:
.LFB0:
.cfi_startproc
movl 4(%esp), %eax
movl 8(%esp), %edx
movl $1, (%eax)
movl (%eax), %eax
movl $0, (%edx)
movl $0, 4(%edx)
ret
(insn:TI 7 18 10 2 (set (mem/j:SI (reg/v/f:SI 0 ax [orig:83 bv ] [83]) [1
bv_3(D)->b.u.f+0 S4 A32])
(const_int 1 [0x1]))
"/space/rguenther/src/gcc/gcc/testsuite/gcc.dg/torture/pr93946-1.c":14:13 67
{*movsi_internal}
(nil))
(insn 18 7 20 2 (set (reg/v/f:SI 1 dx [orig:84 ptr ] [84])
(mem/f/c:SI (plus:SI (reg/f:SI 7 sp)
(const_int 8 [0x8])) [9 ptr+0 S4 A32]))
"/space/rguenther/src/gcc/gcc/testsuite/gcc.dg/torture/pr93946-1.c":15:12 67
{*movsi_internal}
(expr_list:REG_EQUIV (mem/f/c:SI (plus:SI (reg/f:SI 16 argp)
(const_int 4 [0x4])) [9 ptr+0 S4 A32])
(nil)))
(insn:TI 20 10 21 2 (set (mem/j:SI (reg/v/f:SI 1 dx [orig:84 ptr ] [84]) [1
MEM[(struct aa *)ptr_1(D)].a.u.i+0 S4 A32])
(const_int 0 [0]))
"/space/rguenther/src/gcc/gcc/testsuite/gcc.dg/torture/pr93946-1.c":15:12 67
{*movsi_internal}
(nil))
(insn:TI 21 20 16 2 (set (mem/j:SI (plus:SI (reg/v/f:SI 1 dx [orig:84 ptr ]
[84])
(const_int 4 [0x4])) [1 MEM[(struct aa *)ptr_1(D)].a.u.i+4 S4
A32])
(const_int 0 [0]))
"/space/rguenther/src/gcc/gcc/testsuite/gcc.dg/torture/pr93946-1.c":15:12 67
{*movsi_internal}
(expr_list:REG_DEAD (reg/v/f:SI 1 dx [orig:84 ptr ] [84])
(nil)))
(insn 10 7 20 2 (set (reg:SI 0 ax [orig:86 bv_3(D)->b.u.f ] [86])
(mem/j:SI (reg/v/f:SI 0 ax [orig:83 bv ] [83]) [1 bv_3(D)->b.u.f+0 S4
A32]))
"/space/rguenther/src/gcc/gcc/testsuite/gcc.dg/torture/pr93946-1.c":17:17 67
{*movsi_internal}
(nil))
Ah, something dropped the store to b.u.f and split the store to i. DSE.
Obviously.
pr93946-1.c.263r.dse1: processing cselib load against insn 9
pr93946-1.c.263r.dse1:Locally deleting insn 9 because insn 8 stores the same
value and couldn't be eliminated
pr93946-1.c.263r.dse1:Locally deleting insn 9
indeed I remember touching DSE back in time. It still only does
/* We can only remove the later store if the earlier aliases
at least all accesses the later one. */
&& (MEM_ALIAS_SET (mem) == MEM_ALIAS_SET (s_info->mem)
|| alias_set_subset_of (MEM_ALIAS_SET (mem),
MEM_ALIAS_SET (s_info->mem))))
not considering the base set of the other store. Now, we could allow
the DSE by clearing MEM_EXPR here or adjusting MEM_ALIAS_SET. But not
sure if we want that?