diff --git a/collects/tests/typed-racket/optimizer/tests/pr13468.rkt b/collects/tests/typed-racket/optimizer/tests/pr13468.rkt index 0aa9b5d0..c10220fb 100644 --- a/collects/tests/typed-racket/optimizer/tests/pr13468.rkt +++ b/collects/tests/typed-racket/optimizer/tests/pr13468.rkt @@ -6,9 +6,6 @@ TR opt: pr13468.rkt 86:5 (- (ann 6.0+2.3i Float-Complex)) -- unboxed unary float TR opt: pr13468.rkt 87:13 6.0+2.3i -- unboxed literal TR opt: pr13468.rkt 87:13 6.0+2.3i -- unboxed literal TR opt: pr13468.rkt 87:5 (/ (ann 6.0+2.3i Float-Complex)) -- unboxed unary float complex -TR opt: pr13468.rkt 88:13 0.0+0.0i -- unboxed literal -TR opt: pr13468.rkt 88:42 1 -- float-arg-expr in complex ops -TR opt: pr13468.rkt 88:5 (/ (ann 0.0+0.0i Float-Complex) (ann 1 Number)) -- unboxed binary float complex TR missed opt: pr13468.rkt 91:5 (expt (ann -5.0 Flonum) (ann 2.0 Flonum)) -- unexpected complex type TR opt: pr13468.rkt 112:21 0.0 -- float-arg-expr in complex ops TR opt: pr13468.rkt 112:5 (magnitude (ann 0.0 Flonum-Zero)) -- unboxed unary float complex @@ -82,6 +79,9 @@ TR opt: pr13468.rkt 143:5 (real-part (ann 6.0 Flonum)) -- unboxed unary float co #lang typed/racket + + + ;; Most bothersome missing cases: (ann (- (ann 6.0+2.3i Float-Complex)) Float-Complex) (ann (/ (ann 6.0+2.3i Float-Complex)) Float-Complex) diff --git a/collects/typed-racket/optimizer/float-complex.rkt b/collects/typed-racket/optimizer/float-complex.rkt index 0e32fefc..7058f4ab 100644 --- a/collects/typed-racket/optimizer/float-complex.rkt +++ b/collects/typed-racket/optimizer/float-complex.rkt @@ -1,10 +1,10 @@ #lang racket/base -(require syntax/parse syntax/id-table racket/dict unstable/syntax +(require syntax/parse syntax/id-table racket/dict unstable/syntax racket/match "../utils/utils.rkt" racket/unsafe/ops (for-template racket/base racket/math racket/flonum racket/unsafe/ops) (utils tc-utils) - (types numeric-tower) + (types numeric-tower subtype type-table utils) (optimizer utils numeric-utils logging float)) (provide float-complex-opt-expr @@ -209,7 +209,7 @@ c1:unboxed-float-complex-opt-expr c2:unboxed-float-complex-opt-expr cs:unboxed-float-complex-opt-expr ...) - #:when (or (subtypeof? this-syntax -FloatComplex) (subtypeof? this-syntax -Number)) + #:when (subtypeof? this-syntax -FloatComplex) #:with real-binding (unboxed-gensym "unboxed-real-") #:with imag-binding (unboxed-gensym "unboxed-imag-") #:with reals (syntax-map get-part-or-0.0 @@ -462,7 +462,7 @@ (define-syntax-class float-complex-op #:commit - (pattern (~or (~literal +) (~literal -) (~literal *) (~literal /) (~literal conjugate) (~literal exp)))) + (pattern (~or (~literal +) (~literal -) (~literal *) (~literal conjugate) (~literal exp)))) (define-syntax-class float-complex->float-op #:commit @@ -596,6 +596,26 @@ (unsafe-make-flrectangular #,(get-part-or-0.0 #'exp*.real-binding) #,(get-part-or-0.0 #'exp*.imag-binding))))) + ;; division is special. can only optimize if none of the arguments can be exact 0. + ;; otherwise, optimization is unsound (we'd give a result where we're supposed to throw an error) + (pattern (#%plain-app (~literal /) e:expr ...) + #:when (subtypeof? this-syntax -FloatComplex) + #:when (for/and ([c (syntax->list #'(e ...))]) + (match (type-of c) + [(tc-result1: t) + (not (subtype -Zero t))] + [_ #f])) + #:with exp*:unboxed-float-complex-opt-expr this-syntax + #:with real-binding #'exp*.real-binding + #:with imag-binding #'exp*.imag-binding + #:with (bindings ...) #'(exp*.bindings ...) + #:with opt + (begin (reset-unboxed-gensym) + (add-disappeared-use #'op) + #`(let*-values (exp*.bindings ...) + (unsafe-make-flrectangular #,(get-part-or-0.0 #'exp*.real-binding) + #,(get-part-or-0.0 #'exp*.imag-binding))))) + (pattern v:id #:with unboxed-info (dict-ref unboxed-vars-table #'v #f) #:when (syntax->datum #'unboxed-info)