diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index ef4bfa9961..36e48238b4 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -2143,7 +2143,13 @@ (let ([test-if-if-reduction (lambda (dup) (test-comp `(lambda (x y z) (if (if x y #f) z ,dup)) - `(lambda (x y z) (if x (if y z ,dup) ,dup))))]) + `(lambda (x y z) (if x (if y z ,dup) ,dup))) + (test-comp `(lambda (x y z) (if (if x #f y) z ,dup)) + `(lambda (x y z) (if x ,dup (if y z ,dup)))) + (test-comp `(lambda (x y z) (if (if x y #t) ,dup z)) + `(lambda (x y z) (if x (if y ,dup z) ,dup))) + (test-comp `(lambda (x y z) (if (if x #t y) ,dup z)) + `(lambda (x y z) (if x ,dup (if y ,dup z)))))]) (test-if-if-reduction 1) (test-if-if-reduction ''x) (test-if-if-reduction "x") diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index 32c0ee5a82..b66f9ccf12 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -5720,23 +5720,45 @@ static Scheme_Object *optimize_branch(Scheme_Object *o, Optimize_Info *info, int return t; } - /* Convert: (if (if M N #f) M2 K) => (if M (if N M2 K) K) + /* Convert: expressions like + (if (if M N #f) P K) => (if M (if N P K) K) for simple constants K. This is useful to expose simple tests to the JIT. */ - if (SAME_TYPE(SCHEME_TYPE(t), scheme_branch_type) - && scheme_ir_duplicate_ok(fb, 0)) { + if (SAME_TYPE(SCHEME_TYPE(t), scheme_branch_type)) { Scheme_Branch_Rec *b2 = (Scheme_Branch_Rec *)t; - if (SCHEME_FALSEP(b2->fbranch)) { - Scheme_Object *fb3; - Scheme_Branch_Rec *b3; - b3 = MALLOC_ONE_TAGGED(Scheme_Branch_Rec); - b3->so.type = scheme_branch_type; - b3->test = b2->tbranch; - b3->tbranch = tb; - fb3 = optimize_clone(0, fb, info, empty_eq_hash_tree, 0); - b3->fbranch = fb3; + Scheme_Object *ntb, *nfb, *nt2 = NULL; + if (SCHEME_FALSEP(b2->fbranch) + && scheme_ir_duplicate_ok(fb, 0)) { + /* (if (if M N #f) P K) => (if M (if N P K) K) */ + ntb = (Scheme_Object *)b2; + nfb = optimize_clone(0, fb, info, empty_eq_hash_tree, 0); + nt2 = b2->tbranch; + } else if (SCHEME_FALSEP(b2->tbranch) + && scheme_ir_duplicate_ok(fb, 0)) { + /* (if (if M #f N) P K) => (if M K (if N P K)) */ + ntb = optimize_clone(0, fb, info, empty_eq_hash_tree, 0); + nfb = (Scheme_Object *)b2; + nt2 = b2->fbranch; + } else if (SAME_OBJ(b2->fbranch, scheme_true) + && scheme_ir_duplicate_ok(tb, 0)) { + /* (if (if M N #t) K P) => (if M (if N K P) K) */ + ntb = (Scheme_Object *)b2; + nfb = optimize_clone(0, tb, info, empty_eq_hash_tree, 0); + nt2 = b2->tbranch; + } else if (SAME_OBJ(b2->tbranch, scheme_true) + && scheme_ir_duplicate_ok(tb, 0)) { + /* (if (if M #t N) K P) => (if M K (if N K P)) */ + ntb = optimize_clone(0, tb, info, empty_eq_hash_tree, 0); + nfb = (Scheme_Object *)b2; + nt2 = b2->fbranch; + } + if (nt2) { t = b2->test; - tb = (Scheme_Object *)b3; + b2->test = nt2; + b2->tbranch = tb; + b2->fbranch = fb; + tb = ntb; + fb = nfb; } }