Index: priv/host-generic/reg_alloc2.c =================================================================== --- priv/host-generic/reg_alloc2.c (revision 1849) +++ priv/host-generic/reg_alloc2.c (working copy) @@ -1034,6 +1034,51 @@ range ends here and the dst's live range starts here, bind the dst to the src's rreg, and that's all. */ if ( (*isMove)( instrs_in->arr[ii], &vregS, &vregD ) ) { + + /* kill 'MOV v, r' if v is mapped to r */ + if (hregIsVirtual(vregS) && !hregIsVirtual(vregD)) { + Short rregno; + + k = hregNumber(vregS); + rregno = vreg_state[k]; + + if (IS_VALID_RREGNO(rregno) && rreg_state[rregno].rreg == vregD) { +# if DEBUG_REGALLOC + vex_printf("remove redundant 'MOV v, r': "); + (*ppReg)(vregS); + vex_printf(" -> "); + (*ppReg)(vregD); + vex_printf("\n\n"); +# endif + + j = rreg_lrs_la_next; + if (rreg_lrs_la[j].live_after < (ii+1) && + (ii+1) < rreg_lrs_la[j].dead_before && + rreg_lrs_la[j].rreg == vregD) { + + if (vreg_lrs[k].dead_before > ii && !rreg_state[rregno].eq_spill_slot) { + EMIT_INSTR( (*genSpill)( rreg_state[rregno].rreg, + vreg_lrs[k].spill_offset, + mode64 ) ); + } + + rreg_state[rregno].disp = Unavail; + rreg_state[rregno].vreg = INVALID_HREG; + rreg_state[rregno].eq_spill_slot = False; + vreg_state[k] = INVALID_RREG_NO; + rreg_lrs_la_next++; + } + +# if DEBUG_REGALLOC + vex_printf("State after redundant removal:\n"); + PRINT_STATE; + vex_printf("\n"); +# endif + + continue; + } + } + if (!hregIsVirtual(vregS)) goto cannot_coalesce; if (!hregIsVirtual(vregD)) goto cannot_coalesce; /* Check that *isMove is not telling us a bunch of lies ... */