https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88714
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |ktkachov at gcc dot gnu.org,
| |ramana at gcc dot gnu.org,
| |rearnsha at gcc dot gnu.org
--- Comment #19 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
To me, this looks like buggy arm peephole2.
In *.compgotos pass we have:
(insn 96 95 97 18 (set (mem/f:SI (plus:SI (reg/v/f:SI 4 r4 [orig:137 vr_ ]
[137])
(const_int 12 [0xc])) [12 MEM[(struct vn_reference_s
*)vr__23(D)].vuse+0 S4 A32])
(reg/v/f:SI 12 ip [orig:135 vuse ] [135]))
"/tmp/tree-ssa-sccvn.ii":87248:12 650 {*arm_movsi_vfp}
(expr_list:REG_DEAD (reg/v/f:SI 12 ip [orig:135 vuse ] [135])
(expr_list:REG_DEAD (reg/v/f:SI 4 r4 [orig:137 vr_ ] [137])
(nil))))
(insn 97 96 98 18 (set (reg/f:SI 3 r3 [orig:118 _11 ] [118])
(mem/f:SI (plus:SI (reg/f:SI 1 r1 [orig:123 prephitmp_29 ] [123])
(const_int 12 [0xc])) [12 prephitmp_29->vuse+0 S4 A32]))
"/tmp/tree-ssa-sccvn.ii":87249:11 650 {*arm_movsi_vfp}
(nil))
(insn 98 97 99 18 (set (reg:SI 2 r2 [orig:120 _14 ] [120])
(mem:SI (plus:SI (reg/f:SI 1 r1 [orig:123 prephitmp_29 ] [123])
(const_int 8 [0x8])) [4 prephitmp_29->hashcode+0 S4 A32])) 650
{*arm_movsi_vfp}
(nil))
The first stmt is the vr->vuse = ... store from vr->vuse = vuse_ssa_val (vuse);
The next two stmts load vr->hashcode and vr->vuse, but unfortunately the GIMPLE
optimizers weren't able to figure out that
vr is equal to vr__23(D):
# _42 = PHI <iftmp.125_55(16), vuse_26(D)(7)>
# prephitmp_29 = PHI <pretmp_64(16), vr__23(D)(7)>
MEM[(struct vn_reference_s *)vr__23(D)].vuse = _42;
_11 = prephitmp_29->vuse;
pretmp_49 = prephitmp_29->hashcode;
at that point (note, vr is address taken variable).
Then comes peephole2 and does:
Splitting with gen_peephole2_11
scanning new insn with uid = 217.
deleting insn with uid = 98.
deleting insn with uid = 97.
verify found no changes in insn with uid = 217.
and constructs
(insn 96 95 217 18 (set (mem/f:SI (plus:SI (reg/v/f:SI 4 r4 [orig:137 vr_ ]
[137])
(const_int 12 [0xc])) [12 MEM[(struct vn_reference_s
*)vr__23(D)].vuse+0 S4 A32])
(reg/v/f:SI 12 ip [orig:135 vuse ] [135]))
"/tmp/tree-ssa-sccvn.ii":87248:12 650 {*arm_movsi_vfp}
(expr_list:REG_DEAD (reg/v/f:SI 12 ip [orig:135 vuse ] [135])
(expr_list:REG_DEAD (reg/v/f:SI 4 r4 [orig:137 vr_ ] [137])
(nil))))
(insn 217 96 99 18 (set (reg:DI 2 r2)
(mem:DI (plus:SI (reg/f:SI 1 r1 [orig:123 prephitmp_29 ] [123])
(const_int 8 [0x8])) [4 prephitmp_29->hashcode+0 S8 A32])) -1
(nil))
out of this. The insn 217 is a ldrd. The bug is that the DImode MEM uses the
same MEM_ALIAS_SET and same MEM_EXPR as
that of the SImode prephitmp_29->hashcode read, even when it now covers two
fields of the structure. So, either it needs to throw away MEM_EXPR and clear
MEM_ALIAS_SET, or find something conservatively correct covering both.
Finally, sched2 comes and swaps the two, because the (incorrect) aliasing info
makes alias.c believe it can swap the two:
(insn:TI 217 116 96 12 (set (reg:DI 2 r2)
(mem:DI (plus:SI (reg/f:SI 1 r1 [orig:123 prephitmp_29 ] [123])
(const_int 8 [0x8])) [4 prephitmp_29->hashcode+0 S8 A32])) 652
{*movdi_vfp}
(nil))
(insn:TI 96 217 109 12 (set (mem/f:SI (plus:SI (reg/v/f:SI 4 r4 [orig:137 vr_ ]
[137])
(const_int 12 [0xc])) [12 MEM[(struct vn_reference_s
*)vr__23(D)].vuse+0 S4 A32])
(reg/v/f:SI 12 ip [orig:135 vuse ] [135]))
"/tmp/tree-ssa-sccvn.ii":87248:12 650 {*arm_movsi_vfp}
(expr_list:REG_DEAD (reg/v/f:SI 12 ip [orig:135 vuse ] [135])
(expr_list:REG_DEAD (reg/v/f:SI 4 r4 [orig:137 vr_ ] [137])
(nil))))
and thus, instead of using the new vr->vuse value for the vr->hashcode
computation we use the old one.