https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86771
Wilco <wilco at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2018-08-20 CC| |wilco at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #13 from Wilco <wilco at gcc dot gnu.org> --- (In reply to nsz from comment #12) > the wrong string seems to be caused by a missing ldm Yes what happens is that it decides to combine instruction 150 and 190 and split an ldm2: insn_cost 4 for 150: r197:SI=sfp:SI-0x24 ... insn_cost 0 for 190: {r0:SI=[r197:SI];r1:SI=[r197:SI+0x4];} allowing combination of insns 150 and 190 original costs 4 + 0 = 0 replacement costs 8 + 8 = 16 modifying insn i2 150: r0:SI=[sfp:SI-0x24] deferring rescan insn with uid = 150. modifying insn i3 190: r1:SI=[sfp:SI-0x20] deferring rescan insn with uid = 190. There are lots of instructions between 150 and 190, including another ldm2 which writes r0: 150: r0:SI=[sfp:SI-0x24] ... 163: {r0:SI=[r206:SI];r1:SI=[r206:SI+0x4];} ... 190: r1:SI=[sfp:SI-0x20] The combination ends up corrupting r0 because one of the loads is lifted across many instructions without checking liveness. It seems the safest way to split an instruction is to place the new instructions next to each other.