https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79671
--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Bernd Edlinger from comment #12) > Hi, > > I don't know if it helps, but on the assembler level there are only two > instructions that need to be moved to make the test case pass: That of course helps a lot, that is what I was trying to narrow through the hacks. Before sched1 there is: (insn 598 595 1707 67 (set (mem/c:QI (plus:SI (reg/f:SI 102 sfp) (const_int -19 [0xffffffffffffffed])) [98 MEM[(struct parser_binder *)&D.616009 + 5B]+0 S1 A8]) (subreg:QI (reg:SI 505) 0)) 192 {*arm_movqi_insn} (expr_list:REG_DEAD (reg:SI 505) (nil))) ... (insn 604 603 605 67 (set (reg/f:SI 692) (plus:SI (reg/f:SI 102 sfp) (const_int -20 [0xffffffffffffffec]))) "/usr/include/boost/function/function_template.hpp":998 4 {*arm_addsi3} (nil)) (insn 605 604 606 67 (parallel [ (set (reg:SI 0 r0) (mem/c:SI (reg/f:SI 692) [19 MEM[(struct function4 *)&D.616009].D.542442.functor+0 S4 A32])) (set (reg:SI 1 r1) (mem/c:SI (plus:SI (reg/f:SI 692) (const_int 4 [0x4])) [19 MEM[(struct function4 *)&D.616009].D.542442.functor+4 S4 A32])) (set (reg:SI 2 r2) (mem/c:SI (plus:SI (reg/f:SI 692) (const_int 8 [0x8])) [19 MEM[(struct function4 *)&D.616009].D.542442.functor+8 S4 A32])) ]) "/usr/include/boost/function/function_template.hpp":998 364 {*ldm3_} (nil)) (current trunk, the above command line options, no patches), so ignoring strict aliasing, there is a must alias in between the middle mem in insn 605 and the mem insn 598 stores to. Now if I do: break sched_analyze_2 if x->code == MEM && insn->u2.insn_uid == 605 run continue then x is: (mem/c:SI (plus:SI (reg/f:SI 692) (const_int 4 [0x4])) [19 MEM[(struct function4 *)&D.616009].D.542442.functor+4 S4 A32]) and deps->pending_write_mems is: (expr_list:REG_DEP_TRUE (mem/f/c:SI (plus:SI (reg/f:SI 102 sfp) (const_int -264 [0xfffffffffffffef8])) [18 tmp.D.542442.vtable+0 S4 A64]) (expr_list:REG_DEP_TRUE (mem/c:QI (plus:SI (reg/f:SI 102 sfp) (const_int -19 [0xffffffffffffffed])) [98 MEM[(struct parser_binder *)&D.616009 + 5B]+0 S1 A8]) (nil))) This then calls true_dependence with mem: (mem/c:QI (plus:SI (reg/f:SI 102 sfp) (const_int -19 [0xffffffffffffffed])) [98 MEM[(struct parser_binder *)&D.616009 + 5B]+0 S1 A8]) x: (mem/c:SI (plus:SI (reg/f:SI 692) (const_int 4 [0x4])) [19 MEM[(struct function4 *)&D.616009].D.542442.functor+4 S4 A32]) and we return 0 because of: 2931 if (mems_in_disjoint_alias_sets_p (x, mem)) 2932 return 0; In *.optimized dump I believe this is: MEM[(struct parser_binder *)&D.616009 + 5B] = 93; value_283 = (size_t) &stored_vtable.base; value_284 = value_283 | 1; value.75_285 = (struct vtable_base *) value_284; MEM[(struct function4 *)&D.616009].D.542442.vtable = value.75_285; MEM[(struct &)&tmp] ={v} {CLOBBER}; tmp.D.542442.vtable = value.75_285; tmp.D.542442.functor = MEM[(struct function4 *)&D.616009].D.542442.functor; insn 598 is that MEM[(struct parser_binder *)&D.616009 + 5B] = 93; and insn 605 (ldm3_) is the load for the structure assignment tmp.D.542442.functor = MEM[(struct function4 *)&D.616009].D.542442.functor; Richard, could you please have a look from the alias oracle POV?