diff --git a/src/compiler/float-tran.lisp b/src/compiler/float-tran.lisp index 7a82135b922b4e8ccfd79fe0dead86f3fb4758a9..d0a3703cc0088b93e62c0379b545f5770c8a50be 100644 --- a/src/compiler/float-tran.lisp +++ b/src/compiler/float-tran.lisp @@ -634,6 +634,28 @@ (frob >) (frob =)) +;; Convert (/ x n) to (* x (/ n)) when x is a float and n is a power +;; of two, because (/ n) can be reprsented exactly. +(deftransform / ((x y) (float float) * :when :both) + (unless (constant-continuation-p y) + (give-up)) + (let ((val (continuation-value y))) + (multiple-value-bind (frac exp sign) + (decode-float val) + (unless (= frac 0.5) + (give-up)) + `(* x (float (/ ,val) x))))) + +;; Convert 2*x to x+x. +(deftransform * ((x y) (float real) * :when :both) + (unless (constant-continuation-p y) + (give-up)) + (let ((val (continuation-value y))) + (unless (= val 2) + (give-up)) + '(+ x x))) + + ;;;; Irrational transforms: