Skip to content

Commit 50f51f7

Browse files
authored
ZJIT: constant fold bitwise OR (|) operations (ruby#16235)
Continuation of ruby#16226. ### Considerations - The OR (`|`) operation in Rust has the same behavior as in Ruby (it compiles to a assembly `or` instruction: https://godbolt.org/z/5McGzj783); - There are no risk of overflows; - In the test, I added the result of the interpreter in an assertion based on feedback of my last PR.
1 parent eafbf6e commit 50f51f7

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

zjit/src/hir.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4640,6 +4640,12 @@ impl Function {
46404640
_ => None,
46414641
})
46424642
}
4643+
Insn::FixnumOr { left, right, .. } => {
4644+
self.fold_fixnum_bop(insn_id, left, right, |l, r| match (l, r) {
4645+
(Some(l), Some(r)) => Some(l | r),
4646+
_ => None,
4647+
})
4648+
}
46434649
Insn::FixnumEq { left, right, .. } => {
46444650
self.fold_fixnum_pred(insn_id, left, right, |l, r| match (l, r) {
46454651
(Some(l), Some(r)) => Some(l == r),

zjit/src/hir/opt_tests.rs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,96 @@ mod hir_opt_tests {
562562
");
563563
}
564564

565+
#[test]
566+
fn test_fold_fixnum_or() {
567+
eval("
568+
def test
569+
4 | 1
570+
end
571+
");
572+
573+
assert_snapshot!(inspect("test"), @"5");
574+
assert_snapshot!(hir_string("test"), @"
575+
fn test@<compiled>:3:
576+
bb1():
577+
EntryPoint interpreter
578+
v1:BasicObject = LoadSelf
579+
Jump bb3(v1)
580+
bb2():
581+
EntryPoint JIT(0)
582+
v4:BasicObject = LoadArg :self@0
583+
Jump bb3(v4)
584+
bb3(v6:BasicObject):
585+
v10:Fixnum[4] = Const Value(4)
586+
v12:Fixnum[1] = Const Value(1)
587+
PatchPoint MethodRedefined(Integer@0x1000, |@0x1008, cme:0x1010)
588+
v25:Fixnum[5] = Const Value(5)
589+
IncrCounter inline_cfunc_optimized_send_count
590+
CheckInterrupts
591+
Return v25
592+
");
593+
}
594+
595+
#[test]
596+
fn test_fold_fixnum_or_with_negative_self() {
597+
eval("
598+
def test
599+
-4 | 1
600+
end
601+
");
602+
603+
assert_snapshot!(inspect("test"), @"-3");
604+
assert_snapshot!(hir_string("test"), @"
605+
fn test@<compiled>:3:
606+
bb1():
607+
EntryPoint interpreter
608+
v1:BasicObject = LoadSelf
609+
Jump bb3(v1)
610+
bb2():
611+
EntryPoint JIT(0)
612+
v4:BasicObject = LoadArg :self@0
613+
Jump bb3(v4)
614+
bb3(v6:BasicObject):
615+
v10:Fixnum[-4] = Const Value(-4)
616+
v12:Fixnum[1] = Const Value(1)
617+
PatchPoint MethodRedefined(Integer@0x1000, |@0x1008, cme:0x1010)
618+
v25:Fixnum[-3] = Const Value(-3)
619+
IncrCounter inline_cfunc_optimized_send_count
620+
CheckInterrupts
621+
Return v25
622+
");
623+
}
624+
625+
#[test]
626+
fn test_fold_fixnum_or_with_negative_other() {
627+
eval("
628+
def test
629+
4 | -1
630+
end
631+
");
632+
633+
assert_snapshot!(inspect("test"), @"-1");
634+
assert_snapshot!(hir_string("test"), @"
635+
fn test@<compiled>:3:
636+
bb1():
637+
EntryPoint interpreter
638+
v1:BasicObject = LoadSelf
639+
Jump bb3(v1)
640+
bb2():
641+
EntryPoint JIT(0)
642+
v4:BasicObject = LoadArg :self@0
643+
Jump bb3(v4)
644+
bb3(v6:BasicObject):
645+
v10:Fixnum[4] = Const Value(4)
646+
v12:Fixnum[-1] = Const Value(-1)
647+
PatchPoint MethodRedefined(Integer@0x1000, |@0x1008, cme:0x1010)
648+
v25:Fixnum[-1] = Const Value(-1)
649+
IncrCounter inline_cfunc_optimized_send_count
650+
CheckInterrupts
651+
Return v25
652+
");
653+
}
654+
565655
#[test]
566656
fn test_fold_fixnum_less() {
567657
eval("

0 commit comments

Comments
 (0)