Comment 30 for bug 705689

Revision history for this message
Richard Sandiford (rsandifo) wrote :

Thanks to Dave for the excellent debugging work here, pinpointing the RTL instruction that wrongly gets deleted.

The instruction is being deleted by a delete_trivially_dead_insns call during IRA. Surprisingly for such an old function, the bug seems to be in d_t_d_i itself. count_reg_usage counts out how many times each register is used in the entire function, but it tries to ignore uses in self-modifications of the form (set (reg A) (... (reg A) ...)). The problem is that it is ignoring such uses even if the insn has side effects (in this case, an access to volatile memory). insn_live_p rightly returns true for such insns, regardless of register counts, so we end up keeping the self-modification but deleting the instruction that sets its input.

count_reg_usage is set up to predict when insn_live_p would always return true regardless of register usage. It is doing this correctly for instructions that might throw an exception, and for volatile asms. But it is failing to do it for other side-effects that insn_live_p detects. These include volatile MEMs and pre-/post-modifications.

The attached patch seems to fix things (tested on the Linaro sources rather than Ubuntu). I'll run it through a full test cycle.

This is another reason why the CSE code should be using the DF machinery rather than such an ad-hoc approach.