Skip to content

Commit 81515ac

Browse files
authored
ZJIT: Fix fixnum folding for negative values (ruby#13942)
Use `fixnum_from_isize` instead of `fixnum_from_usize` in `fold_fixnum_bop` to properly handle negative values. Casting negative `i64` to `usize` produces large unsigned values that exceed `RUBY_FIXNUM_MAX`.
1 parent 30b1368 commit 81515ac

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

test/.excludes-zjit/TestTime.rb

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/.excludes-zjit/TestTimeTZ.rb

Lines changed: 0 additions & 1 deletion
This file was deleted.

zjit/src/hir.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1703,7 +1703,7 @@ impl Function {
17031703
fn fold_fixnum_bop(&mut self, insn_id: InsnId, left: InsnId, right: InsnId, f: impl FnOnce(Option<i64>, Option<i64>) -> Option<i64>) -> InsnId {
17041704
f(self.type_of(left).fixnum_value(), self.type_of(right).fixnum_value())
17051705
.filter(|&n| n >= (RUBY_FIXNUM_MIN as i64) && n <= RUBY_FIXNUM_MAX as i64)
1706-
.map(|n| self.new_insn(Insn::Const { val: Const::Value(VALUE::fixnum_from_usize(n as usize)) }))
1706+
.map(|n| self.new_insn(Insn::Const { val: Const::Value(VALUE::fixnum_from_isize(n as isize)) }))
17071707
.unwrap_or(insn_id)
17081708
}
17091709

@@ -5191,6 +5191,24 @@ mod opt_tests {
51915191
"#]]);
51925192
}
51935193

5194+
#[test]
5195+
fn test_fold_fixnum_sub_large_negative_result() {
5196+
eval("
5197+
def test
5198+
0 - 1073741825
5199+
end
5200+
");
5201+
assert_optimized_method_hir("test", expect![[r#"
5202+
fn test@<compiled>:3:
5203+
bb0(v0:BasicObject):
5204+
v2:Fixnum[0] = Const Value(0)
5205+
v3:Fixnum[1073741825] = Const Value(1073741825)
5206+
PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_MINUS)
5207+
v9:Fixnum[-1073741825] = Const Value(-1073741825)
5208+
Return v9
5209+
"#]]);
5210+
}
5211+
51945212
#[test]
51955213
fn test_fold_fixnum_mult() {
51965214
eval("

0 commit comments

Comments
 (0)