diff --git a/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/optimizer/float-complex.rkt b/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/optimizer/float-complex.rkt index a5a33644..55579cc9 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/optimizer/float-complex.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/optimizer/float-complex.rkt @@ -31,6 +31,7 @@ (define-merged-syntax-class float-complex-op (+^ -^ *^ conjugate^ exp^)) +(define-syntax-class/specialize number-expr (subtyped-expr -Number)) (define-syntax-class/specialize float-expr (subtyped-expr -Flonum)) (define-syntax-class/specialize float-complex-expr (subtyped-expr -FloatComplex)) @@ -331,22 +332,28 @@ ((real-binding) (unsafe-flreal-part e*)) ((imag-binding) (unsafe-flimag-part e*)))) - ;; The following optimizations are incorrect and cause bugs because they turn exact numbers into inexact - (pattern e:float-arg-expr - #:with real-binding (generate-temporary 'unboxed-float-) - #:with imag-binding #'0.0 - #:do [(log-unboxing-opt "float-arg-expr in complex ops")] - #:with (bindings ...) #`(((real-binding) e.opt))) - - (pattern e:opt-expr - #:when (subtypeof? #'e -Number) ; complex, maybe exact, maybe not + ;; The following optimization is incorrect and causes bugs because it turns exact numbers into inexact + (pattern e:number-expr #:with e* (generate-temporary) #:with (real-binding imag-binding) (binding-names) - #:do [(log-unboxing-opt "unbox complex")] + #:do [(log-unboxing-opt + (if (subtypeof? #'e -Flonum) + "float in complex ops" + "non float complex in complex ops"))] + #:with real-binding-value + (cond + [(subtypeof? #'e -Flonum) #'e*] + [(subtypeof? #'e -Real) #'(real->double-flonum e*)] + [else #'(real->double-flonum (real-part e*))]) + #:with imag-binding-value + (cond + [(subtypeof? #'e -Real) #'0.0] + [else #'(real->double-flonum (imag-part e*))]) + #:with (bindings ...) #'(((e*) e.opt) - ((real-binding) (real->double-flonum (real-part e*))) - ((imag-binding) (real->double-flonum (imag-part e*))))) + ((real-binding) real-binding-value) + ((imag-binding) imag-binding-value))) (pattern e:expr #:do [(error (format "non exhaustive pattern match ~a" #'e))] #:with (bindings ...) (list) diff --git a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/missed-optimizations/unexpected-complex.rkt b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/missed-optimizations/unexpected-complex.rkt index 3586878e..e4aeae85 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/missed-optimizations/unexpected-complex.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/missed-optimizations/unexpected-complex.rkt @@ -2,7 +2,7 @@ #< unboxed fun TR opt: pr12475.rkt 19:29 so-far-init -- unboxed var -> table TR opt: pr12475.rkt 21:26 (* so-far-init (quote 1.0)) -- unboxed binary float complex TR opt: pr12475.rkt 21:29 so-far-init -- leave var unboxed -TR opt: pr12475.rkt 21:41 (quote 1.0) -- float-arg-expr in complex ops +TR opt: pr12475.rkt 21:41 (quote 1.0) -- float in complex ops TR opt: pr12475.rkt 22:26 so-far-init -- dead else branch TR opt: pr12475.rkt 23:5 for-loop -- unboxed let loop TR opt: pr12475.rkt 24:3 (quote 0.0+0.0i) -- unboxed literal diff --git a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/pr14284.rkt b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/pr14284.rkt index 29a1d5d3..a04f9225 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/pr14284.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/pr14284.rkt @@ -3,7 +3,7 @@ TR info: pr14284.rkt 26:26 displayln -- hidden parameter TR opt: pr14284.rkt 24:13 0.0+2.0i -- unboxed literal TR opt: pr14284.rkt 24:6 (+ 1.0 0.0+2.0i) -- unboxed binary float complex -TR opt: pr14284.rkt 24:9 1.0 -- float-arg-expr in complex ops +TR opt: pr14284.rkt 24:9 1.0 -- float in complex ops TR opt: pr14284.rkt 25:27 x -- unboxed var -> table TR opt: pr14284.rkt 25:4 optimizable -- fun -> unboxed fun TR opt: pr14284.rkt 27:25 (+ x y) -- unboxed binary float complex diff --git a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/real-part-loop.rkt b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/real-part-loop.rkt index 66ceba8c..354ee8f4 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/real-part-loop.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/real-part-loop.rkt @@ -10,7 +10,7 @@ TR opt: real-part-loop.rkt 30:6 (> (real-part v) 70000.2) -- binary float comp TR opt: real-part-loop.rkt 30:9 (real-part v) -- complex accessor elimination TR opt: real-part-loop.rkt 32:12 (+ v 3.6) -- unboxed binary float complex TR opt: real-part-loop.rkt 32:15 v -- leave var unboxed -TR opt: real-part-loop.rkt 32:17 3.6 -- float-arg-expr in complex ops +TR opt: real-part-loop.rkt 32:17 3.6 -- float in complex ops TR opt: real-part-loop.rkt 32:6 (loop (+ v 3.6)) -- call to fun with unboxed args TR opt: real-part-loop.rkt 32:6 (loop (+ v 3.6)) -- unboxed call site END diff --git a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions3.rkt b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions3.rkt index 483974be..6c0f56a0 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions3.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions3.rkt @@ -4,7 +4,7 @@ TR opt: unboxed-let-functions3.rkt 23:20 x -- unboxed var -> table TR opt: unboxed-let-functions3.rkt 23:7 f -- fun -> unboxed fun TR opt: unboxed-let-functions3.rkt 24:18 (+ x y) -- unboxed binary float complex TR opt: unboxed-let-functions3.rkt 24:21 x -- leave var unboxed -TR opt: unboxed-let-functions3.rkt 24:23 y -- float-arg-expr in complex ops +TR opt: unboxed-let-functions3.rkt 24:23 y -- float in complex ops TR opt: unboxed-let-functions3.rkt 25:17 2.0+4.0i -- unboxed literal TR opt: unboxed-let-functions3.rkt 25:2 (f (+ 1.0+2.0i 2.0+4.0i) 3.0) -- call to fun with unboxed args TR opt: unboxed-let-functions3.rkt 25:2 (f (+ 1.0+2.0i 2.0+4.0i) 3.0) -- unboxed call site diff --git a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions4.rkt b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions4.rkt index 8d9d5e1c..6194137d 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions4.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions4.rkt @@ -4,7 +4,7 @@ TR opt: unboxed-let-functions4.rkt 23:32 x -- unboxed var -> table TR opt: unboxed-let-functions4.rkt 23:7 f -- fun -> unboxed fun TR opt: unboxed-let-functions4.rkt 24:18 (+ x y) -- unboxed binary float complex TR opt: unboxed-let-functions4.rkt 24:21 x -- leave var unboxed -TR opt: unboxed-let-functions4.rkt 24:23 y -- float-arg-expr in complex ops +TR opt: unboxed-let-functions4.rkt 24:23 y -- float in complex ops TR opt: unboxed-let-functions4.rkt 25:2 (f 3.0 (+ 1.0+2.0i 2.0+4.0i)) -- call to fun with unboxed args TR opt: unboxed-let-functions4.rkt 25:2 (f 3.0 (+ 1.0+2.0i 2.0+4.0i)) -- unboxed call site TR opt: unboxed-let-functions4.rkt 26:17 2.0+4.0i -- unboxed literal diff --git a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions6.rkt b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions6.rkt index b20254d7..e8103462 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions6.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions6.rkt @@ -12,7 +12,7 @@ TR opt: unboxed-let-functions6.rkt 31:10 (loop (+ z (car l)) (cdr l)) -- call to TR opt: unboxed-let-functions6.rkt 31:10 (loop (+ z (car l)) (cdr l)) -- unboxed call site TR opt: unboxed-let-functions6.rkt 31:16 (+ z (car l)) -- unboxed binary float complex TR opt: unboxed-let-functions6.rkt 31:19 z -- leave var unboxed -TR opt: unboxed-let-functions6.rkt 31:21 (car l) -- float-arg-expr in complex ops +TR opt: unboxed-let-functions6.rkt 31:21 (car l) -- non float complex in complex ops TR opt: unboxed-let-functions6.rkt 31:21 (car l) -- pair TR opt: unboxed-let-functions6.rkt 32:16 (cdr l) -- pair END diff --git a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions7.rkt b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions7.rkt index 8df8de3d..c848029b 100644 --- a/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions7.rkt +++ b/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-let-functions7.rkt @@ -8,7 +8,7 @@ TR opt: unboxed-let-functions7.rkt 26:6 loop -- unboxed let loop TR opt: unboxed-let-functions7.rkt 29:6 z -- unboxed complex variable TR opt: unboxed-let-functions7.rkt 30:12 (+ z (car l)) -- unboxed binary float complex TR opt: unboxed-let-functions7.rkt 30:15 z -- leave var unboxed -TR opt: unboxed-let-functions7.rkt 30:17 (car l) -- float-arg-expr in complex ops +TR opt: unboxed-let-functions7.rkt 30:17 (car l) -- non float complex in complex ops TR opt: unboxed-let-functions7.rkt 30:17 (car l) -- pair TR opt: unboxed-let-functions7.rkt 30:6 (loop (+ z (car l)) (cdr l)) -- call to fun with unboxed args TR opt: unboxed-let-functions7.rkt 30:6 (loop (+ z (car l)) (cdr l)) -- unboxed call site