https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87871
--- Comment #12 from Segher Boessenkool <segher at gcc dot gnu.org> --- (In reply to Segher Boessenkool from comment #11) > (In reply to Wilco from comment #8) > > mov r4, r0 > > cmp r4, #0 > > Why does it copy r0 to r4 and then compare r4? On more modern machines it > is faster to compare r0 itself, and it would allow shrink-wrapping to work > fine here We get this in combine: Trying 2 -> 7: 2: r112:SI=r116:SI REG_DEAD r116:SI 7: cc:CC=cmp(r112:SI,0) Successfully matched this instruction: (parallel [ (set (reg:CC 100 cc) (compare:CC (reg:SI 116) (const_int 0 [0]))) (set (reg/v:SI 112 [ a ]) (reg:SI 116)) ]) (that's *movsi_compare0). This is preceded by (insn 50 3 7 2 (set (reg:SI 116) (reg:SI 0 r0 [ a ])) "ira-shrinkwrap-prep-1.c":14:1 179 {*arm_movsi_insn} (nil)) And it stays that way until IRA, which does Disposition: 0:r111 l0 0 3:r112 l0 4 1:r113 l0 2 2:r114 l0 3 5:r116 l0 4 4:r117 l0 0 If r116 had been allocated hard reg 0 all would be fine (and we know r116 dies in insn 7 already, there is a REG_DEAD note on it).