diff --git a/src/compiler/float-tran.lisp b/src/compiler/float-tran.lisp index b856a6c328e394ebfe8da5ea7c9fd9c02fd6dad9..08ce90bdf785a35547da0771c9afabbe4cb45818 100644 --- a/src/compiler/float-tran.lisp +++ b/src/compiler/float-tran.lisp @@ -1494,15 +1494,11 @@ (two-arg-derive-type x y #'expt-derive-type-aux #'expt)) +;;; Note must assume that a type including 0.0 may also include -0.0 +;;; and thus the result may be complex -infinity + i*pi. +;;; (defun log-derive-type-aux-1 (x) - (elfun-derive-type-simple x - #'(lambda (z) - ;; log(0) and log(-0) is -infinity. - ;; Return NIL to indicate that. - (if (zerop z) - nil - (log z))) - -0d0 nil nil nil)) + (elfun-derive-type-simple x #'log 0d0 nil nil nil)) (defun log-derive-type-aux-2 (x y same-arg) (let ((log-x (log-derive-type-aux-1 x)) diff --git a/tests/trac.lisp b/tests/trac.lisp index 7fd940821f4a6bba381e4944febef1aad847673a..f8b425826b085edb78b6b0cbb596ab97c098cae3 100644 --- a/tests/trac.lisp +++ b/tests/trac.lisp @@ -329,8 +329,20 @@ (declare (type (double-float 0d0) x)) (log x))))) (assert-equal - 'double-float - (third (kernel:%function-type f))))) + '(or double-float (complex double-float)) + (third (kernel:%function-type f))) + ;; It is important that log(-0) = -inf + i*pi. This is needed to + ;; ensure that all of the special functions have the right values + ;; on the branch cuts. (Although the implementation of the special + ;; function may not use log internally, the definition might and + ;; this property is needed to derive the correct value from the + ;; definition.) + (assert-equal + (complex ext:double-float-negative-infinity pi) + (ext:with-float-traps-masked (:divide-by-zero) (log -0d0))) + (assert-equal + (complex ext:single-float-negative-infinity (float pi 1f0)) + (ext:with-float-traps-masked (:divide-by-zero) (log -0f0))))) (define-test trac.93 (:tag :trac)