Skip to content

Commit 95eaff4

Browse files
committed
ZJIT: Annotate & method for true and false
1 parent 1225a1c commit 95eaff4

3 files changed

Lines changed: 146 additions & 0 deletions

File tree

test/ruby/test_zjit.rb

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,82 @@ def test(x, y) = x & y
323323
RUBY
324324
end
325325

326+
def test_opt_and_true_true
327+
assert_compiles 'true', %q{
328+
def test(a, b) = a & b
329+
test(true, true)
330+
test(true, true)
331+
}, call_threshold: 2, insns: [:opt_and]
332+
end
333+
334+
def test_opt_and_true_false
335+
assert_compiles 'false', %q{
336+
def test(a, b) = a & b
337+
test(true, false)
338+
test(true, false)
339+
}, call_threshold: 2, insns: [:opt_and]
340+
end
341+
342+
def test_opt_and_false_true
343+
assert_compiles 'false', %q{
344+
def test(a, b) = a & b
345+
test(false, true)
346+
test(false, true)
347+
}, call_threshold: 2, insns: [:opt_and]
348+
end
349+
350+
def test_opt_and_false_false
351+
assert_compiles 'false', %q{
352+
def test(a, b) = a & b
353+
test(false, false)
354+
test(false, false)
355+
}, call_threshold: 2, insns: [:opt_and]
356+
end
357+
358+
def test_opt_and_true_with_truthy
359+
assert_compiles 'true', %q{
360+
def test(a, b) = a & b
361+
test(true, true)
362+
test(true, 1)
363+
}, call_threshold: 2, insns: [:opt_and]
364+
end
365+
366+
def test_opt_and_true_with_falsey
367+
assert_compiles 'false', %q{
368+
def test(a, b) = a & b
369+
test(true, true)
370+
test(true, nil)
371+
}, call_threshold: 2, insns: [:opt_and]
372+
end
373+
374+
def test_opt_and_false_with_truthy
375+
assert_compiles 'false', %q{
376+
def test(a, b) = a & b
377+
test(false, true)
378+
test(false, "hi")
379+
}, call_threshold: 2, insns: [:opt_and]
380+
end
381+
382+
def test_opt_and_bool_fallthrough_to_integer
383+
assert_compiles '1', %q{
384+
def test(a, b) = a & b
385+
test(true, false)
386+
test(true, true)
387+
test(3, 1)
388+
}, call_threshold: 2, insns: [:opt_and]
389+
end
390+
391+
def test_opt_and_mixed_types_side_exit
392+
assert_compiles '[false, true, 1]', %q{
393+
def test(a, b) = a & b
394+
test(true, true)
395+
r1 = test(true, false)
396+
r2 = test(true, 1)
397+
r3 = test(3, 1)
398+
[r1, r2, r3]
399+
}, call_threshold: 2, insns: [:opt_and]
400+
end
401+
326402
def test_opt_or
327403
assert_compiles('[11, [3, 2, 1]]', <<~RUBY, insns: [:opt_or])
328404
def test(x, y) = x | y

zjit/src/cruby_methods.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ pub fn init() -> Annotations {
8282
annotate!(rb_cArray, "size", types::Fixnum, no_gc, leaf, elidable);
8383
annotate!(rb_cNilClass, "nil?", types::TrueClassExact, no_gc, leaf, elidable);
8484
annotate!(rb_mKernel, "nil?", types::FalseClassExact, no_gc, leaf, elidable);
85+
annotate!(rb_cTrueClass, "&", types::BoolExact, no_gc, leaf, elidable);
86+
annotate!(rb_cFalseClass, "&", types::FalseClassExact, no_gc, leaf, elidable);
8587

8688
Annotations {
8789
cfuncs: std::mem::take(cfuncs)

zjit/src/hir.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6787,4 +6787,72 @@ mod opt_tests {
67876787
Return v8
67886788
"#]]);
67896789
}
6790+
6791+
#[test]
6792+
fn test_guard_true_and_true() {
6793+
eval("
6794+
def test(a, b) = a & b
6795+
6796+
test(true, true)
6797+
");
6798+
assert_optimized_method_hir("test", expect![[r#"
6799+
fn test:
6800+
bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject):
6801+
PatchPoint MethodRedefined(TrueClass@0x1000, &@0x1008)
6802+
v8:TrueClassExact = GuardType v1, TrueClassExact
6803+
v9:BoolExact = CCall &@0x1010, v8, v2
6804+
Return v9
6805+
"#]]);
6806+
}
6807+
6808+
#[test]
6809+
fn test_guard_true_and_false() {
6810+
eval("
6811+
def test(a, b) = a & b
6812+
6813+
test(true, false)
6814+
");
6815+
assert_optimized_method_hir("test", expect![[r#"
6816+
fn test:
6817+
bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject):
6818+
PatchPoint MethodRedefined(TrueClass@0x1000, &@0x1008)
6819+
v8:TrueClassExact = GuardType v1, TrueClassExact
6820+
v9:BoolExact = CCall &@0x1010, v8, v2
6821+
Return v9
6822+
"#]]);
6823+
}
6824+
6825+
#[test]
6826+
fn test_guard_false_and_true() {
6827+
eval("
6828+
def test(a, b) = a & b
6829+
6830+
test(false, true)
6831+
");
6832+
assert_optimized_method_hir("test", expect![[r#"
6833+
fn test:
6834+
bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject):
6835+
PatchPoint MethodRedefined(FalseClass@0x1000, &@0x1008)
6836+
v8:FalseClassExact = GuardType v1, FalseClassExact
6837+
v9:FalseClassExact = CCall &@0x1010, v8, v2
6838+
Return v9
6839+
"#]]);
6840+
}
6841+
6842+
#[test]
6843+
fn test_guard_false_and_false() {
6844+
eval("
6845+
def test(a, b) = a & b
6846+
6847+
test(false, false)
6848+
");
6849+
assert_optimized_method_hir("test", expect![[r#"
6850+
fn test:
6851+
bb0(v0:BasicObject, v1:BasicObject, v2:BasicObject):
6852+
PatchPoint MethodRedefined(FalseClass@0x1000, &@0x1008)
6853+
v8:FalseClassExact = GuardType v1, FalseClassExact
6854+
v9:FalseClassExact = CCall &@0x1010, v8, v2
6855+
Return v9
6856+
"#]]);
6857+
}
67906858
}

0 commit comments

Comments
 (0)