diff options
| author | Alan Wu <XrXr@users.noreply.github.com> | 2025-07-15 20:13:53 -0400 |
|---|---|---|
| committer | Alan Wu <XrXr@users.noreply.github.com> | 2025-07-16 14:10:22 -0400 |
| commit | 0c26dea5bb49ab98d2248f02cbbae82393a3c844 (patch) | |
| tree | f697688c7da523212c7494c2571dec7fbde7ff67 | |
| parent | 7df8e9e4276afd9f14a6b6d650b8031de1dd8408 (diff) | |
ZJIT: A64: Fix the optimization merging `asm.add(reg, imm)` with Mov
The raw bytes didn't disassemble to the disassembly, but we missed this
since CI didn't run `make zjit-test` with the disasm feature.
Fixes: 1317377fa74 ("ZJIT: A64: Have add/sub to SP be
single-instruction")
| -rw-r--r-- | zjit/src/backend/arm64/mod.rs | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/zjit/src/backend/arm64/mod.rs b/zjit/src/backend/arm64/mod.rs index db4fc5f710..25b0a525fd 100644 --- a/zjit/src/backend/arm64/mod.rs +++ b/zjit/src/backend/arm64/mod.rs @@ -421,13 +421,16 @@ impl Assembler (Opnd::Reg(_) | Opnd::VReg { .. }, Opnd::Reg(_) | Opnd::VReg { .. }) => { merge_three_reg_mov(&live_ranges, &mut iterator, left, right, out); asm.push_insn(insn); - }, + } (reg_opnd @ (Opnd::Reg(_) | Opnd::VReg { .. }), other_opnd) | (other_opnd, reg_opnd @ (Opnd::Reg(_) | Opnd::VReg { .. })) => { *left = reg_opnd; *right = split_shifted_immediate(asm, other_opnd); + // Now `right` is either a register or an immediate, both can try to + // merge with a subsequent mov. + merge_three_reg_mov(&live_ranges, &mut iterator, left, left, out); asm.push_insn(insn); - }, + } _ => { *left = split_load_operand(asm, *left); *right = split_shifted_immediate(asm, *right); @@ -1381,12 +1384,12 @@ mod tests { asm.mov(sp, new_sp); let new_sp = asm.sub(sp, 0x20.into()); asm.mov(sp, new_sp); - asm.compile_with_num_regs(&mut cb, 2); - assert_disasm!(cb, "e08300b11f000091e08300f11f000091", {" + asm.compile_with_num_regs(&mut cb, 2); + assert_disasm!(cb, "ff830091ff8300d1", " 0x0: add sp, sp, #0x20 0x4: sub sp, sp, #0x20 - "}); + "); } #[test] |
