summaryrefslogtreecommitdiff
diff options
authorStan Lo <[email protected]>2025-07-18 00:48:53 +0100
committerGitHub <[email protected]>2025-07-17 19:48:53 -0400
commit81515aca67a0d3cc50205ff0a99cdc44ed0a927d (patch)
tree04b37a363fc3c4a423f8786c916155536c36c989
parent30b1368829820721e502f4e0edcaa4de511959a8 (diff)
ZJIT: Fix fixnum folding for negative values (#13942)HEADmaster
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`.
-rw-r--r--test/.excludes-zjit/TestTime.rb1
-rw-r--r--test/.excludes-zjit/TestTimeTZ.rb1
-rw-r--r--zjit/src/hir.rs20
3 files changed, 19 insertions, 3 deletions
diff --git a/test/.excludes-zjit/TestTime.rb b/test/.excludes-zjit/TestTime.rb
deleted file mode 100644
index b2ca8c67f7..0000000000
--- a/test/.excludes-zjit/TestTime.rb
+++ /dev/null
@@ -1 +0,0 @@
-exclude(/test_/, 'Tests make ZJIT panic')
diff --git a/test/.excludes-zjit/TestTimeTZ.rb b/test/.excludes-zjit/TestTimeTZ.rb
deleted file mode 100644
index b2ca8c67f7..0000000000
--- a/test/.excludes-zjit/TestTimeTZ.rb
+++ /dev/null
@@ -1 +0,0 @@
-exclude(/test_/, 'Tests make ZJIT panic')
diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs
index fa72b569b4..41efce6624 100644
--- a/zjit/src/hir.rs
+++ b/zjit/src/hir.rs
@@ -1703,7 +1703,7 @@ impl Function {
fn fold_fixnum_bop(&mut self, insn_id: InsnId, left: InsnId, right: InsnId, f: impl FnOnce(Option<i64>, Option<i64>) -> Option<i64>) -> InsnId {
f(self.type_of(left).fixnum_value(), self.type_of(right).fixnum_value())
.filter(|&n| n >= (RUBY_FIXNUM_MIN as i64) && n <= RUBY_FIXNUM_MAX as i64)
- .map(|n| self.new_insn(Insn::Const { val: Const::Value(VALUE::fixnum_from_usize(n as usize)) }))
+ .map(|n| self.new_insn(Insn::Const { val: Const::Value(VALUE::fixnum_from_isize(n as isize)) }))
.unwrap_or(insn_id)
}
@@ -5192,6 +5192,24 @@ mod opt_tests {
}
#[test]
+ fn test_fold_fixnum_sub_large_negative_result() {
+ eval("
+ def test
+ 0 - 1073741825
+ end
+ ");
+ assert_optimized_method_hir("test", expect![[r#"
+ fn test@<compiled>:3:
+ bb0(v0:BasicObject):
+ v2:Fixnum[0] = Const Value(0)
+ v3:Fixnum[1073741825] = Const Value(1073741825)
+ PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_MINUS)
+ v9:Fixnum[-1073741825] = Const Value(-1073741825)
+ Return v9
+ "#]]);
+ }
+
+ #[test]
fn test_fold_fixnum_mult() {
eval("
def test
close