summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2025-07-18 15:31:07 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2025-07-21 13:51:44 -0400
commit3bbdcf084846b8da1e2c30e7bb215a1aecccad78 (patch)
tree69c818f081c941de68927956de89398a86ae2dc6
parent495e3f642bd2efdb4479a14866610e94defb9e66 (diff)
ZJIT: Remove no-op movs after register allocation
Previously `no_dead_mov_from_vreg` generated: 0x0: ldur x0, [x0] 0x4: mov x0, x0 0x8: ret Because of phase ordering. Split couldn't recognize that the no-op mov because at that point it sees a `VReg`.
-rw-r--r--zjit/src/backend/arm64/mod.rs14
-rw-r--r--zjit/src/backend/lir.rs3
2 files changed, 17 insertions, 0 deletions
diff --git a/zjit/src/backend/arm64/mod.rs b/zjit/src/backend/arm64/mod.rs
index e97c06414d..dc5c7e6058 100644
--- a/zjit/src/backend/arm64/mod.rs
+++ b/zjit/src/backend/arm64/mod.rs
@@ -1425,6 +1425,20 @@ mod tests {
}
#[test]
+ fn no_dead_mov_from_vreg() {
+ let (mut asm, mut cb) = setup_asm();
+
+ let ret_val = asm.load(Opnd::mem(64, C_RET_OPND, 0));
+ asm.cret(ret_val);
+
+ asm.compile_with_num_regs(&mut cb, 1);
+ assert_disasm!(cb, "000040f8c0035fd6", "
+ 0x0: ldur x0, [x0]
+ 0x4: ret
+ ");
+ }
+
+ #[test]
fn test_emit_add() {
let (mut asm, mut cb) = setup_asm();
diff --git a/zjit/src/backend/lir.rs b/zjit/src/backend/lir.rs
index 94c53569b4..47ba5ddf70 100644
--- a/zjit/src/backend/lir.rs
+++ b/zjit/src/backend/lir.rs
@@ -1752,6 +1752,9 @@ impl Assembler
asm.push_insn(Insn::PosMarker(end_marker));
}
}
+ Insn::Mov { src, dest } | Insn::LoadInto { dest, opnd: src } if src == dest => {
+ // Remove no-op move now that VReg are resolved to physical Reg
+ }
_ => asm.push_insn(insn),
}