Don't coerce (= single-float 1d0) to double-float.
[sbcl.git] / src / compiler / float-tran.lisp
blobe24b595008f7a18b81e29b876a3fbd2b5a791a8f
1 ;;;; This file contains floating-point-specific transforms, and may be
2 ;;;; somewhat implementation-dependent in its assumptions of what the
3 ;;;; formats are.
5 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; more information.
7 ;;;;
8 ;;;; This software is derived from the CMU CL system, which was
9 ;;;; written at Carnegie Mellon University and released into the
10 ;;;; public domain. The software is in the public domain and is
11 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
12 ;;;; files for more information.
14 (in-package "SB-C")
16 ;;;; coercions
18 (deftransform float ((n f) (t single-float) *)
19 '(%single-float n))
21 (deftransform float ((n f) (t double-float) *)
22 '(%double-float n))
24 (deftransform float ((n) *)
25 '(if (floatp n)
27 (%single-float n)))
29 (deftransform %single-float ((n) (single-float) * :important nil)
30 'n)
32 (deftransform %double-float ((n) (double-float) * :important nil)
33 'n)
35 (deftransform %single-float ((n) (ratio) * :important nil)
36 '(sb-kernel::single-float-ratio n))
38 (deftransform %double-float ((n) (ratio) * :important nil)
39 '(sb-kernel::double-float-ratio n))
41 (macrolet ((def (type from-type)
42 `(deftransform ,(symbolicate "%" type) ((n) ((or ,type ,from-type)) * :important nil)
43 (when (or (csubtypep (lvar-type n) (specifier-type ',type))
44 (csubtypep (lvar-type n) (specifier-type ',from-type)))
45 (give-up-ir1-transform))
46 `(if (,',(symbolicate type "-P") n)
47 (truly-the ,',type n)
48 (,',(symbolicate "%" type) (truly-the ,',from-type n))))))
49 (def single-float double-float)
50 (def single-float sb-vm:signed-word)
51 (def single-float word)
52 (def double-float single-float)
53 (def double-float sb-vm:signed-word)
54 (def double-float word))
56 ;;; RANDOM
57 (macrolet ((frob (fun type)
58 `(deftransform random ((num &optional state)
59 (,type &optional t) *)
60 "Use inline float operations."
61 '(,fun num (or state *random-state*)))))
62 (frob %random-single-float single-float)
63 (frob %random-double-float double-float))
65 ;;; Return an expression to generate an integer of N-BITS many random
66 ;;; bits, using the minimal number of random chunks possible.
67 (defun generate-random-expr-for-power-of-2 (n-bits state)
68 (declare (type (integer 1 #.sb-vm:n-word-bits) n-bits))
69 (multiple-value-bind (n-chunk-bits chunk-expr)
70 (cond ((<= n-bits n-random-chunk-bits)
71 (values n-random-chunk-bits `(random-chunk ,state)))
72 ((<= n-bits (* 2 n-random-chunk-bits))
73 (values (* 2 n-random-chunk-bits) `(big-random-chunk ,state)))
75 (error "Unexpectedly small N-RANDOM-CHUNK-BITS")))
76 (if (< n-bits n-chunk-bits)
77 `(logand ,(1- (ash 1 n-bits)) ,chunk-expr)
78 chunk-expr)))
80 ;;; This transform for compile-time constant word-sized integers
81 ;;; generates an accept-reject loop to achieve equidistribution of the
82 ;;; returned values. Several optimizations are done: If NUM is a power
83 ;;; of two no loop is needed. If the random chunk size is half the word
84 ;;; size only one chunk is used where sufficient. For values of NUM
85 ;;; where it is possible and results in faster code, the rejection
86 ;;; probability is reduced by accepting all values below the largest
87 ;;; multiple of the limit that fits into one or two chunks and and doing
88 ;;; a division to get the random value into the desired range.
89 (deftransform random ((num &optional state)
90 ((constant-arg (integer 1 #.(expt 2 sb-vm:n-word-bits)))
91 &optional t)
93 :policy (and (> speed compilation-speed)
94 (> speed space)))
95 "optimize to inlined RANDOM-CHUNK operations"
96 (let ((num (lvar-value num)))
97 (if (= num 1)
99 (flet ((chunk-n-bits-and-expr (n-bits)
100 (cond ((<= n-bits n-random-chunk-bits)
101 (values n-random-chunk-bits
102 '(random-chunk (or state *random-state*))))
103 ((<= n-bits (* 2 n-random-chunk-bits))
104 (values (* 2 n-random-chunk-bits)
105 '(big-random-chunk (or state *random-state*))))
107 (error "Unexpectedly small N-RANDOM-CHUNK-BITS")))))
108 (if (zerop (logand num (1- num)))
109 ;; NUM is a power of 2.
110 (let ((n-bits (integer-length (1- num))))
111 (multiple-value-bind (n-chunk-bits chunk-expr)
112 (chunk-n-bits-and-expr n-bits)
113 (if (< n-bits n-chunk-bits)
114 `(logand ,(1- (ash 1 n-bits)) ,chunk-expr)
115 chunk-expr)))
116 ;; Generate an accept-reject loop.
117 (let ((n-bits (integer-length num)))
118 (multiple-value-bind (n-chunk-bits chunk-expr)
119 (chunk-n-bits-and-expr n-bits)
120 (if (or (> (* num 3) (expt 2 n-chunk-bits))
121 (logbitp (- n-bits 2) num))
122 ;; Division can't help as the quotient is below 3,
123 ;; or is too costly as the rejection probability
124 ;; without it is already small (namely at most 1/4
125 ;; with the given test, which is experimentally a
126 ;; reasonable threshold and cheap to test for).
127 `(loop
128 (let ((bits ,(generate-random-expr-for-power-of-2
129 n-bits '(or state *random-state*))))
130 (when (< bits num)
131 (return bits))))
132 (let ((d (truncate (expt 2 n-chunk-bits) num)))
133 `(loop
134 (let ((bits ,chunk-expr))
135 (when (< bits ,(* num d))
136 (return (values (truncate bits ,d)))))))))))))))
139 ;;;; float accessors
141 ;;; NaNs can not be constructed from constant bits mainly due to compiler problems
142 ;;; in so doing. See https://bugs.launchpad.net/sbcl/+bug/486812
143 (deftransform make-single-float ((bits) ((constant-arg t)))
144 "Conditional constant folding"
145 (let ((float (make-single-float (lvar-value bits))))
146 (if (float-nan-p float) (give-up-ir1-transform) float)))
148 (deftransform make-double-float ((hi lo) ((constant-arg t) (constant-arg t)))
149 "Conditional constant folding"
150 (let ((float (make-double-float (lvar-value hi) (lvar-value lo))))
151 (if (float-nan-p float) (give-up-ir1-transform) float)))
153 ;;; I'd like to transition all the 64-bit backends to use the single-arg
154 ;;; %MAKE-DOUBLE-FLOAT constructor instead of the 2-arg MAKE-DOUBLE-FLOAT.
155 ;;; So we need a transform to fold constant calls for either.
156 #+64-bit
157 (deftransform %make-double-float ((bits) ((constant-arg t)))
158 "Conditional constant folding"
159 (let ((float (%make-double-float (lvar-value bits))))
160 (if (float-nan-p float) (give-up-ir1-transform) float)))
162 ;;; On the face of it, these transforms are ridiculous because if we're going
163 ;;; to express (MINUSP X) as (MINUSP (foo-FLOAT-BITS X)), then why not _always_
164 ;;; transform MINUSP of a float into an integer comparison instead of a
165 ;;; floating-point comparison, and then express this as (if (minusp float) ...)
166 ;;; rather than (if (minusp (bits float)) ...) ?
167 ;;; I suspect that the difference is that FLOAT-SIGN must remain silent
168 ;;; when given a signaling NaN.
169 (deftransform float-sign ((float &optional float2)
170 (single-float &optional single-float) *)
171 (if (vop-existsp :translate single-float-copysign)
172 (if float2
173 `(single-float-copysign float float2)
174 `(single-float-sign float))
175 (if float2
176 (let ((temp (gensym)))
177 `(let ((,temp (abs float2)))
178 (if (minusp (single-float-bits float)) (- ,temp) ,temp)))
179 '(if (minusp (single-float-bits float)) $-1f0 $1f0))))
181 (deftransform float-sign ((float &optional float2)
182 (double-float &optional double-float) *)
183 ;; If words are 64 bits, then it's actually simpler to extract _all_ bits
184 ;; instead of only the upper bits.
185 (let ((bits #+64-bit '(double-float-bits float)
186 #-64-bit '(double-float-high-bits float)))
187 (if float2
188 (let ((temp (gensym)))
189 `(let ((,temp (abs float2)))
190 (if (minusp ,bits) (- ,temp) ,temp)))
191 `(if (minusp ,bits) $-1d0 $1d0))))
193 (deftransform float-sign-bit ((x) (single-float) *)
194 `(logand (ash (single-float-bits x) -31) 1))
195 (deftransform float-sign-bit ((x) (double-float) *)
196 #-64-bit `(logand (ash (double-float-high-bits x) -31) 1)
197 #+64-bit `(ash (logand (double-float-bits x) most-positive-word) -63))
199 (deftransform float-sign-bit-set-p ((x) (single-float) *)
200 `(logbitp 31 (single-float-bits x)))
201 (deftransform float-sign-bit-set-p ((x) (double-float) *)
202 #-64-bit `(logbitp 31 (double-float-high-bits x))
203 #+64-bit `(logbitp 63 (double-float-bits x)))
205 ;;; This doesn't deal with complex at the moment.
206 (deftransform signum ((x) (number))
207 (let* ((ctype (lvar-type x))
208 (result-type
209 (dolist (x '(single-float double-float rational))
210 (when (csubtypep ctype (specifier-type x))
211 (return x)))))
212 ;; SB-XC:COERCE doesn't like RATIONAL for some reason.
213 (when (eq result-type 'rational) (setq result-type 'integer))
214 (if result-type
215 `(cond ((zerop x) x)
216 ((plusp x) ,(sb-xc:coerce 1 result-type))
217 (t ,(sb-xc:coerce -1 result-type)))
218 (give-up-ir1-transform))))
220 ;;;; DECODE-FLOAT, INTEGER-DECODE-FLOAT, and SCALE-FLOAT
222 (defknown decode-single-float (single-float)
223 (values single-float single-float-exponent (member $-1f0 $1f0))
224 (movable foldable flushable))
226 (defknown decode-double-float (double-float)
227 (values double-float double-float-exponent (member $-1d0 $1d0))
228 (movable foldable flushable))
230 (defknown integer-decode-single-float (single-float)
231 (values single-float-significand single-float-int-exponent (member -1 1))
232 (movable foldable flushable))
234 (defknown integer-decode-double-float (double-float)
235 (values double-float-significand double-float-int-exponent (member -1 1))
236 (movable foldable flushable))
238 (defknown scale-single-float (single-float integer) single-float
239 (movable foldable flushable fixed-args unboxed-return))
240 (defknown scale-double-float (double-float integer) double-float
241 (movable foldable flushable fixed-args unboxed-return))
243 (defknown sb-kernel::scale-single-float-maybe-overflow
244 (single-float integer) single-float
245 (movable foldable flushable fixed-args unboxed-return))
246 (defknown sb-kernel::scale-single-float-maybe-underflow
247 (single-float integer) single-float
248 (movable foldable flushable fixed-args unboxed-return))
249 (defknown sb-kernel::scale-double-float-maybe-overflow
250 (double-float integer) double-float
251 (movable foldable flushable fixed-args unboxed-return))
252 (defknown sb-kernel::scale-double-float-maybe-underflow
253 (double-float integer) double-float
254 (movable foldable flushable fixed-args unboxed-return))
256 (deftransform decode-float ((x) (single-float) *)
257 '(decode-single-float x))
259 (deftransform decode-float ((x) (double-float) *)
260 '(decode-double-float x))
262 (deftransform integer-decode-float ((x) (single-float) *)
263 '(integer-decode-single-float x))
265 (deftransform integer-decode-float ((x) (double-float) *)
266 '(integer-decode-double-float x))
268 (deftransform scale-float ((f ex) (single-float t) *)
269 (cond #+(and x86 ()) ;; this producess different results based on whether it's inlined or not
270 ((csubtypep (lvar-type ex)
271 (specifier-type '(signed-byte 32)))
272 '(coerce (%scalbn (coerce f 'double-float) ex) 'single-float))
274 '(scale-single-float f ex))))
276 (deftransform scale-float ((f ex) (double-float t) *)
277 (cond #+(and x86 ())
278 ((csubtypep (lvar-type ex)
279 (specifier-type '(signed-byte 32)))
280 '(%scalbn f ex))
282 '(scale-double-float f ex))))
284 ;;; Given a number X, create a form suitable as a bound for an
285 ;;; interval. Make the bound open if OPEN-P is T. NIL remains NIL.
286 ;;; FIXME: as this is a constructor, shouldn't it be named MAKE-BOUND?
287 (declaim (inline set-bound))
288 (defun set-bound (x open-p)
289 (if (and x open-p) (list x) x))
291 ;;; optimizers for SCALE-FLOAT. If the float has bounds, new bounds
292 ;;; are computed for the result, if possible.
293 (defun scale-float-derive-type-aux (f ex same-arg)
294 (declare (ignore same-arg))
295 (flet ((scale-bound (x n)
296 ;; We need to be a bit careful here and catch any overflows
297 ;; that might occur. We can ignore underflows which become
298 ;; zeros.
299 (set-bound
300 (handler-case
301 (scale-float (type-bound-number x) n)
302 (floating-point-overflow ()
303 nil))
304 (consp x))))
305 (when (and (numeric-type-p f) (numeric-type-p ex))
306 (let ((f-lo (numeric-type-low f))
307 (f-hi (numeric-type-high f))
308 (ex-lo (numeric-type-low ex))
309 (ex-hi (numeric-type-high ex))
310 (new-lo nil)
311 (new-hi nil))
312 (when f-hi
313 (if (sb-xc:< (float-sign (type-bound-number f-hi)) $0.0)
314 (when ex-lo
315 (setf new-hi (scale-bound f-hi ex-lo)))
316 (when ex-hi
317 (setf new-hi (scale-bound f-hi ex-hi)))))
318 (when f-lo
319 (if (sb-xc:< (float-sign (type-bound-number f-lo)) $0.0)
320 (when ex-hi
321 (setf new-lo (scale-bound f-lo ex-hi)))
322 (when ex-lo
323 (setf new-lo (scale-bound f-lo ex-lo)))))
324 (make-numeric-type :class (numeric-type-class f)
325 :format (numeric-type-format f)
326 :complexp :real
327 :low new-lo
328 :high new-hi)))))
329 (defoptimizer (scale-single-float derive-type) ((f ex))
330 (two-arg-derive-type f ex #'scale-float-derive-type-aux
331 #'scale-single-float))
332 (defoptimizer (scale-double-float derive-type) ((f ex))
333 (two-arg-derive-type f ex #'scale-float-derive-type-aux
334 #'scale-double-float))
336 ;;; DEFOPTIMIZERs for %SINGLE-FLOAT and %DOUBLE-FLOAT. This makes the
337 ;;; FLOAT function return the correct ranges if the input has some
338 ;;; defined range. Quite useful if we want to convert some type of
339 ;;; bounded integer into a float.
340 (macrolet
341 ((frob (fun type most-negative most-positive)
342 (let ((aux-name (symbolicate fun "-DERIVE-TYPE-AUX")))
343 `(progn
344 (defun ,aux-name (num)
345 ;; When converting a number to a float, the limits are
346 ;; the same.
347 (let* ((lo (bound-func (lambda (x)
348 (if (sb-xc:< x ,most-negative)
349 ,most-negative
350 (coerce x ',type)))
351 (numeric-type-low num)
352 nil))
353 (hi (bound-func (lambda (x)
354 (if (sb-xc:< ,most-positive x )
355 ,most-positive
356 (coerce x ',type)))
357 (numeric-type-high num)
358 nil)))
359 (specifier-type `(,',type ,(or lo '*) ,(or hi '*)))))
361 (defoptimizer (,fun derive-type) ((num))
362 (handler-case
363 (one-arg-derive-type num #',aux-name #',fun)
364 (type-error ()
365 nil)))))))
366 (frob %single-float single-float
367 most-negative-single-float most-positive-single-float)
368 (frob %double-float double-float
369 most-negative-double-float most-positive-double-float))
371 (defoptimizer (float derive-type) ((number prototype))
372 (let ((type (lvar-type prototype)))
373 (unless (or (csubtypep type (specifier-type 'double-float))
374 (csubtypep type (specifier-type 'single-float)))
375 (handler-case
376 (type-union
377 (one-arg-derive-type number #'%single-float-derive-type-aux #'%single-float)
378 (one-arg-derive-type number #'%double-float-derive-type-aux #'%double-float))
379 (type-error ()
380 nil)))))
382 (macrolet ((def (type &rest args)
383 `(deftransform * ((x y) (,type (constant-arg (member ,@args))) *
384 ;; Beware the SNaN!
385 :policy (zerop float-accuracy))
386 "optimize multiplication by one"
387 (let ((y (lvar-value y)))
388 (if (minusp y)
389 '(%negate x)
390 'x)))))
391 (def single-float $1.0 $-1.0)
392 (def double-float $1.0d0 $-1.0d0))
394 ;;; Return the reciprocal of X if it can be represented exactly, NIL otherwise.
395 (defun maybe-exact-reciprocal (x)
396 (unless (zerop x)
397 (handler-case
398 (multiple-value-bind (significand exponent sign)
399 (integer-decode-float x)
400 ;; only powers of 2 can be inverted exactly
401 (unless (zerop (logand significand (1- significand)))
402 (return-from maybe-exact-reciprocal nil))
403 (let ((expected (/ sign significand (expt 2 exponent)))
404 (reciprocal (/ x)))
405 (multiple-value-bind (significand exponent sign)
406 (integer-decode-float reciprocal)
407 ;; Denorms can't be inverted safely.
408 (and (eql expected (* sign significand (expt 2 exponent)))
409 reciprocal))))
410 (error () (return-from maybe-exact-reciprocal nil)))))
412 ;;; Replace constant division by multiplication with exact reciprocal,
413 ;;; if one exists.
414 (macrolet ((def (type)
415 `(deftransform / ((x y) (,type (constant-arg ,type)) *
416 :node node)
417 "convert to multiplication by reciprocal"
418 (let ((n (lvar-value y)))
419 (if (policy node (zerop float-accuracy))
420 `(* x ,(/ n))
421 (let ((r (maybe-exact-reciprocal n)))
422 (if r
423 `(* x ,r)
424 (give-up-ir1-transform
425 "~S does not have an exact reciprocal"
426 n))))))))
427 (def single-float)
428 (def double-float))
430 ;;; Optimize addition and subtraction of zero
431 (macrolet ((def (op type &rest args)
432 `(deftransform ,op ((x y) (,type (constant-arg (member ,@args))) *
433 ;; Beware the SNaN!
434 :policy (zerop float-accuracy))
435 'x)))
436 ;; No signed zeros, thanks.
437 (def + single-float 0 $0.0)
438 (def - single-float 0 $0.0)
439 (def + double-float 0 $0.0 $0.0d0)
440 (def - double-float 0 $0.0 $0.0d0))
442 ;;; On most platforms (+ x x) is faster than (* x 2)
443 (macrolet ((def (type &rest args)
444 `(deftransform * ((x y) (,type (constant-arg (member ,@args))))
445 '(+ x x))))
446 (def single-float 2 $2.0)
447 (def double-float 2 $2.0 $2.0d0))
449 ;;; Prevent ZEROP, PLUSP, and MINUSP from losing horribly. We can't in
450 ;;; general float rational args to comparison, since Common Lisp
451 ;;; semantics says we are supposed to compare as rationals, but we can
452 ;;; do it for any rational that has a precise representation as a
453 ;;; float (such as 0).
454 (macrolet ((frob (op &optional complex)
455 `(deftransform ,op ((x y) (:or ((,(if complex
456 '(complex single-float)
457 'single-float)
458 rational) *)
459 ((,(if complex
460 '(complex double-float)
461 'double-float)
462 rational) *)))
463 "open-code FLOAT to RATIONAL comparison"
464 (unless (constant-lvar-p y)
465 (give-up-ir1-transform
466 "The RATIONAL value isn't known at compile time."))
467 (let ((val (lvar-value y)))
468 (multiple-value-bind (low high type)
469 (if (csubtypep (lvar-type x) (specifier-type 'double-float))
470 (values most-negative-double-float most-positive-double-float
471 'double-float)
472 (values most-negative-single-float most-positive-single-float
473 'single-float))
474 (unless (and (sb-xc:<= low val high)
475 (eql (rational (coerce val type)) val))
476 (give-up-ir1-transform
477 "~S doesn't have a precise float representation."
478 val))))
479 `(,',op x (float y ,',(if complex
480 '(realpart x)
481 'x))))))
482 (frob <)
483 (frob >)
484 (frob <=)
485 (frob >=)
486 (frob =)
487 (frob = t))
490 ;;;; irrational transforms
492 (macrolet ((def (name prim rtype)
493 `(progn
494 (deftransform ,name ((x) (single-float) ,rtype :node node)
495 (delay-ir1-transform node :ir1-phases)
496 `(%single-float (,',prim (%double-float x))))
497 (deftransform ,name ((x) (double-float) ,rtype :node node)
498 (delay-ir1-transform node :ir1-phases)
499 `(,',prim x)))))
500 (def exp %exp *)
501 (def log %log float)
502 (def sqrt %sqrt float)
503 (def asin %asin float)
504 (def acos %acos float)
505 (def atan %atan *)
506 (def sinh %sinh *)
507 (def cosh %cosh *)
508 (def tanh %tanh *)
509 (def asinh %asinh *)
510 (def acosh %acosh float)
511 (def atanh %atanh float))
513 ;;; The argument range is limited on the x86 FP trig. functions. A
514 ;;; post-test can detect a failure (and load a suitable result), but
515 ;;; this test is avoided if possible.
516 (macrolet ((def (name prim prim-quick)
517 (declare (ignorable prim-quick))
518 `(progn
519 (deftransform ,name ((x) (single-float) *)
520 #+x86 (cond ((csubtypep (lvar-type x)
521 (specifier-type
522 `(single-float (,(sb-xc:- (expt $2f0 63)))
523 (,(expt $2f0 63)))))
524 `(coerce (,',prim-quick (coerce x 'double-float))
525 'single-float))
527 (compiler-notify
528 "unable to avoid inline argument range check~@
529 because the argument range (~S) was not within 2^63"
530 (type-specifier (lvar-type x)))
531 `(coerce (,',prim (coerce x 'double-float)) 'single-float)))
532 #-x86 `(coerce (,',prim (coerce x 'double-float)) 'single-float))
533 (deftransform ,name ((x) (double-float) *)
534 #+x86 (cond ((csubtypep (lvar-type x)
535 (specifier-type
536 `(double-float (,(sb-xc:- (expt $2d0 63)))
537 (,(expt $2d0 63)))))
538 `(,',prim-quick x))
540 (compiler-notify
541 "unable to avoid inline argument range check~@
542 because the argument range (~S) was not within 2^63"
543 (type-specifier (lvar-type x)))
544 `(,',prim x)))
545 #-x86 `(,',prim x)))))
546 (def sin %sin %sin-quick)
547 (def cos %cos %cos-quick)
548 (def tan %tan %tan-quick))
550 (deftransform atan ((x y) (single-float single-float) *)
551 `(coerce (%atan2 (coerce x 'double-float) (coerce y 'double-float))
552 'single-float))
553 (deftransform atan ((x y) (double-float double-float) *)
554 `(%atan2 x y))
556 (deftransform expt ((x y) (single-float single-float) single-float)
557 `(coerce (%pow (coerce x 'double-float) (coerce y 'double-float))
558 'single-float))
559 (deftransform expt ((x y) (double-float double-float) double-float)
560 `(%pow x y))
561 (deftransform expt ((x y) (single-float integer) single-float)
562 `(coerce (%pow (coerce x 'double-float) (coerce y 'double-float))
563 'single-float))
564 (deftransform expt ((x y) (double-float integer) double-float)
565 `(%pow x (coerce y 'double-float)))
567 ;;; ANSI says log with base zero returns zero.
568 (deftransform log ((x y) (float float) float)
569 '(if (zerop y) y (/ (log x) (log y))))
571 ;;; Handle some simple transformations.
573 (deftransform abs ((x) ((complex double-float)) double-float)
574 '(%hypot (realpart x) (imagpart x)))
576 (deftransform abs ((x) ((complex single-float)) single-float)
577 '(coerce (%hypot (coerce (realpart x) 'double-float)
578 (coerce (imagpart x) 'double-float))
579 'single-float))
581 (deftransform phase ((x) ((complex double-float)) double-float)
582 '(%atan2 (imagpart x) (realpart x)))
584 (deftransform phase ((x) ((complex single-float)) single-float)
585 '(coerce (%atan2 (coerce (imagpart x) 'double-float)
586 (coerce (realpart x) 'double-float))
587 'single-float))
589 (deftransform phase ((x) ((float)) float)
590 '(if (minusp (float-sign x))
591 (float pi x)
592 (float 0 x)))
594 ;;; The number is of type REAL.
595 (defun numeric-type-real-p (type)
596 (and (numeric-type-p type)
597 (eq (numeric-type-complexp type) :real)))
599 ;;;; optimizers for elementary functions
600 ;;;;
601 ;;;; These optimizers compute the output range of the elementary
602 ;;;; function, based on the domain of the input.
604 ;;; Generate a specifier for a complex type specialized to the same
605 ;;; type as the argument.
606 (defun complex-float-type (arg)
607 (declare (type numeric-type arg))
608 (let* ((format (case (numeric-type-class arg)
609 ((integer rational) 'single-float)
610 (t (numeric-type-format arg))))
611 (float-type (or format 'float)))
612 (specifier-type `(complex ,float-type))))
614 ;;; Compute a specifier like '(OR FLOAT (COMPLEX FLOAT)), except float
615 ;;; should be the right kind of float. Allow bounds for the float
616 ;;; part too.
617 (defun float-or-complex-float-type (arg &optional lo hi)
618 (cond
619 ((numeric-type-p arg)
620 (let* ((format (case (numeric-type-class arg)
621 ((integer rational) 'single-float)
622 (t (numeric-type-format arg))))
623 (float-type (or format 'float))
624 (lo (coerce-numeric-bound lo float-type))
625 (hi (coerce-numeric-bound hi float-type)))
626 (specifier-type `(or (,float-type ,(or lo '*) ,(or hi '*))
627 (complex ,float-type)))))
628 ((union-type-p arg)
629 (apply #'type-union
630 (loop for type in (union-type-types arg)
631 collect (float-or-complex-float-type type lo hi))))
632 (t (specifier-type 'number))))
634 (eval-when (:compile-toplevel :execute)
635 ;; So the problem with this hack is that it's actually broken. If
636 ;; the host does not have long floats, then setting *R-D-F-F* to
637 ;; LONG-FLOAT doesn't actually buy us anything. FIXME.
638 (setf *read-default-float-format*
639 #+long-float 'cl:long-float #-long-float 'cl:double-float))
641 ;;; Test whether the numeric-type ARG is within the domain specified by
642 ;;; DOMAIN-LOW and DOMAIN-HIGH, consider negative and positive zero to
643 ;;; be distinct.
644 (defun domain-subtypep (arg domain-low domain-high)
645 (declare (type numeric-type arg)
646 (type (or real null) domain-low domain-high))
647 (let* ((arg-lo (numeric-type-low arg))
648 (arg-lo-val (type-bound-number arg-lo))
649 (arg-hi (numeric-type-high arg))
650 (arg-hi-val (type-bound-number arg-hi)))
651 ;; Check that the ARG bounds are correctly canonicalized.
652 (when (and arg-lo (floatp arg-lo-val) (zerop arg-lo-val) (consp arg-lo)
653 (minusp (float-sign arg-lo-val)))
654 (setf arg-lo
655 (typecase arg-lo-val
656 (single-float $0f0)
657 (double-float $0d0)
658 #+long-float
659 (long-float 0l0))
660 arg-lo-val arg-lo))
661 (when (and arg-hi (zerop arg-hi-val) (floatp arg-hi-val) (consp arg-hi)
662 (plusp (float-sign arg-hi-val)))
663 (setf arg-hi
664 (typecase arg-lo-val
665 (single-float $-0f0)
666 (double-float $-0d0)
667 #+long-float
668 (long-float $-0L0))
669 arg-hi-val arg-hi))
670 (flet ((fp-neg-zero-p (f) ; Is F -0.0?
671 (and (floatp f) (zerop f) (float-sign-bit-set-p f)))
672 (fp-pos-zero-p (f) ; Is F +0.0?
673 (and (floatp f) (zerop f) (not (float-sign-bit-set-p f)))))
674 (and (or (null domain-low)
675 (and arg-lo (sb-xc:>= arg-lo-val domain-low)
676 (not (and (fp-pos-zero-p domain-low)
677 (fp-neg-zero-p arg-lo)))))
678 (or (null domain-high)
679 (and arg-hi (sb-xc:<= arg-hi-val domain-high)
680 (not (and (fp-neg-zero-p domain-high)
681 (fp-pos-zero-p arg-hi)))))))))
683 (eval-when (:compile-toplevel :execute)
684 (setf *read-default-float-format* 'cl:single-float))
686 ;;; Handle monotonic functions of a single variable whose domain is
687 ;;; possibly part of the real line. ARG is the variable, FUN is the
688 ;;; function, and DOMAIN is a specifier that gives the (real) domain
689 ;;; of the function. If ARG is a subset of the DOMAIN, we compute the
690 ;;; bounds directly. Otherwise, we compute the bounds for the
691 ;;; intersection between ARG and DOMAIN, and then append a complex
692 ;;; result, which occurs for the parts of ARG not in the DOMAIN.
694 ;;; Negative and positive zero are considered distinct within
695 ;;; DOMAIN-LOW and DOMAIN-HIGH.
697 ;;; DEFAULT-LOW and DEFAULT-HIGH are the lower and upper bounds if we
698 ;;; can't compute the bounds using FUN.
699 (defun elfun-derive-type-simple (arg fun domain-low domain-high
700 default-low default-high
701 &optional (increasingp t))
702 (declare (type (or null real) domain-low domain-high))
703 (etypecase arg
704 (numeric-type
705 (cond ((eq (numeric-type-complexp arg) :complex)
706 (complex-float-type arg))
707 ((numeric-type-real-p arg)
708 ;; The argument is real, so let's find the intersection
709 ;; between the argument and the domain of the function.
710 ;; We compute the bounds on the intersection, and for
711 ;; everything else, we return a complex number of the
712 ;; appropriate type.
713 (multiple-value-bind (intersection difference)
714 (interval-intersection/difference (numeric-type->interval arg)
715 (make-interval
716 :low domain-low
717 :high domain-high))
718 (cond
719 (intersection
720 ;; Process the intersection.
721 (let* ((low (interval-low intersection))
722 (high (interval-high intersection))
723 (res-lo (or (bound-func fun (if increasingp low high) nil)
724 default-low))
725 (res-hi (or (bound-func fun (if increasingp high low) nil)
726 default-high))
727 (format (case (numeric-type-class arg)
728 ((integer rational) 'single-float)
729 (t (numeric-type-format arg))))
730 (bound-type (or format 'float))
731 (result-type
732 (make-numeric-type
733 :class 'float
734 :format format
735 :low (coerce-numeric-bound res-lo bound-type)
736 :high (coerce-numeric-bound res-hi bound-type))))
737 ;; If the ARG is a subset of the domain, we don't
738 ;; have to worry about the difference, because that
739 ;; can't occur.
740 (if (or (null difference)
741 ;; Check whether the arg is within the domain.
742 (domain-subtypep arg domain-low domain-high))
743 result-type
744 (list result-type
745 (specifier-type `(complex ,bound-type))))))
747 ;; No intersection so the result must be purely complex.
748 (complex-float-type arg)))))
750 (float-or-complex-float-type arg default-low default-high))))))
752 (macrolet
753 ((frob (name domain-low domain-high def-low-bnd def-high-bnd
754 &key (increasingp t))
755 (let ((num (gensym)))
756 `(defoptimizer (,name derive-type) ((,num))
757 (one-arg-derive-type
758 ,num
759 (lambda (arg)
760 (elfun-derive-type-simple arg #',name
761 ,domain-low ,domain-high
762 ,def-low-bnd ,def-high-bnd
763 ,increasingp))
764 #',name)))))
765 ;; These functions are easy because they are defined for the whole
766 ;; real line.
767 (frob exp nil nil 0 nil)
768 (frob sinh nil nil nil nil)
769 (frob tanh nil nil -1 1)
770 (frob asinh nil nil nil nil)
772 ;; These functions are only defined for part of the real line. The
773 ;; condition selects the desired part of the line.
774 (frob asin $-1d0 $1d0 (sb-xc:- (sb-xc:/ pi 2)) (sb-xc:/ pi 2))
775 ;; Acos is monotonic decreasing, so we need to swap the function
776 ;; values at the lower and upper bounds of the input domain.
777 (frob acos $-1d0 $1d0 0 pi :increasingp nil)
778 (frob acosh $1d0 nil nil nil)
779 (frob atanh $-1d0 $1d0 -1 1)
780 ;; Kahan says that (sqrt -0.0) is -0.0, so use a specifier that
781 ;; includes -0.0.
782 (frob sqrt $-0.0d0 nil 0 nil))
784 ;;; Compute bounds for (expt x y). This should be easy since (expt x
785 ;;; y) = (exp (* y (log x))). However, computations done this way
786 ;;; have too much roundoff. Thus we have to do it the hard way.
787 (defun safe-expt (x y)
788 (when (and (numberp x) (numberp y))
789 (handler-case
790 (when (sb-xc:< (abs y) 10000)
791 (expt x y))
792 ;; Currently we can hide unanticipated errors (such as failure to use SB-XC: math
793 ;; when cross-compiling) as well as the anticipated potential problem of overflow.
794 ;; So don't handle anything when cross-compiling.
795 ;; FIXME: I think this should not handle ERROR, but just FLOATING-POINT-OVERFLOW.
796 (#+sb-xc-host nil
797 #-sb-xc-host error ()
798 nil))))
800 ;;; Handle the case when x >= 1.
801 (defun interval-expt-> (x y)
802 (case (interval-range-info y $0d0)
804 ;; Y is positive and log X >= 0. The range of exp(y * log(x)) is
805 ;; obviously non-negative. We just have to be careful for
806 ;; infinite bounds (given by nil).
807 (let ((lo (safe-expt (type-bound-number (interval-low x))
808 (type-bound-number (interval-low y))))
809 (hi (safe-expt (type-bound-number (interval-high x))
810 (type-bound-number (interval-high y)))))
811 (list (make-interval :low (or lo 1) :high hi))))
813 ;; Y is negative and log x >= 0. The range of exp(y * log(x)) is
814 ;; obviously [0, 1]. However, underflow (nil) means 0 is the
815 ;; result.
816 (let ((lo (safe-expt (type-bound-number (interval-high x))
817 (type-bound-number (interval-low y))))
818 (hi (safe-expt (type-bound-number (interval-low x))
819 (type-bound-number (interval-high y)))))
820 (list (make-interval :low (or lo 0) :high (or hi 1)))))
822 ;; Split the interval in half.
823 (destructuring-bind (y- y+)
824 (interval-split 0 y t)
825 (list (interval-expt-> x y-)
826 (interval-expt-> x y+))))))
828 ;;; Handle the case when 0 <= x <= 1
829 (defun interval-expt-< (x y)
830 (case (interval-range-info x $0d0)
832 ;; The case of 0 <= x <= 1 is easy
833 (case (interval-range-info y)
835 ;; Y is positive and log X <= 0. The range of exp(y * log(x)) is
836 ;; obviously [0, 1]. We just have to be careful for infinite bounds
837 ;; (given by nil).
838 (let ((lo (safe-expt (type-bound-number (interval-low x))
839 (type-bound-number (interval-high y))))
840 (hi (safe-expt (type-bound-number (interval-high x))
841 (type-bound-number (interval-low y)))))
842 (list (make-interval :low (or lo 0) :high (or hi 1)))))
844 ;; Y is negative and log x <= 0. The range of exp(y * log(x)) is
845 ;; obviously [1, inf].
846 (let ((hi (safe-expt (type-bound-number (interval-low x))
847 (type-bound-number (interval-low y))))
848 (lo (safe-expt (type-bound-number (interval-high x))
849 (type-bound-number (interval-high y)))))
850 (list (make-interval :low (or lo 1) :high hi))))
852 ;; Split the interval in half
853 (destructuring-bind (y- y+)
854 (interval-split 0 y t)
855 (list (interval-expt-< x y-)
856 (interval-expt-< x y+))))))
858 ;; The case where x <= 0. Y MUST be an INTEGER for this to work!
859 ;; The calling function must insure this!
860 (loop for interval in (flatten-list (interval-expt (interval-neg x) y))
861 for low = (interval-low interval)
862 for high = (interval-high interval)
863 collect interval
864 when (or high low)
865 collect (interval-neg interval)))
867 (destructuring-bind (neg pos)
868 (interval-split 0 x t t)
869 (list (interval-expt-< neg y)
870 (interval-expt-< pos y))))))
872 ;;; Compute bounds for (expt x y).
873 (defun interval-expt (x y)
874 (case (interval-range-info x 1)
876 ;; X >= 1
877 (interval-expt-> x y))
879 ;; X <= 1
880 (interval-expt-< x y))
882 (destructuring-bind (left right)
883 (interval-split 1 x t t)
884 (list (interval-expt left y)
885 (interval-expt right y))))))
887 (defun fixup-interval-expt (bnd x-int y-int x-type y-type)
888 (declare (ignore x-int))
889 ;; Figure out what the return type should be, given the argument
890 ;; types and bounds and the result type and bounds.
891 (cond ((csubtypep x-type (specifier-type 'integer))
892 ;; an integer to some power
893 (case (numeric-type-class y-type)
894 (integer
895 ;; Positive integer to an integer power is either an
896 ;; integer or a rational.
897 (let ((lo (or (interval-low bnd) '*))
898 (hi (or (interval-high bnd) '*))
899 (y-lo (interval-low y-int))
900 (y-hi (interval-high y-int)))
901 (cond ((and (eq lo '*)
902 (eql y-lo y-hi)
903 (typep y-lo 'unsigned-byte)
904 (evenp y-lo))
905 (specifier-type `(integer 0 ,hi)))
906 ((and (interval-low y-int)
907 (>= (type-bound-number y-lo) 0))
909 (specifier-type `(integer ,lo ,hi)))
911 (specifier-type `(rational ,lo ,hi))))))
912 (rational
913 ;; Positive integer to rational power is either a rational
914 ;; or a single-float.
915 (let* ((lo (interval-low bnd))
916 (hi (interval-high bnd))
917 (int-lo (if lo
918 (floor (type-bound-number lo))
919 '*))
920 (int-hi (if hi
921 (ceiling (type-bound-number hi))
922 '*))
923 (f-lo (or (bound-func #'float lo nil)
924 '*))
925 (f-hi (or (bound-func #'float hi nil)
926 '*)))
927 (specifier-type `(or (rational ,int-lo ,int-hi)
928 (single-float ,f-lo, f-hi)))))
929 (float
930 ;; A positive integer to a float power is a float.
931 (let ((format (numeric-type-format y-type)))
932 (aver format)
933 (modified-numeric-type
934 y-type
935 :low (coerce-numeric-bound (interval-low bnd) format)
936 :high (coerce-numeric-bound (interval-high bnd) format))))
938 ;; A positive integer to a number is a number (for now).
939 (specifier-type 'number))))
940 ((csubtypep x-type (specifier-type 'rational))
941 ;; a rational to some power
942 (case (numeric-type-class y-type)
943 (integer
944 ;; A positive rational to an integer power is always a rational.
945 (specifier-type `(rational ,(or (interval-low bnd) '*)
946 ,(or (interval-high bnd) '*))))
947 (rational
948 ;; A positive rational to rational power is either a rational
949 ;; or a single-float.
950 (let* ((lo (interval-low bnd))
951 (hi (interval-high bnd))
952 (int-lo (if lo
953 (floor (type-bound-number lo))
954 '*))
955 (int-hi (if hi
956 (ceiling (type-bound-number hi))
957 '*))
958 (f-lo (or (bound-func #'float lo nil)
959 '*))
960 (f-hi (or (bound-func #'float hi nil)
961 '*)))
962 (specifier-type `(or (rational ,int-lo ,int-hi)
963 (single-float ,f-lo, f-hi)))))
964 (float
965 ;; A positive rational to a float power is a float.
966 (let ((format (numeric-type-format y-type)))
967 (aver format)
968 (modified-numeric-type
969 y-type
970 :low (coerce-numeric-bound (interval-low bnd) format)
971 :high (coerce-numeric-bound (interval-high bnd) format))))
973 ;; A positive rational to a number is a number (for now).
974 (specifier-type 'number))))
975 ((csubtypep x-type (specifier-type 'float))
976 ;; a float to some power
977 (case (numeric-type-class y-type)
978 ((or integer rational)
979 ;; A positive float to an integer or rational power is
980 ;; always a float.
981 (let ((format (numeric-type-format x-type)))
982 (aver format)
983 (make-numeric-type
984 :class 'float
985 :format format
986 :low (coerce-numeric-bound (interval-low bnd) format)
987 :high (coerce-numeric-bound (interval-high bnd) format))))
988 (float
989 ;; A positive float to a float power is a float of the
990 ;; higher type.
991 (let ((format (float-format-max (numeric-type-format x-type)
992 (numeric-type-format y-type))))
993 (aver format)
994 (make-numeric-type
995 :class 'float
996 :format format
997 :low (coerce-numeric-bound (interval-low bnd) format)
998 :high (coerce-numeric-bound (interval-high bnd) format))))
1000 ;; A positive float to a number is a number (for now)
1001 (specifier-type 'number))))
1003 ;; A number to some power is a number.
1004 (specifier-type 'number))))
1006 (defun merged-interval-expt (x y)
1007 (let* ((x-int (numeric-type->interval x))
1008 (y-int (numeric-type->interval y)))
1009 (mapcar (lambda (type)
1010 (fixup-interval-expt type x-int y-int x y))
1011 (flatten-list (interval-expt x-int y-int)))))
1013 (defun integer-float-p (float)
1014 (and (floatp float)
1015 (multiple-value-bind (significand exponent) (integer-decode-float float)
1016 (or (plusp exponent)
1017 (<= (- exponent) (sb-kernel::first-bit-set significand))))))
1019 (defun expt-derive-type-aux (x y same-arg)
1020 (declare (ignore same-arg))
1021 (cond ((or (not (numeric-type-real-p x))
1022 (not (numeric-type-real-p y)))
1023 ;; Use numeric contagion if either is not real.
1024 (numeric-contagion x y))
1025 ((or (csubtypep y (specifier-type 'integer))
1026 (integer-float-p (nth-value 1 (type-singleton-p y))))
1027 ;; A real raised to an integer power is well-defined.
1028 (merged-interval-expt x y))
1029 ;; A real raised to a non-integral power can be a float or a
1030 ;; complex number.
1031 ((csubtypep x (specifier-type '(real 0)))
1032 ;; But a positive real to any power is well-defined.
1033 (merged-interval-expt x y))
1034 ((and (csubtypep x (specifier-type 'rational))
1035 (csubtypep y (specifier-type 'rational)))
1036 ;; A rational to the power of a rational could be a rational
1037 ;; or a possibly-complex single float
1038 (specifier-type '(or rational single-float (complex single-float))))
1040 ;; a real to some power. The result could be a real or a
1041 ;; complex.
1042 (float-or-complex-float-type (numeric-contagion x y)))))
1044 (defoptimizer (expt derive-type) ((x y))
1045 (two-arg-derive-type x y #'expt-derive-type-aux #'expt))
1047 ;;; Note we must assume that a type including 0.0 may also include
1048 ;;; -0.0 and thus the result may be complex -infinity + i*pi.
1049 (defun log-derive-type-aux-1 (x)
1050 (elfun-derive-type-simple x #'log $0d0 nil
1051 ;; (log 0) is an error
1052 ;; and there's nothing between 0 and 1 for integers.
1053 (and (integer-type-p x)
1054 $0f0)
1055 nil))
1057 (defun log-derive-type-aux-2 (x y same-arg)
1058 (let ((log-x (log-derive-type-aux-1 x))
1059 (log-y (log-derive-type-aux-1 y))
1060 (accumulated-list nil))
1061 ;; LOG-X or LOG-Y might be union types. We need to run through
1062 ;; the union types ourselves because /-DERIVE-TYPE-AUX doesn't.
1063 (dolist (x-type (prepare-arg-for-derive-type log-x))
1064 (dolist (y-type (prepare-arg-for-derive-type log-y))
1065 (push (/-derive-type-aux x-type y-type same-arg) accumulated-list)))
1066 (apply #'type-union (flatten-list accumulated-list))))
1068 (defoptimizer (log derive-type) ((x &optional y))
1069 (if y
1070 (two-arg-derive-type x y #'log-derive-type-aux-2 #'log)
1071 (one-arg-derive-type x #'log-derive-type-aux-1 #'log)))
1073 (defun atan-derive-type-aux-1 (y)
1074 (elfun-derive-type-simple y #'atan nil nil (sb-xc:- (sb-xc:/ pi 2)) (sb-xc:/ pi 2)))
1076 (defun atan-derive-type-aux-2 (y x same-arg)
1077 (declare (ignore same-arg))
1078 ;; The hard case with two args. We just return the max bounds.
1079 (let ((result-type (numeric-contagion y x)))
1080 (cond ((and (numeric-type-real-p x)
1081 (numeric-type-real-p y))
1082 (let* (;; FIXME: This expression for FORMAT seems to
1083 ;; appear multiple times, and should be factored out.
1084 (format (case (numeric-type-class result-type)
1085 ((integer rational) 'single-float)
1086 (t (numeric-type-format result-type))))
1087 (bound-format (or format 'float)))
1088 (make-numeric-type :class 'float
1089 :format format
1090 :complexp :real
1091 :low (coerce (sb-xc:- pi) bound-format)
1092 :high (coerce pi bound-format))))
1094 ;; The result is a float or a complex number
1095 (float-or-complex-float-type result-type)))))
1097 (defoptimizer (atan derive-type) ((y &optional x))
1098 (if x
1099 (two-arg-derive-type y x #'atan-derive-type-aux-2 #'atan)
1100 (one-arg-derive-type y #'atan-derive-type-aux-1 #'atan)))
1102 (defun cosh-derive-type-aux (x)
1103 ;; We note that cosh x = cosh |x| for all real x.
1104 (elfun-derive-type-simple
1105 (if (numeric-type-real-p x)
1106 (abs-derive-type-aux x)
1108 #'cosh nil nil 0 nil))
1110 (defoptimizer (cosh derive-type) ((num))
1111 (one-arg-derive-type num #'cosh-derive-type-aux #'cosh))
1113 (defun phase-derive-type-aux (arg)
1114 (let* ((format (case (numeric-type-class arg)
1115 ((integer rational) 'single-float)
1116 (t (numeric-type-format arg))))
1117 (bound-type (or format 'float)))
1118 (cond ((numeric-type-real-p arg)
1119 (case (interval-range-info> (numeric-type->interval arg) $0.0)
1121 ;; The number is positive, so the phase is 0.
1122 (make-numeric-type :class 'float
1123 :format format
1124 :complexp :real
1125 :low (coerce 0 bound-type)
1126 :high (coerce 0 bound-type)))
1128 ;; The number is always negative, so the phase is pi.
1129 (make-numeric-type :class 'float
1130 :format format
1131 :complexp :real
1132 :low (coerce pi bound-type)
1133 :high (coerce pi bound-type)))
1135 ;; We can't tell. The result is 0 or pi. Use a union
1136 ;; type for this.
1137 (list
1138 (make-numeric-type :class 'float
1139 :format format
1140 :complexp :real
1141 :low (coerce 0 bound-type)
1142 :high (coerce 0 bound-type))
1143 (make-numeric-type :class 'float
1144 :format format
1145 :complexp :real
1146 :low (coerce pi bound-type)
1147 :high (coerce pi bound-type))))))
1149 ;; We have a complex number. The answer is the range -pi
1150 ;; to pi. (-pi is included because we have -0.)
1151 (make-numeric-type :class 'float
1152 :format format
1153 :complexp :real
1154 :low (coerce (sb-xc:- pi) bound-type)
1155 :high (coerce pi bound-type))))))
1157 (defoptimizer (phase derive-type) ((num))
1158 (one-arg-derive-type num #'phase-derive-type-aux #'phase))
1160 (deftransform realpart ((x) ((complex rational)) * :important nil)
1161 '(%realpart x))
1162 (deftransform imagpart ((x) ((complex rational)) * :important nil)
1163 '(%imagpart x))
1165 (deftransform realpart ((x) (real) * :important nil)
1167 (deftransform imagpart ((x) ((and single-float (not (eql $-0f0)))) * :important nil)
1168 $0f0)
1169 (deftransform imagpart ((x) ((and double-float (not (eql $-0d0)))) * :important nil)
1170 $0d0)
1172 ;;; Make REALPART and IMAGPART return the appropriate types. This
1173 ;;; should help a lot in optimized code.
1174 (defun realpart-derive-type-aux (type)
1175 (let ((class (numeric-type-class type))
1176 (format (numeric-type-format type)))
1177 (cond ((numeric-type-real-p type)
1178 ;; The realpart of a real has the same type and range as
1179 ;; the input.
1180 (make-numeric-type :class class
1181 :format format
1182 :complexp :real
1183 :low (numeric-type-low type)
1184 :high (numeric-type-high type)))
1186 ;; We have a complex number. The result has the same type
1187 ;; as the real part, except that it's real, not complex,
1188 ;; obviously.
1189 (make-numeric-type :class class
1190 :format format
1191 :complexp :real
1192 :low (numeric-type-low type)
1193 :high (numeric-type-high type))))))
1195 (defoptimizer (realpart derive-type) ((num))
1196 (one-arg-derive-type num #'realpart-derive-type-aux #'realpart))
1198 (defun imagpart-derive-type-aux (type)
1199 (let ((class (numeric-type-class type))
1200 (format (numeric-type-format type)))
1201 (cond ((numeric-type-real-p type)
1202 ;; The imagpart of a real has the same type as the input,
1203 ;; except that it's zero.
1204 (let ((bound-format (or format class 'real)))
1205 (make-numeric-type :class class
1206 :format format
1207 :complexp :real
1208 :low (coerce 0 bound-format)
1209 :high (coerce 0 bound-format))))
1211 ;; We have a complex number. The result has the same type as
1212 ;; the imaginary part, except that it's real, not complex,
1213 ;; obviously.
1214 (make-numeric-type :class class
1215 :format format
1216 :complexp :real
1217 :low (numeric-type-low type)
1218 :high (numeric-type-high type))))))
1220 (defoptimizer (imagpart derive-type) ((num))
1221 (one-arg-derive-type num #'imagpart-derive-type-aux #'imagpart))
1223 (defun complex-derive-type-aux-1 (re-type)
1224 (if (numeric-type-p re-type)
1225 (make-numeric-type :class (numeric-type-class re-type)
1226 :format (numeric-type-format re-type)
1227 :complexp (if (csubtypep re-type
1228 (specifier-type 'rational))
1229 :real
1230 :complex)
1231 :low (numeric-type-low re-type)
1232 :high (numeric-type-high re-type))
1233 (specifier-type 'complex)))
1235 (defun complex-derive-type-aux-2 (re-type im-type same-arg)
1236 (declare (ignore same-arg))
1237 (if (and (numeric-type-p re-type)
1238 (numeric-type-p im-type))
1239 ;; Need to check to make sure numeric-contagion returns the
1240 ;; right type for what we want here.
1242 ;; Also, what about rational canonicalization, like (complex 5 0)
1243 ;; is 5? So, if the result must be complex, we make it so.
1244 ;; If the result might be complex, which happens only if the
1245 ;; arguments are rational, we make it a union type of (or
1246 ;; rational (complex rational)).
1247 (let* ((element-type (numeric-contagion re-type im-type))
1248 (maybe-rat-result-p (types-equal-or-intersect
1249 element-type (specifier-type 'rational)))
1250 (definitely-rat-result-p (csubtypep element-type (specifier-type 'rational)))
1251 (real-result-p (and definitely-rat-result-p
1252 (csubtypep im-type (specifier-type '(eql 0))))))
1253 (cond
1254 (real-result-p re-type)
1255 (maybe-rat-result-p
1256 (type-union element-type
1257 (specifier-type
1258 `(complex ,(numeric-type-class element-type)))))
1260 (make-numeric-type :class (numeric-type-class element-type)
1261 :format (numeric-type-format element-type)
1262 :complexp (if definitely-rat-result-p
1263 :real
1264 :complex)))))
1265 (specifier-type 'complex)))
1267 (defoptimizer (complex derive-type) ((re &optional im))
1268 (if im
1269 (two-arg-derive-type re im #'complex-derive-type-aux-2 #'complex)
1270 (one-arg-derive-type re #'complex-derive-type-aux-1 #'complex)))
1272 ;;; Define some transforms for complex operations in lieu of complex operation
1273 ;;; VOPs for most backends. If vops exist, they must support the following
1274 ;;; on complex-single-float and complex-double-float:
1275 ;;; * real-complex, complex-real and complex-complex addition and subtraction
1276 ;;; * complex-real and real-complex multiplication
1277 ;;; * complex-real division
1278 ;;; * sb-vm::swap-complex, which swaps the real and imaginary parts.
1279 ;;; * conjugate
1280 ;;; * complex-real, real-complex and complex-complex CL:=
1281 ;;; (complex-complex EQL would usually be a good idea).
1282 (macrolet ((frob (type contagion)
1283 `(progn
1284 (deftransform complex ((r) (,type))
1285 '(complex r ,(coerce 0 type)))
1286 (deftransform complex ((r i) (,type ,contagion))
1287 (when (csubtypep (lvar-type i) (specifier-type ',type))
1288 (give-up-ir1-transform))
1289 '(complex r (truly-the ,type (coerce i ',type))))
1290 (deftransform complex ((r i) (,contagion ,type))
1291 (when (csubtypep (lvar-type r) (specifier-type ',type))
1292 (give-up-ir1-transform))
1293 '(complex (truly-the ,type (coerce r ',type)) i))
1295 ;; Arbitrarily use %NEGATE/COMPLEX-DOUBLE-FLOAT as an indicator
1296 ;; of whether all the operations below are translated by vops.
1297 ;; We could be more fine-grained, but it seems reasonable that
1298 ;; they be implemented on an all-or-none basis.
1299 (unless (vop-existsp :named sb-vm::%negate/complex-double-float)
1300 ;; negation
1301 (deftransform %negate ((z) ((complex ,type)) * :important nil)
1302 '(complex (%negate (realpart z)) (%negate (imagpart z))))
1303 ;; complex addition and subtraction
1304 (deftransform + ((w z) ((complex ,type) (complex ,type)) * :important nil)
1305 '(complex (+ (realpart w) (realpart z))
1306 (+ (imagpart w) (imagpart z))))
1307 (deftransform - ((w z) ((complex ,type) (complex ,type)) * :important nil)
1308 '(complex (- (realpart w) (realpart z))
1309 (- (imagpart w) (imagpart z))))
1310 ;; Add and subtract a complex and a real.
1311 (deftransform + ((w z) ((complex ,type) real) * :important nil)
1312 `(complex (+ (realpart w) z)
1313 (+ (imagpart w) ,(coerce 0 ',type))))
1314 (deftransform + ((z w) (real (complex ,type)) * :important nil)
1315 `(complex (+ (realpart w) z)
1316 (+ (imagpart w) ,(coerce 0 ',type))))
1317 ;; Add and subtract a real and a complex number.
1318 (deftransform - ((w z) ((complex ,type) real) * :important nil)
1319 `(complex (- (realpart w) z)
1320 (- (imagpart w) ,(coerce 0 ',type))))
1321 (deftransform - ((z w) (real (complex ,type)) * :important nil)
1322 `(complex (- z (realpart w))
1323 (- ,(coerce 0 ',type) (imagpart w))))
1324 ;; Multiply a complex by a real or vice versa.
1325 (deftransform * ((w z) ((complex ,type) real) * :important nil)
1326 '(complex (* (realpart w) z) (* (imagpart w) z)))
1327 (deftransform * ((z w) (real (complex ,type)) * :important nil)
1328 '(complex (* (realpart w) z) (* (imagpart w) z)))
1329 ;; conjugate of complex number
1330 (deftransform conjugate ((z) ((complex ,type)) * :important nil)
1331 '(complex (realpart z) (- (imagpart z))))
1332 ;; comparison
1333 (deftransform = ((w z) ((complex ,type) (complex ,type)) * :important nil)
1334 '(and (= (realpart w) (realpart z))
1335 (= (imagpart w) (imagpart z))))
1336 (deftransform = ((w z) ((complex ,type) real) * :important nil)
1337 '(and (= (realpart w) z) (zerop (imagpart w))))
1338 (deftransform = ((w z) (real (complex ,type)) * :important nil)
1339 '(and (= (realpart z) w) (zerop (imagpart z))))
1340 ;; Multiply two complex numbers.
1341 (deftransform * ((x y) ((complex ,type) (complex ,type)) * :important nil)
1342 '(let* ((rx (realpart x))
1343 (ix (imagpart x))
1344 (ry (realpart y))
1345 (iy (imagpart y)))
1346 (complex (- (* rx ry) (* ix iy))
1347 (+ (* rx iy) (* ix ry)))))
1348 ;; Divide a complex by a real.
1349 (deftransform / ((w z) ((complex ,type) real) * :important nil)
1350 '(complex (/ (realpart w) z) (/ (imagpart w) z)))
1353 ;; Divide two complex numbers.
1354 (deftransform / ((x y) ((complex ,type) (complex ,type)) * :important nil)
1355 (if (vop-existsp :translate sb-vm::swap-complex)
1356 '(let* ((cs (conjugate (sb-vm::swap-complex x)))
1357 (ry (realpart y))
1358 (iy (imagpart y)))
1359 (if (> (abs ry) (abs iy))
1360 (let* ((r (/ iy ry))
1361 (dn (+ ry (* r iy))))
1362 (/ (+ x (* cs r)) dn))
1363 (let* ((r (/ ry iy))
1364 (dn (+ iy (* r ry))))
1365 (/ (+ (* x r) cs) dn))))
1366 '(let* ((rx (realpart x))
1367 (ix (imagpart x))
1368 (ry (realpart y))
1369 (iy (imagpart y)))
1370 (if (> (abs ry) (abs iy))
1371 (let* ((r (/ iy ry))
1372 (dn (+ ry (* r iy))))
1373 (complex (/ (+ rx (* ix r)) dn)
1374 (/ (- ix (* rx r)) dn)))
1375 (let* ((r (/ ry iy))
1376 (dn (+ iy (* r ry))))
1377 (complex (/ (+ (* rx r) ix) dn)
1378 (/ (- (* ix r) rx) dn)))))))
1379 ;; Divide a real by a complex.
1380 (deftransform / ((x y) (real (complex ,type)) * :important nil)
1381 (if (vop-existsp :translate sb-vm::swap-complex)
1382 '(let* ((ry (realpart y))
1383 (iy (imagpart y)))
1384 (if (> (abs ry) (abs iy))
1385 (let* ((r (/ iy ry))
1386 (dn (+ ry (* r iy))))
1387 (/ (complex x (- (* x r))) dn))
1388 (let* ((r (/ ry iy))
1389 (dn (+ iy (* r ry))))
1390 (/ (complex (* x r) (- x)) dn))))
1391 '(let* ((ry (realpart y))
1392 (iy (imagpart y)))
1393 (if (> (abs ry) (abs iy))
1394 (let* ((r (/ iy ry))
1395 (dn (+ ry (* r iy))))
1396 (complex (/ x dn)
1397 (/ (- (* x r)) dn)))
1398 (let* ((r (/ ry iy))
1399 (dn (+ iy (* r ry))))
1400 (complex (/ (* x r) dn)
1401 (/ (- x) dn)))))))
1402 ;; CIS
1403 (deftransform cis ((z) ((,type)) *)
1404 '(complex (cos z) (sin z)))
1406 (frob single-float (or rational single-float))
1407 (frob double-float (or rational single-float double-float)))
1410 ;;;; float contagion
1411 (deftransform single-float-real-contagion ((x y) * * :node node :defun-only t)
1412 (if (csubtypep (lvar-type y) (specifier-type 'single-float))
1413 (give-up-ir1-transform)
1414 `(,(lvar-fun-name (basic-combination-fun node)) x (%single-float y))))
1416 (deftransform real-single-float-contagion ((x y) * * :node node :defun-only t)
1417 (if (csubtypep (lvar-type x) (specifier-type 'single-float))
1418 (give-up-ir1-transform)
1419 `(,(lvar-fun-name (basic-combination-fun node)) (%single-float x) y)))
1421 (deftransform double-float-real-contagion ((x y) * * :node node :defun-only t)
1422 (if (csubtypep (lvar-type y) (specifier-type 'double-float))
1423 (give-up-ir1-transform)
1424 `(,(lvar-fun-name (basic-combination-fun node)) x (%double-float y))))
1426 (deftransform real-double-float-contagion ((x y) * * :node node :defun-only t)
1427 (if (csubtypep (lvar-type x) (specifier-type 'double-float))
1428 (give-up-ir1-transform)
1429 `(,(lvar-fun-name (basic-combination-fun node)) (%double-float x) y)))
1431 (deftransform double-float-real-contagion-cmp ((x y) * * :node node :defun-only t)
1432 (cond ((csubtypep (lvar-type y) (specifier-type 'double-float))
1433 (give-up-ir1-transform))
1434 ;; Turn (= single-float 1d0) into (= single-float 1f0)
1435 ((and (constant-lvar-p x)
1436 (csubtypep (lvar-type y) (specifier-type 'single-float))
1437 (let ((x (lvar-value x)))
1438 (when (and (safe-single-coercion-p x)
1439 (= x (coerce x 'single-float)))
1440 `(,(lvar-fun-name (basic-combination-fun node)) ,(coerce x 'single-float) y)))))
1442 `(,(lvar-fun-name (basic-combination-fun node)) x (%double-float y)))))
1444 (deftransform real-double-float-contagion-cmp ((x y) * * :node node :defun-only t)
1445 (cond ((csubtypep (lvar-type x) (specifier-type 'double-float))
1446 (give-up-ir1-transform))
1447 ((and (constant-lvar-p y)
1448 (csubtypep (lvar-type x) (specifier-type 'single-float))
1449 (let ((y (lvar-value y)))
1450 (when (and (safe-single-coercion-p y)
1451 (= y (coerce y 'single-float)))
1452 `(,(lvar-fun-name (basic-combination-fun node)) x ,(coerce y 'single-float))))))
1454 `(,(lvar-fun-name (basic-combination-fun node)) (%double-float x) y))))
1456 (flet ((def (op)
1457 (%deftransform op nil '(function (single-float real) single-float)
1458 #'single-float-real-contagion nil)
1459 (%deftransform op nil '(function (real single-float) single-float)
1460 #'real-single-float-contagion nil)
1461 (%deftransform op nil '(function (double-float real))
1462 #'double-float-real-contagion nil)
1463 (%deftransform op nil '(function (real double-float))
1464 #'real-double-float-contagion nil)
1466 (%deftransform op nil '(function ((complex single-float) real) (complex single-float))
1467 #'single-float-real-contagion nil)
1468 (%deftransform op nil '(function (real (complex single-float)) (complex single-float))
1469 #'real-single-float-contagion nil)
1470 (%deftransform op nil '(function ((complex double-float) real) (complex double-float))
1471 #'double-float-real-contagion nil)
1472 (%deftransform op nil '(function (real (complex double-float)) (complex double-float))
1473 #'real-double-float-contagion nil)))
1474 (dolist (op '(+ * / -))
1475 (def op)))
1477 (flet ((def (op)
1478 (%deftransform op nil `(function (single-float (integer ,most-negative-exactly-single-float-integer
1479 ,most-positive-exactly-single-float-integer)))
1480 #'single-float-real-contagion nil)
1481 (%deftransform op nil `(function ((integer ,most-negative-exactly-single-float-integer
1482 ,most-positive-exactly-single-float-integer)
1483 single-float))
1484 #'real-single-float-contagion nil)
1486 (%deftransform op nil `(function (double-float
1487 (or single-float
1488 (integer ,most-negative-exactly-double-float-integer
1489 ,most-positive-exactly-double-float-integer))))
1490 #'double-float-real-contagion-cmp nil)
1491 (%deftransform op nil `(function ((or single-float
1492 (integer ,most-negative-exactly-double-float-integer
1493 ,most-positive-exactly-double-float-integer))
1494 double-float))
1495 #'real-double-float-contagion-cmp nil)))
1496 (dolist (op '(= < > <= >=))
1497 (def op)))
1499 (%deftransform '= nil '(function ((complex double-float) single-float))
1500 #'double-float-real-contagion nil)
1501 (%deftransform '= nil '(function (single-float (complex double-float)))
1502 #'real-double-float-contagion nil)
1504 (deftransform complex ((realpart &optional imagpart) (rational &optional (or null (integer 0 0))) * :important nil)
1505 'realpart)
1507 ;;; Here are simple optimizers for SIN, COS, and TAN. They do not
1508 ;;; produce a minimal range for the result; the result is the widest
1509 ;;; possible answer. This gets around the problem of doing range
1510 ;;; reduction correctly but still provides useful results when the
1511 ;;; inputs are union types.
1512 (defun trig-derive-type-aux (arg domain fun
1513 &optional def-lo def-hi (increasingp t))
1514 (etypecase arg
1515 (numeric-type
1516 (flet ((floatify-format ()
1517 (case (numeric-type-class arg)
1518 ((integer rational) 'single-float)
1519 (t (numeric-type-format arg)))))
1520 (cond ((eq (numeric-type-complexp arg) :complex)
1521 (make-numeric-type :class 'float
1522 :format (floatify-format)
1523 :complexp :complex))
1524 ((numeric-type-real-p arg)
1525 (let* ((format (floatify-format))
1526 (bound-type (or format 'float)))
1527 ;; If the argument is a subset of the "principal" domain
1528 ;; of the function, we can compute the bounds because
1529 ;; the function is monotonic. We can't do this in
1530 ;; general for these periodic functions because we can't
1531 ;; (and don't want to) do the argument reduction in
1532 ;; exactly the same way as the functions themselves do
1533 ;; it.
1534 (if (csubtypep arg domain)
1535 (let ((res-lo (bound-func fun (numeric-type-low arg) nil))
1536 (res-hi (bound-func fun (numeric-type-high arg) nil)))
1537 (unless increasingp
1538 (rotatef res-lo res-hi))
1539 (make-numeric-type
1540 :class 'float
1541 :format format
1542 :low (coerce-numeric-bound res-lo bound-type)
1543 :high (coerce-numeric-bound res-hi bound-type)))
1544 (make-numeric-type
1545 :class 'float
1546 :format format
1547 :low (and def-lo (coerce def-lo bound-type))
1548 :high (and def-hi (coerce def-hi bound-type))))))
1550 (float-or-complex-float-type arg def-lo def-hi)))))))
1552 (defoptimizer (sin derive-type) ((num))
1553 (one-arg-derive-type
1555 (lambda (arg)
1556 ;; Derive the bounds if the arg is in [-pi/2, pi/2].
1557 (trig-derive-type-aux
1559 (specifier-type `(float ,(sb-xc:- (sb-xc:/ pi 2)) ,(sb-xc:/ pi 2)))
1560 #'sin
1561 -1 1))
1562 #'sin))
1564 (defoptimizer (cos derive-type) ((num))
1565 (one-arg-derive-type
1567 (lambda (arg)
1568 ;; Derive the bounds if the arg is in [0, pi].
1569 (trig-derive-type-aux arg
1570 (specifier-type `(float $0d0 ,pi))
1571 #'cos
1572 -1 1
1573 nil))
1574 #'cos))
1576 (defoptimizer (tan derive-type) ((num))
1577 (one-arg-derive-type
1579 (lambda (arg)
1580 ;; Derive the bounds if the arg is in [-pi/2, pi/2].
1581 (trig-derive-type-aux arg
1582 (specifier-type `(float ,(sb-xc:- (sb-xc:/ pi 2))
1583 ,(sb-xc:/ pi 2)))
1584 #'tan
1585 nil nil))
1586 #'tan))
1588 (defoptimizer (conjugate derive-type) ((num))
1589 (one-arg-derive-type num
1590 (lambda (arg)
1591 (flet ((most-negative-bound (l h)
1592 (and l h
1593 (if (< (type-bound-number l) (- (type-bound-number h)))
1595 (set-bound (- (type-bound-number h)) (consp h)))))
1596 (most-positive-bound (l h)
1597 (and l h
1598 (if (> (type-bound-number h) (- (type-bound-number l)))
1600 (set-bound (- (type-bound-number l)) (consp l))))))
1601 (if (numeric-type-real-p arg)
1602 (lvar-type num)
1603 (let ((low (numeric-type-low arg))
1604 (high (numeric-type-high arg)))
1605 (let ((new-low (most-negative-bound low high))
1606 (new-high (most-positive-bound low high)))
1607 (modified-numeric-type arg :low new-low :high new-high))))))
1608 #'conjugate))
1610 (defoptimizer (cis derive-type) ((num))
1611 (one-arg-derive-type num
1612 (lambda (arg)
1613 (specifier-type
1614 `(complex ,(or (numeric-type-format arg) 'float))))
1615 #'cis))
1618 ;;;; TRUNCATE, FLOOR, CEILING, and ROUND
1619 (deftransform truncate ((x &optional by)
1620 (t &optional (constant-arg (member 1))))
1621 '(unary-truncate x))
1623 (deftransform round ((x &optional by)
1624 (t &optional (constant-arg (member 1))))
1625 '(let ((res (%unary-round x)))
1626 (values res (locally
1627 (declare (flushable %single-float
1628 %double-float))
1629 (- x res)))))
1631 (deftransform %unary-truncate ((x) (single-float))
1632 `(values (unary-truncate x)))
1633 (deftransform %unary-truncate ((x) (double-float))
1634 `(values (unary-truncate x)))
1636 (defun value-within-numeric-type (type)
1637 (labels ((try (x)
1638 (when (ctypep x type)
1639 (return-from value-within-numeric-type x)))
1640 (next-float (float)
1641 (multiple-value-bind (frac exp sign)
1642 (integer-decode-float float)
1643 (* (scale-float (float (1+ frac) float) exp)
1644 sign)))
1645 (prev-float (float)
1646 (multiple-value-bind (frac exp sign)
1647 (integer-decode-float float)
1648 (* (scale-float (float (1- frac) float) exp)
1649 sign)))
1650 (next (x)
1651 (typecase x
1652 (integer
1653 (1+ x))
1654 (float
1655 (next-float x))
1657 0)))
1658 (prev (x)
1659 (typecase x
1660 (integer
1661 (1- x))
1662 (float
1663 (prev-float x))
1665 0)))
1666 (ratio-between (low high)
1667 (+ low (/ (- high low) 2)))
1668 (numeric (x)
1669 (when (numeric-type-p x)
1670 (let ((lo (numeric-type-low x))
1671 (hi (numeric-type-high x)))
1672 (when (numberp lo)
1673 (try lo))
1674 (when (numberp hi)
1675 (try hi))
1676 (when (consp lo)
1677 (try (next (car lo))))
1678 (when (consp hi)
1679 (try (prev (car hi))))
1680 (when (and (typep lo '(cons rational))
1681 (typep hi '(cons rational)))
1682 (try (ratio-between (car lo) (car hi))))
1683 (when (csubtypep x (specifier-type 'rational))
1684 (try 0))
1685 (when (csubtypep x (specifier-type 'double-float))
1686 (try $0d0))
1687 (when (csubtypep x (specifier-type 'single-float))
1688 (try $0f0))))))
1689 (typecase type
1690 (numeric-type (numeric type))
1691 (union-type (mapc #'numeric (union-type-types type))))
1692 (error "Couldn't come up with a value for ~s" type)))
1694 #-(or sb-xc-host 64-bit)
1695 (progn
1696 (declaim (inline %make-double-float))
1697 (defun %make-double-float (bits)
1698 (make-double-float (ash bits -32) (ldb (byte 32 0) bits))))
1700 ;;; Transform inclusive integer bounds so that they work on floats
1701 ;;; before truncating to zero.
1702 (macrolet
1703 ((def (type)
1704 `(defun ,(symbolicate type '-integer-bounds) (low high)
1705 (macrolet ((const (name)
1706 (package-symbolicate :sb-vm ',type '- name)))
1707 (labels ((fractions-p (number)
1708 (< (integer-length (abs number))
1709 (const digits)))
1710 (c (number round)
1711 (if (zerop number)
1712 (sb-kernel:make-single-float 0)
1713 (let* ((negative (minusp number))
1714 (number (abs number))
1715 (length (integer-length number))
1716 (shift (- length (const digits)))
1717 (shifted (truly-the fixnum
1718 (ash number
1719 (- shift))))
1720 ;; Cut off the hidden bit
1721 (signif (ldb (const significand-byte) shifted))
1722 (exp (+ (const bias) length))
1723 (bits (ash exp
1724 (byte-position (const exponent-byte)))))
1725 (incf signif round)
1726 ;; If rounding up overflows this will increase the exponent too
1727 (let ((bits (+ bits signif)))
1728 (when negative
1729 (setf bits (logior (ash -1 ,(case type
1730 (double-float 63)
1731 (single-float 31)))
1732 bits)))
1733 (,(case type
1734 (single-float 'make-single-float)
1735 (double-float '%make-double-float)) bits))))))
1736 (values (if (<= low 0)
1737 (if (fractions-p low)
1738 (c (1- low) -1)
1739 (c low 0))
1740 (c low 0))
1741 (if (< high 0)
1742 (c high 0)
1743 (if (fractions-p high)
1744 (c (1+ high) -1)
1745 (c high 0)))))))))
1746 (def single-float)
1747 (def double-float))
1749 (deftransform unary-truncate ((x) * * :result result :node node)
1750 (unless (lvar-single-value-p result)
1751 (give-up-ir1-transform))
1752 (let ((rem-type (second (values-type-required (node-derived-type node)))))
1753 `(values (%unary-truncate x)
1754 ,(value-within-numeric-type rem-type))))
1756 (macrolet ((def (type)
1757 `(deftransform unary-truncate ((number) (,type) * :node node)
1758 (let ((cast (cast-or-check-bound-type node)))
1759 (if (and cast
1760 (csubtypep cast (specifier-type 'sb-vm:signed-word)))
1761 (let ((int (type-approximate-interval cast)))
1762 (when int
1763 (multiple-value-bind (low high) (,(symbolicate type '-integer-bounds)
1764 (interval-low int)
1765 (interval-high int))
1766 `(if (typep number
1767 '(,',type ,low ,high))
1768 (let ((truncated (truly-the ,(type-specifier cast) (,',(symbolicate '%unary-truncate/ type) number))))
1769 (declare (flushable ,',(symbolicate "%" type)))
1770 (values truncated
1771 (- number
1772 (coerce truncated ',',type))))
1773 ,(internal-type-error-call 'number (type-specifier cast) 'truncate-to-integer)))))
1774 '(if (typep number
1775 '(,type
1776 ,(symbol-value (package-symbolicate :sb-kernel 'most-negative-fixnum- type))
1777 ,(symbol-value (package-symbolicate :sb-kernel 'most-positive-fixnum- type))))
1778 (let ((truncated (truly-the fixnum (,(symbolicate '%unary-truncate/ type) number))))
1779 (declare (flushable ,(symbolicate "%" type)))
1780 (values truncated
1781 (- number
1782 (coerce truncated ',type))))
1783 (,(symbolicate 'unary-truncate- type '-to-bignum) number)))))))
1784 (def single-float)
1785 (def double-float))
1787 ;;; Convert (TRUNCATE x y) to the obvious implementation.
1789 ;;; ...plus hair: Insert explicit coercions to appropriate float types: Python
1790 ;;; is reluctant it generate explicit integer->float coercions due to
1791 ;;; precision issues (see SAFE-SINGLE-COERCION-P &co), but this is not an
1792 ;;; issue here as there is no DERIVE-TYPE optimizer on specialized versions of
1793 ;;; %UNARY-TRUNCATE, so the derived type of TRUNCATE remains the best we can
1794 ;;; do here -- which is fine. Also take care not to add unnecassary division
1795 ;;; or multiplication by 1, since we are not able to always eliminate them,
1796 ;;; depending on FLOAT-ACCURACY. Finally, leave out the secondary value when
1797 ;;; we know it is unused: COERCE is not flushable.
1798 (macrolet ((def (type other-float-arg-types)
1799 (let* ((unary (symbolicate "%UNARY-TRUNCATE/" type))
1800 (unary-to-bignum (symbolicate '%unary-truncate- type '-to-bignum))
1801 (coerce (symbolicate "%" type))
1802 (unary `(lambda (number)
1803 (if (typep number
1804 '(,type
1805 ,(symbol-value (package-symbolicate :sb-kernel 'most-negative-fixnum- type))
1806 ,(symbol-value (package-symbolicate :sb-kernel 'most-positive-fixnum- type))))
1807 (truly-the fixnum (,unary number))
1808 (,unary-to-bignum number)))))
1809 `(deftransform truncate ((x &optional y)
1810 (,type
1811 &optional (or ,type ,@other-float-arg-types integer))
1812 * :result result)
1813 (let* ((result-type (and result
1814 (lvar-derived-type result)))
1815 (compute-all (and (or (eq result-type *wild-type*)
1816 (values-type-p result-type))
1817 (not (type-single-value-p result-type)))))
1818 (if (or (not y)
1819 (and (constant-lvar-p y) (sb-xc:= 1 (lvar-value y))))
1820 (if compute-all
1821 `(unary-truncate x)
1822 `(let ((res (,',unary x)))
1823 ;; Dummy secondary value!
1824 (values res x)))
1825 (if compute-all
1826 `(let* ((f (,',coerce y))
1827 (div (/ x f))
1828 (res (,',unary div)))
1829 (values res
1830 (- x (* f
1831 #+round-float
1832 (- (,',(ecase type
1833 (double-float 'round-double)
1834 (single-float 'round-single))
1835 div :truncate)
1836 ,,(ecase type
1837 (double-float $-0.0d0)
1838 (single-float $-0.0f0)))
1839 #-round-float
1840 (locally
1841 (declare (flushable ,',coerce))
1842 (,',coerce res))))))
1843 `(let* ((f (,',coerce y))
1844 (res (,',unary (/ x f))))
1845 ;; Dummy secondary value!
1846 (values res x)))))))))
1847 (def single-float ())
1848 (def double-float (single-float)))
1850 ;;; truncate on bignum floats will always have a remainder of zero
1851 ;;; on 64-bit, so ceiling and floor are the same as truncate.
1852 #+64-bit
1853 (macrolet ((def (name type other-float-arg-types
1854 fixup)
1855 (let* ((unary (symbolicate "%UNARY-TRUNCATE/" type))
1856 (unary-to-bignum (symbolicate 'unary-truncate- type '-to-bignum))
1857 (coerce (symbolicate "%" type)))
1858 `(deftransform ,name ((number &optional divisor)
1859 (,type
1860 &optional (or ,type ,@other-float-arg-types integer))
1862 (block nil
1863 (let ((one-p (or (not divisor)
1864 (and (constant-lvar-p divisor) (sb-xc:= (lvar-value divisor) 1)))))
1865 #+round-float
1866 (when-vop-existsp (:translate %unary-ceiling)
1867 (when one-p
1868 (return
1869 `(if (typep number
1870 '(,',type
1871 ,',(symbol-value (package-symbolicate :sb-kernel 'most-negative-fixnum- type))
1872 ,',(symbol-value (package-symbolicate :sb-kernel 'most-positive-fixnum- type))))
1873 (values (truly-the fixnum (,',(symbolicate '%unary- name) number))
1874 (- number
1875 (,',(ecase type
1876 (double-float 'round-double)
1877 (single-float 'round-single))
1878 number ,,(keywordicate name))))
1879 (,',unary-to-bignum number)))))
1880 `(let* ,(if one-p
1881 `((f-divisor 1)
1882 (div number))
1883 `((f-divisor (,',coerce divisor))
1884 (div (/ number f-divisor))))
1885 (if (typep div
1886 '(,',type
1887 ,',(symbol-value (package-symbolicate :sb-kernel 'most-negative-fixnum- type))
1888 ,',(symbol-value (package-symbolicate :sb-kernel 'most-positive-fixnum- type))))
1889 (let* ((tru (truly-the fixnum (,',unary div)))
1890 (rem (- number (* ,@(unless one-p
1891 '(f-divisor))
1892 #+round-float
1893 (- (,',(ecase type
1894 (double-float 'round-double)
1895 (single-float 'round-single))
1896 div :truncate)
1897 ,,(ecase type
1898 (double-float $-0.0d0)
1899 (single-float $-0.0f0)))
1900 #-round-float
1901 (locally
1902 (declare (flushable ,',coerce))
1903 (,',coerce tru))))))
1904 ,',fixup)
1905 (,',unary-to-bignum div)))))))))
1906 (def floor single-float ()
1907 #1=(if (and (not (zerop rem))
1908 (if (minusp f-divisor)
1909 (plusp number)
1910 (minusp number)))
1911 (values
1912 ;; the above conditions wouldn't hold when tru is m-n-f
1913 (truly-the fixnum (1- tru))
1914 (+ rem f-divisor))
1915 (values tru rem)))
1916 (def floor double-float (single-float)
1917 #1#)
1918 (def ceiling single-float ()
1919 #2=(if (and (not (zerop rem))
1920 (if (minusp f-divisor)
1921 (minusp number)
1922 (plusp number)))
1923 (values (+ tru 1) (- rem f-divisor))
1924 (values tru rem)))
1925 (def ceiling double-float (single-float)
1926 #2#))
1928 #-64-bit
1929 (macrolet ((def (number-type divisor-type)
1930 `(progn
1931 (deftransform floor ((number divisor) (,number-type ,divisor-type) * :node node)
1932 `(let ((divisor (coerce divisor ',',number-type)))
1933 (multiple-value-bind (tru rem) (truncate number divisor)
1934 (if (and (not (zerop rem))
1935 (if (minusp divisor)
1936 (plusp number)
1937 (minusp number)))
1938 (values (1- tru) (+ rem divisor))
1939 (values tru rem)))))
1941 (deftransform ceiling ((number divisor) (,number-type ,divisor-type) * :node node)
1942 `(let ((divisor (coerce divisor ',',number-type)))
1943 (multiple-value-bind (tru rem) (truncate number divisor)
1944 (if (and (not (zerop rem))
1945 (if (minusp divisor)
1946 (minusp number)
1947 (plusp number)))
1948 (values (+ tru 1) (- rem divisor))
1949 (values tru rem))))))))
1950 (def double-float (or float integer))
1951 (def single-float (or single-float integer)))
1953 #-round-float
1954 (progn
1955 (defknown (%unary-ftruncate %unary-fround) (real) float (movable foldable flushable))
1956 #-64-bit
1957 (defknown (%unary-ftruncate/double %unary-fround/double) (double-float) double-float
1958 (movable foldable flushable))
1960 (deftransform %unary-ftruncate ((x) (single-float))
1961 `(cond ((or (typep x '(single-float ($-1f0) ($0f0)))
1962 (eql x $-0f0))
1963 $-0f0)
1964 ((typep x '(single-float ,(float (- (expt 2 sb-vm:single-float-digits)) $1f0)
1965 ,(float (1- (expt 2 sb-vm:single-float-digits)) $1f0)))
1966 (float (truncate x) $1f0))
1968 x)))
1970 (deftransform %unary-fround ((x) (single-float))
1971 `(cond ((or (typep x '(single-float $-0.5f0 ($0f0)))
1972 (eql x $-0f0))
1973 $-0f0)
1974 ((typep x '(single-float ,(float (- (expt 2 sb-vm:single-float-digits)) $1f0)
1975 ,(float (1- (expt 2 sb-vm:single-float-digits)) $1f0)))
1976 (float (round x) $1f0))
1978 x)))
1980 #+64-bit
1981 (progn
1982 (deftransform %unary-ftruncate ((x) (double-float))
1983 `(cond ((or (typep x '(double-float ($-1d0) ($0d0)))
1984 (eql x $-0d0))
1985 $-0d0)
1986 ((typep x '(double-float ,(float (- (expt 2 sb-vm:double-float-digits)) $1d0)
1987 ,(float (1- (expt 2 sb-vm:double-float-digits)) $1d0)))
1988 (float (truncate x) $1d0))
1990 x)))
1992 (deftransform %unary-fround ((x) (double-float))
1993 `(cond ((or (typep x '(double-float $-0.5d0 ($0d0)))
1994 (eql x $-0d0))
1995 $-0d0)
1996 ((typep x '(double-float ,(float (- (expt 2 sb-vm:double-float-digits)) $1d0)
1997 ,(float (1- (expt 2 sb-vm:double-float-digits)) $1d0)))
1998 (float (round x) $1d0))
2000 x))))
2002 #-64-bit
2003 (progn
2004 #-sb-xc-host
2005 (progn
2006 (defun %unary-ftruncate/double (x)
2007 (declare (muffle-conditions compiler-note))
2008 (declare (type double-float x))
2009 (declare (optimize speed (safety 0)))
2010 (let* ((high (double-float-high-bits x))
2011 (low (double-float-low-bits x))
2012 (exp (ldb sb-vm:double-float-hi-exponent-byte high))
2013 (biased (the double-float-exponent
2014 (- exp sb-vm:double-float-bias))))
2015 (declare (type (signed-byte 32) high)
2016 (type (unsigned-byte 32) low))
2017 (cond
2018 ((= exp sb-vm:double-float-normal-exponent-max) x)
2019 ((<= biased 0) (* x $0d0))
2020 ((>= biased (float-digits x)) x)
2022 (let ((frac-bits (- (float-digits x) biased)))
2023 (cond ((< frac-bits 32)
2024 (setf low (logandc2 low (- (ash 1 frac-bits) 1))))
2026 (setf low 0)
2027 (setf high (logandc2 high (- (ash 1 (- frac-bits 32)) 1)))))
2028 (make-double-float high low))))))
2029 (defun %unary-fround/double (x)
2030 (declare (muffle-conditions compiler-note))
2031 (declare (type double-float x))
2032 (declare (optimize speed (safety 0)))
2033 (let* ((high (double-float-high-bits x))
2034 (low (double-float-low-bits x))
2035 (exp (ldb sb-vm:double-float-hi-exponent-byte high))
2036 (biased (the double-float-exponent
2037 (- exp sb-vm:double-float-bias))))
2038 (declare (type (signed-byte 32) high)
2039 (type (unsigned-byte 32) low))
2040 (cond
2041 ((= exp sb-vm:double-float-normal-exponent-max) x)
2042 ((<= biased -1) (* x $0d0)) ; [0,0.5)
2043 ((and (= biased 0) (= low 0) (= (ldb sb-vm:double-float-hi-significand-byte high) 0)) ; [0.5,0.5]
2044 (* x $0d0))
2045 ((= biased 0) (float-sign x $1d0)) ; (0.5,1.0)
2046 ((= biased 1) ; [1.0,2.0)
2047 (cond
2048 ((>= (ldb sb-vm:double-float-hi-significand-byte high) (ash 1 19))
2049 (float-sign x $2d0))
2050 (t (float-sign x $1d0))))
2051 ((>= biased (float-digits x)) x)
2053 ;; it's probably possible to do something very contorted
2054 ;; to avoid consing intermediate bignums, by performing
2055 ;; arithmetic on the fractional part, the low integer
2056 ;; part, the high integer part, and the exponent of the
2057 ;; double float. But in the interest of getting
2058 ;; something correct to start with, delegate to ROUND.
2059 (float (round x) $1d0))))))
2060 (deftransform %unary-ftruncate ((x) (double-float))
2061 `(%unary-ftruncate/double x))
2062 (deftransform %unary-fround ((x) (double-float))
2063 `(%unary-fround/double x))))
2065 #+round-float
2066 (deftransform fround ((number &optional divisor) (double-float &optional t))
2067 (if (or (not divisor)
2068 (and (constant-lvar-p divisor)
2069 (= (lvar-value divisor) 1)))
2070 `(let ((res (round-double number :round)))
2071 (values res (- number res)))
2072 `(let* ((divisor (%double-float divisor))
2073 (res (round-double (/ number (%double-float divisor)) :round)))
2074 (values res (- number (* res divisor))))))
2076 #+round-float
2077 (deftransform fround ((number &optional divisor) (single-float &optional (or null single-float rational)))
2078 (if (or (not divisor)
2079 (and (constant-lvar-p divisor)
2080 (= (lvar-value divisor) 1)))
2081 `(let ((res (round-single number :round)))
2082 (values res (- number res)))
2083 `(let* ((divisor (%single-float divisor))
2084 (res (round-single (/ number divisor) :round)))
2085 (values res (- number (* res divisor))))))
2087 ;;;; TESTS
2089 ;;; Dumping of double-float literals in genesis got some bits messed up,
2090 ;;; but only if the double-float was the value of a slot in a ctype instance.
2091 ;;; It was broken for either endianness, but miraculously didn't crash
2092 ;;; for little-endian builds even though it could have.
2093 ;;; (The dumped constants were legal normalalized float bit patterns, albeit wrong)
2094 ;;; For 32-bit big-endian machines, the bit patterns were those of subnormals.
2095 ;;; So thank goodness for that - it allowed detection of the problem.
2096 (defun test-ctype-involving-double-float ()
2097 (specifier-type '(double-float #.pi)))
2098 (assert (sb-xc:= (numeric-type-low (test-ctype-involving-double-float)) pi))
2100 ;;; Dummy functions to test that complex number are dumped correctly in genesis.
2101 (defun try-folding-complex-single ()
2102 (let ((re (make-single-float #x4E000000))
2103 (im (make-single-float #x-21800000)))
2104 (values (complex re im)
2105 (locally (declare (notinline complex)) (complex re im)))))
2107 (defun try-folding-complex-double ()
2108 (let ((re (make-double-float #X3FE62E42 #xFEFA39EF))
2109 (im (make-double-float #X43CFFFFF #XFFFFFFFF)))
2110 (values (complex re im)
2111 (locally (declare (notinline complex)) (complex re im)))))
2113 #-sb-xc-host
2114 (dolist (test '(try-folding-complex-single try-folding-complex-double))
2115 (multiple-value-bind (a b) (funcall test)
2116 (assert (eql a b)))
2117 (let ((code (fun-code-header (symbol-function test))))
2118 (aver (loop for index from sb-vm:code-constants-offset
2119 below (code-header-words code)
2120 thereis (typep (code-header-ref code index) 'complex))))
2121 (fmakunbound test))
2123 (defun more-folding ()
2124 (values (complex single-float-positive-infinity single-float-positive-infinity)
2125 (complex single-float-negative-infinity single-float-positive-infinity)
2126 (complex single-float-negative-infinity single-float-negative-infinity)
2127 (complex single-float-positive-infinity single-float-negative-infinity)))
2129 #-sb-xc-host
2130 (multiple-value-bind (a b c d) (funcall 'more-folding)
2131 (assert (sb-ext:float-infinity-p (realpart a)))
2132 (assert (sb-ext:float-infinity-p (imagpart a)))
2133 (assert (sb-ext:float-infinity-p (realpart b)))
2134 (assert (sb-ext:float-infinity-p (imagpart b)))
2135 (assert (sb-ext:float-infinity-p (realpart c)))
2136 (assert (sb-ext:float-infinity-p (imagpart c)))
2137 (assert (sb-ext:float-infinity-p (realpart d)))
2138 (assert (sb-ext:float-infinity-p (imagpart d)))
2139 (let ((code (fun-code-header (symbol-function 'more-folding))))
2140 (aver (loop for index from sb-vm:code-constants-offset
2141 below (code-header-words code)
2142 thereis (typep (code-header-ref code index) 'complex))))
2143 (fmakunbound 'more-folding))