diff options
author | ywenc <[email protected]> | 2025-06-30 15:26:23 -0400 |
---|---|---|
committer | Takashi Kokubun <[email protected]> | 2025-06-30 17:04:15 -0700 |
commit | 03e08a946d498e75e1bb31ddb28fc012dc4694f5 (patch) | |
tree | 7ced9e9cb038754b9d441e31513b484c8fbbc907 | |
parent | 4a7d1a7062e7802eb6758bab121eecde59b19125 (diff) |
ZJIT: Add codegen for IsNil
-rw-r--r-- | test/ruby/test_zjit.rb | 9 | ||||
-rw-r--r-- | zjit/src/codegen.rs | 8 |
2 files changed, 17 insertions, 0 deletions
diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb index 823fb8e043..e7ce1e1837 100644 --- a/test/ruby/test_zjit.rb +++ b/test/ruby/test_zjit.rb @@ -831,6 +831,15 @@ class TestZJIT < Test::Unit::TestCase }, call_threshold: 2 end + def test_branchnil + assert_compiles '[2, nil]', %q{ + def test(x) + x&.succ + end + [test(1), test(nil)] + }, call_threshold: 1, insns: [:branchnil] + end + # tool/ruby_vm/views/*.erb relies on the zjit instructions a) being contiguous and # b) being reliably ordered after all the other instructions. def test_instruction_order diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index 4c1d9698ac..d7d3cb8aca 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -272,6 +272,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio Insn::FixnumLe { left, right } => gen_fixnum_le(asm, opnd!(left), opnd!(right))?, Insn::FixnumGt { left, right } => gen_fixnum_gt(asm, opnd!(left), opnd!(right))?, Insn::FixnumGe { left, right } => gen_fixnum_ge(asm, opnd!(left), opnd!(right))?, + Insn::IsNil { val } => gen_isnil(asm, opnd!(val))?, Insn::Test { val } => gen_test(asm, opnd!(val))?, Insn::GuardType { val, guard_type, state } => gen_guard_type(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state))?, Insn::GuardBitEquals { val, expected, state } => gen_guard_bit_equals(jit, asm, opnd!(val), *expected, &function.frame_state(*state))?, @@ -890,6 +891,13 @@ fn gen_fixnum_ge(asm: &mut Assembler, left: lir::Opnd, right: lir::Opnd) -> Opti Some(asm.csel_ge(Qtrue.into(), Qfalse.into())) } +// Compile val == nil +fn gen_isnil(asm: &mut Assembler, val: lir::Opnd) -> Option<lir::Opnd> { + asm.cmp(val, Qnil.into()); + // TODO: Implement and use setcc + Some(asm.csel_e(Opnd::Imm(1), Opnd::Imm(0))) +} + fn gen_anytostring(asm: &mut Assembler, val: lir::Opnd, str: lir::Opnd, state: &FrameState) -> Option<lir::Opnd> { // Save PC gen_save_pc(asm, state); |