Avoid unsound optimization for complex division.

Found using random testing.

original commit: a50d9bad7e0823af5f3134e5edbd9be2768f247a
This commit is contained in:
Vincent St-Amour 2013-04-02 18:07:32 -04:00
parent 101b1d6496
commit 5f3a09570a
2 changed files with 27 additions and 7 deletions

View File

@ -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)

View File

@ -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)