ZJIT: Fix "memory operand with non-register base" (#14153)

This commit is contained in:
Takashi Kokubun 2025-08-08 11:24:39 -07:00 committed by GitHub
parent 8eb26ebf91
commit eb931a09c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 20 additions and 2 deletions

View file

@ -111,7 +111,7 @@ impl Opnd
})
},
_ => unreachable!("memory operand with non-register base")
_ => unreachable!("memory operand with non-register base: {base:?}")
}
}

View file

@ -1088,9 +1088,15 @@ fn gen_guard_type(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, guard
} else if let Some(expected_class) = guard_type.runtime_exact_ruby_class() {
asm_comment!(asm, "guard exact class for non-immediate types");
let side_exit = side_exit(jit, state, GuardType(guard_type))?;
// If val isn't in a register, load it to use it as the base of Opnd::mem later.
// TODO: Max thinks codegen should not care about the shapes of the operands except to create them. (Shopify/ruby#685)
let val = match val {
Opnd::Reg(_) | Opnd::VReg { .. } => val,
_ => asm.load(val),
};
// Check if it's a special constant
let side_exit = side_exit(jit, state, GuardType(guard_type))?;
asm.test(val, (RUBY_IMMEDIATE_MASK as u64).into());
asm.jnz(side_exit.clone());