Skip to content

Commit

Permalink
YJIT: Optimize cmp REG, 0 into test REG, REG (#7471)
Browse files Browse the repository at this point in the history
  • Loading branch information
k0kubun committed Mar 9, 2023
1 parent 3926ad5 commit 22d8e95
Showing 1 changed file with 31 additions and 2 deletions.
33 changes: 31 additions & 2 deletions yjit/src/backend/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,29 @@ impl Assembler
*out = asm.next_opnd_out(Opnd::match_num_bits(&[*left, *right]));
asm.push_insn(insn);
},
Insn::Cmp { left, right } |
Insn::Cmp { left, right } => {
// Replace `cmp REG, 0` (4 bytes) with `test REG, REG` (3 bytes)
// when next IR is `je`, `jne`, `csel_e`, or `csel_ne`
match (&left, &right, iterator.peek()) {
(Opnd::InsnOut { .. },
Opnd::UImm(0) | Opnd::Imm(0),
Some(Insn::Je(_) | Insn::Jne(_) | Insn::CSelE { .. } | Insn::CSelNE { .. })) => {
asm.push_insn(Insn::Test { left: *left, right: *left });
}
_ => {
if let (Opnd::Mem(_), Opnd::Mem(_)) = (&left, &right) {
let loaded = asm.load(*right);
*right = loaded;
}
asm.push_insn(insn);
}
}
},
Insn::Test { left, right } => {
if let (Opnd::Mem(_), Opnd::Mem(_)) = (&left, &right) {
let loaded = asm.load(*right);
*right = loaded;
}

asm.push_insn(insn);
},
// These instructions modify their input operand in-place, so we
Expand Down Expand Up @@ -943,4 +959,17 @@ mod tests {
asm.compile_with_num_regs(&mut cb, 1);
assert_eq!(format!("{:x}", cb), "488d4308488903");
}

#[test]
fn test_replace_cmp_0() {
let (mut asm, mut cb) = setup_asm();

let val = asm.load(Opnd::mem(64, SP, 8));
asm.cmp(val, 0.into());
let result = asm.csel_e(Qtrue.into(), Qfalse.into());
asm.mov(Opnd::Reg(RAX_REG), result);
asm.compile_with_num_regs(&mut cb, 2);

assert_eq!(format!("{:x}", cb), "488b43084885c0b814000000b900000000480f45c14889c0");
}
}

0 comments on commit 22d8e95

Please sign in to comment.