Skip to content

Commit ddef6a7

Browse files
committed
Split LHS of CMP if it's an immediate (Shopify/zjit#94)
1 parent bfe7da0 commit ddef6a7

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

test/ruby/test_zjit.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,14 @@ def test(a, b) = a < b
147147
}, call_threshold: 2
148148
end
149149

150+
def test_opt_lt_with_literal_lhs
151+
assert_compiles '[false, false, true]', %q{
152+
def test(n) = 2 < n
153+
test(2) # profile opt_lt
154+
[test(1), test(2), test(3)]
155+
}, call_threshold: 2
156+
end
157+
150158
def test_opt_le
151159
assert_compiles '[true, true, false]', %q{
152160
def test(a, b) = a <= b

zjit/src/backend/x86_64/mod.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,17 @@ impl Assembler
202202
asm.push_insn(Insn::Test { left: *left, right: *left });
203203
}
204204
_ => {
205-
if let (Opnd::Mem(_), Opnd::Mem(_)) = (&left, &right) {
206-
let loaded = asm.load(*right);
207-
*right = loaded;
205+
// Split the instruction if `cmp` can't be encoded with given operands
206+
match (&left, &right) {
207+
// One of the operands should not be a memory operand
208+
(Opnd::Mem(_), Opnd::Mem(_)) => {
209+
*right = asm.load(*right);
210+
}
211+
// The left operand needs to be either a register or a memory operand
212+
(Opnd::UImm(_) | Opnd::Imm(_), _) => {
213+
*left = asm.load(*left);
214+
}
215+
_ => {},
208216
}
209217
asm.push_insn(insn);
210218
}

0 commit comments

Comments
 (0)