c808988499c711bd19b13aba32bafd4761a24a64
[sbcl.git] / src / compiler / srctran.lisp
1 ;;;; This file contains macro-like source transformations which
2 ;;;; convert uses of certain functions into the canonical form desired
3 ;;;; within the compiler. FIXME: and other IR1 transforms and stuff.
4
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.
13
14 (in-package "SB!C")
15
16 ;;; We turn IDENTITY into PROG1 so that it is obvious that it just
17 ;;; returns the first value of its argument. Ditto for VALUES with one
18 ;;; arg.
19 (define-source-transform identity (x) `(prog1 ,x))
20 (define-source-transform values (x) `(prog1 ,x))
21
22 ;;; CONSTANTLY is pretty much never worth transforming, but it's good to get the type.
23 (defoptimizer (constantly derive-type) ((value))
24   (specifier-type
25    `(function (&rest t) (values ,(type-specifier (lvar-type value)) &optional))))
26
27 ;;; If the function has a known number of arguments, then return a
28 ;;; lambda with the appropriate fixed number of args. If the
29 ;;; destination is a FUNCALL, then do the &REST APPLY thing, and let
30 ;;; MV optimization figure things out.
31 (deftransform complement ((fun) * * :node node)
32   "open code"
33   (multiple-value-bind (min max)
34       (fun-type-nargs (lvar-type fun))
35     (cond
36      ((and min (eql min max))
37       (let ((dums (make-gensym-list min)))
38         `#'(lambda ,dums (not (funcall fun ,@dums)))))
39      ((awhen (node-lvar node)
40         (let ((dest (lvar-dest it)))
41           (and (combination-p dest)
42                (eq (combination-fun dest) it))))
43       '#'(lambda (&rest args)
44            (not (apply fun args))))
45      (t
46       (give-up-ir1-transform
47        "The function doesn't have a fixed argument count.")))))
48 \f
49 ;;;; SYMBOL-VALUE &co
50 (defun derive-symbol-value-type (lvar node)
51   (if (constant-lvar-p lvar)
52       (let* ((sym (lvar-value lvar))
53              (var (maybe-find-free-var sym))
54              (local-type (when var
55                            (let ((*lexenv* (node-lexenv node)))
56                              (lexenv-find var type-restrictions))))
57              (global-type (info :variable :type sym)))
58         (if local-type
59             (type-intersection local-type global-type)
60             global-type))
61       *universal-type*))
62
63 (defoptimizer (symbol-value derive-type) ((symbol) node)
64   (derive-symbol-value-type symbol node))
65
66 (defoptimizer (symbol-global-value derive-type) ((symbol) node)
67   (derive-symbol-value-type symbol node))
68 \f
69 ;;;; list hackery
70
71 ;;; Translate CxR into CAR/CDR combos.
72 (defun source-transform-cxr (form)
73   (if (/= (length form) 2)
74       (values nil t)
75       (let* ((name (car form))
76              (string (symbol-name
77                       (etypecase name
78                         (symbol name)
79                         (leaf (leaf-source-name name))))))
80         (do ((i (- (length string) 2) (1- i))
81              (res (cadr form)
82                   `(,(ecase (char string i)
83                        (#\A 'car)
84                        (#\D 'cdr))
85                     ,res)))
86             ((zerop i) res)))))
87
88 ;;; Make source transforms to turn CxR forms into combinations of CAR
89 ;;; and CDR. ANSI specifies that everything up to 4 A/D operations is
90 ;;; defined.
91 ;;; Don't transform CAD*R, they are treated specially for &more args
92 ;;; optimizations
93
94 (/show0 "about to set CxR source transforms")
95 (loop for i of-type index from 2 upto 4 do
96       ;; Iterate over BUF = all names CxR where x = an I-element
97       ;; string of #\A or #\D characters.
98       (let ((buf (make-string (+ 2 i))))
99         (setf (aref buf 0) #\C
100               (aref buf (1+ i)) #\R)
101         (dotimes (j (ash 2 i))
102           (declare (type index j))
103           (dotimes (k i)
104             (declare (type index k))
105             (setf (aref buf (1+ k))
106                   (if (logbitp k j) #\A #\D)))
107           (unless (member buf '("CADR" "CADDR" "CADDDR")
108                           :test #'equal)
109             (setf (info :function :source-transform (intern buf))
110                   #'source-transform-cxr)))))
111 (/show0 "done setting CxR source transforms")
112
113 ;;; Turn FIRST..FOURTH and REST into the obvious synonym, assuming
114 ;;; whatever is right for them is right for us. FIFTH..TENTH turn into
115 ;;; Nth, which can be expanded into a CAR/CDR later on if policy
116 ;;; favors it.
117 (define-source-transform rest (x) `(cdr ,x))
118 (define-source-transform first (x) `(car ,x))
119 (define-source-transform second (x) `(cadr ,x))
120 (define-source-transform third (x) `(caddr ,x))
121 (define-source-transform fourth (x) `(cadddr ,x))
122 (define-source-transform fifth (x) `(nth 4 ,x))
123 (define-source-transform sixth (x) `(nth 5 ,x))
124 (define-source-transform seventh (x) `(nth 6 ,x))
125 (define-source-transform eighth (x) `(nth 7 ,x))
126 (define-source-transform ninth (x) `(nth 8 ,x))
127 (define-source-transform tenth (x) `(nth 9 ,x))
128
129 ;;; LIST with one arg is an extremely common operation (at least inside
130 ;;; SBCL itself); translate it to CONS to take advantage of common
131 ;;; allocation routines.
132 (define-source-transform list (&rest args)
133   (case (length args)
134     (1 `(cons ,(first args) nil))
135     (t (values nil t))))
136
137 (defoptimizer (list derive-type) ((&rest args) node)
138   (if args
139       (specifier-type 'cons)
140       (specifier-type 'null)))
141
142 ;;; And similarly for LIST*.
143 (define-source-transform list* (arg &rest others)
144   (cond ((not others) arg)
145         ((not (cdr others)) `(cons ,arg ,(car others)))
146         (t (values nil t))))
147
148 (defoptimizer (list* derive-type) ((arg &rest args))
149   (if args
150       (specifier-type 'cons)
151       (lvar-type arg)))
152
153 ;;;
154
155 (define-source-transform nconc (&rest args)
156   (case (length args)
157     (0 ())
158     (1 (car args))
159     (t (values nil t))))
160
161 ;;; (append nil nil nil fixnum) => fixnum
162 ;;; (append x x cons x x) => cons
163 ;;; (append x x x x list) => list
164 ;;; (append x x x x sequence) => sequence
165 ;;; (append fixnum x ...) => nil
166 (defun derive-append-type (args)
167   (when (null args)
168     (return-from derive-append-type (specifier-type 'null)))
169   (let* ((cons-type (specifier-type 'cons))
170          (null-type (specifier-type 'null))
171          (list-type (specifier-type 'list))
172          (last (lvar-type (car (last args)))))
173     ;; Derive the actual return type, assuming that all but the last
174     ;; arguments are LISTs (otherwise, APPEND/NCONC doesn't return).
175     (loop with all-nil = t       ; all but the last args are NIL?
176           with some-cons = nil   ; some args are conses?
177           for (arg next) on args
178           for lvar-type = (type-approx-intersection2 (lvar-type arg)
179                                                      list-type)
180           while next
181           do (multiple-value-bind (typep definitely)
182                  (ctypep nil lvar-type)
183                (cond ((type= lvar-type *empty-type*)
184                       ;; type mismatch! insert an inline check that'll cause
185                       ;; compile-time warnings.
186                       (assert-lvar-type arg list-type
187                                         (lexenv-policy *lexenv*)))
188                      (some-cons) ; we know result's a cons -- nothing to do
189                      ((and (not typep) definitely) ; can't be NIL
190                       (setf some-cons t))          ; must be a CONS
191                      (all-nil
192                       (setf all-nil (csubtypep lvar-type null-type)))))
193           finally
194              ;; if some of the previous arguments are CONSes so is the result;
195              ;; if all the previous values are NIL, we're a fancy identity;
196              ;; otherwise, could be either
197              (return (cond (some-cons cons-type)
198                            (all-nil last)
199                            (t (type-union last cons-type)))))))
200
201 (defoptimizer (append derive-type) ((&rest args))
202   (derive-append-type args))
203
204 (defoptimizer (sb!impl::append2 derive-type) ((&rest args))
205   (derive-append-type args))
206
207 (defoptimizer (nconc derive-type) ((&rest args))
208   (derive-append-type args))
209
210 ;;; Translate RPLACx to LET and SETF.
211 (define-source-transform rplaca (x y)
212   (once-only ((n-x x))
213     `(progn
214        (setf (car ,n-x) ,y)
215        ,n-x)))
216 (define-source-transform rplacd (x y)
217   (once-only ((n-x x))
218     `(progn
219        (setf (cdr ,n-x) ,y)
220        ,n-x)))
221
222 (deftransform last ((list &optional n) (t &optional t))
223   (let ((c (constant-lvar-p n)))
224     (cond ((or (not n)
225                (and c (eql 1 (lvar-value n))))
226            '(%last1 list))
227           ((and c (eql 0 (lvar-value n)))
228            '(%last0 list))
229           (t
230            (let ((type (lvar-type n)))
231              (cond ((csubtypep type (specifier-type 'fixnum))
232                     '(%lastn/fixnum list n))
233                    ((csubtypep type (specifier-type 'bignum))
234                     '(%lastn/bignum list n))
235                    (t
236                     (give-up-ir1-transform "second argument type too vague"))))))))
237
238 (define-source-transform gethash (&rest args)
239   (case (length args)
240    (2 `(sb!impl::gethash3 ,@args nil))
241    (3 `(sb!impl::gethash3 ,@args))
242    (t (values nil t))))
243 (define-source-transform get (&rest args)
244   (case (length args)
245    (2 `(sb!impl::get3 ,@args nil))
246    (3 `(sb!impl::get3 ,@args))
247    (t (values nil t))))
248
249 (defvar *default-nthcdr-open-code-limit* 6)
250 (defvar *extreme-nthcdr-open-code-limit* 20)
251
252 (deftransform nthcdr ((n l) (unsigned-byte t) * :node node)
253   "convert NTHCDR to CAxxR"
254   (unless (constant-lvar-p n)
255     (give-up-ir1-transform))
256   (let ((n (lvar-value n)))
257     (when (> n
258              (if (policy node (and (= speed 3) (= space 0)))
259                  *extreme-nthcdr-open-code-limit*
260                  *default-nthcdr-open-code-limit*))
261       (give-up-ir1-transform))
262
263     (labels ((frob (n)
264                (if (zerop n)
265                    'l
266                    `(cdr ,(frob (1- n))))))
267       (frob n))))
268 \f
269 ;;;; arithmetic and numerology
270
271 (define-source-transform plusp (x) `(> ,x 0))
272 (define-source-transform minusp (x) `(< ,x 0))
273 (define-source-transform zerop (x) `(= ,x 0))
274
275 (define-source-transform 1+ (x) `(+ ,x 1))
276 (define-source-transform 1- (x) `(- ,x 1))
277
278 (define-source-transform oddp (x) `(logtest ,x 1))
279 (define-source-transform evenp (x) `(not (logtest ,x 1)))
280
281 ;;; Note that all the integer division functions are available for
282 ;;; inline expansion.
283
284 (macrolet ((deffrob (fun)
285              `(define-source-transform ,fun (x &optional (y nil y-p))
286                 (declare (ignore y))
287                 (if y-p
288                     (values nil t)
289                     `(,',fun ,x 1)))))
290   (deffrob truncate)
291   (deffrob round)
292   #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
293   (deffrob floor)
294   #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
295   (deffrob ceiling))
296
297 ;;; This used to be a source transform (hence the lack of restrictions
298 ;;; on the argument types), but we make it a regular transform so that
299 ;;; the VM has a chance to see the bare LOGTEST and potentiall choose
300 ;;; to implement it differently.  --njf, 06-02-2006
301 ;;;
302 ;;; Other transforms may be useful even with direct LOGTEST VOPs; let
303 ;;; them fire (including the type-directed constant folding below), but
304 ;;; disable the inlining rewrite in such cases. -- PK, 2013-05-20
305 (deftransform logtest ((x y) * * :node node)
306   (let ((type (two-arg-derive-type x y
307                                    #'logand-derive-type-aux
308                                    #'logand)))
309     (multiple-value-bind (typep definitely)
310         (ctypep 0 type)
311       (cond ((and (not typep) definitely)
312              t)
313             ((type= type (specifier-type '(eql 0)))
314              nil)
315             ((neq :default (combination-implementation-style node))
316              (give-up-ir1-transform))
317             (t
318              `(not (zerop (logand x y))))))))
319
320 (deftransform logbitp
321     ((index integer) (unsigned-byte (or (signed-byte #.sb!vm:n-word-bits)
322                                         (unsigned-byte #.sb!vm:n-word-bits))))
323   `(if (>= index #.sb!vm:n-word-bits)
324        (minusp integer)
325        (not (zerop (logand integer (ash 1 index))))))
326
327 (define-source-transform byte (size position)
328   `(cons ,size ,position))
329 (define-source-transform byte-size (spec) `(car ,spec))
330 (define-source-transform byte-position (spec) `(cdr ,spec))
331 (define-source-transform ldb-test (bytespec integer)
332   `(not (zerop (mask-field ,bytespec ,integer))))
333
334 ;;; With the ratio and complex accessors, we pick off the "identity"
335 ;;; case, and use a primitive to handle the cell access case.
336 (define-source-transform numerator (num)
337   (once-only ((n-num `(the rational ,num)))
338     `(if (ratiop ,n-num)
339          (%numerator ,n-num)
340          ,n-num)))
341 (define-source-transform denominator (num)
342   (once-only ((n-num `(the rational ,num)))
343     `(if (ratiop ,n-num)
344          (%denominator ,n-num)
345          1)))
346 \f
347 ;;;; interval arithmetic for computing bounds
348 ;;;;
349 ;;;; This is a set of routines for operating on intervals. It
350 ;;;; implements a simple interval arithmetic package. Although SBCL
351 ;;;; has an interval type in NUMERIC-TYPE, we choose to use our own
352 ;;;; for two reasons:
353 ;;;;
354 ;;;;   1. This package is simpler than NUMERIC-TYPE.
355 ;;;;
356 ;;;;   2. It makes debugging much easier because you can just strip
357 ;;;;   out these routines and test them independently of SBCL. (This is a
358 ;;;;   big win!)
359 ;;;;
360 ;;;; One disadvantage is a probable increase in consing because we
361 ;;;; have to create these new interval structures even though
362 ;;;; numeric-type has everything we want to know. Reason 2 wins for
363 ;;;; now.
364
365 ;;; Support operations that mimic real arithmetic comparison
366 ;;; operators, but imposing a total order on the floating points such
367 ;;; that negative zeros are strictly less than positive zeros.
368 (macrolet ((def (name op)
369              `(defun ,name (x y)
370                 (declare (real x y))
371                 (if (and (floatp x) (floatp y) (zerop x) (zerop y))
372                     (,op (float-sign x) (float-sign y))
373                     (,op x y)))))
374   (def signed-zero->= >=)
375   (def signed-zero-> >)
376   (def signed-zero-= =)
377   (def signed-zero-< <)
378   (def signed-zero-<= <=))
379
380 ;;; The basic interval type. It can handle open and closed intervals.
381 ;;; A bound is open if it is a list containing a number, just like
382 ;;; Lisp says. NIL means unbounded.
383 (defstruct (interval (:constructor %make-interval)
384                      (:copier nil))
385   low high)
386
387 (defun make-interval (&key low high)
388   (labels ((normalize-bound (val)
389              (cond #-sb-xc-host
390                    ((and (floatp val)
391                          (float-infinity-p val))
392                     ;; Handle infinities.
393                     nil)
394                    ((or (numberp val)
395                         (eq val nil))
396                     ;; Handle any closed bounds.
397                     val)
398                    ((listp val)
399                     ;; We have an open bound. Normalize the numeric
400                     ;; bound. If the normalized bound is still a number
401                     ;; (not nil), keep the bound open. Otherwise, the
402                     ;; bound is really unbounded, so drop the openness.
403                     (let ((new-val (normalize-bound (first val))))
404                       (when new-val
405                         ;; The bound exists, so keep it open still.
406                         (list new-val))))
407                    (t
408                     (error "unknown bound type in MAKE-INTERVAL")))))
409     (%make-interval :low (normalize-bound low)
410                     :high (normalize-bound high))))
411
412 ;;; Given a number X, create a form suitable as a bound for an
413 ;;; interval. Make the bound open if OPEN-P is T. NIL remains NIL.
414 #!-sb-fluid (declaim (inline set-bound))
415 (defun set-bound (x open-p)
416   (if (and x open-p) (list x) x))
417
418 ;;; Apply the function F to a bound X. If X is an open bound and the
419 ;;; function is declared strictly monotonic, then the result will be
420 ;;; open. IF X is NIL, the result is NIL.
421 (defun bound-func (f x strict)
422   (declare (type function f))
423   (and x
424        (handler-case
425          (with-float-traps-masked (:underflow :overflow :inexact :divide-by-zero)
426            ;; With these traps masked, we might get things like infinity
427            ;; or negative infinity returned. Check for this and return
428            ;; NIL to indicate unbounded.
429            (let ((y (funcall f (type-bound-number x))))
430              (if (and (floatp y)
431                       (float-infinity-p y))
432                  nil
433                  (set-bound y (and strict (consp x))))))
434          ;; Some numerical operations will signal SIMPLE-TYPE-ERROR, e.g.
435          ;; in the course of converting a bignum to a float.  Default to
436          ;; NIL in that case.
437          (simple-type-error ()))))
438
439 (defun safe-double-coercion-p (x)
440   (or (typep x 'double-float)
441       (<= most-negative-double-float x most-positive-double-float)))
442
443 (defun safe-single-coercion-p (x)
444   (or (typep x 'single-float)
445       (and
446        ;; Fix for bug 420, and related issues: during type derivation we often
447        ;; end up deriving types for both
448        ;;
449        ;;   (some-op <int> <single>)
450        ;; and
451        ;;   (some-op (coerce <int> 'single-float) <single>)
452        ;;
453        ;; or other equivalent transformed forms. The problem with this
454        ;; is that on x86 (+ <int> <single>) is on the machine level
455        ;; equivalent of
456        ;;
457        ;;   (coerce (+ (coerce <int> 'double-float)
458        ;;              (coerce <single> 'double-float))
459        ;;           'single-float)
460        ;;
461        ;; so if the result of (coerce <int> 'single-float) is not exact, the
462        ;; derived types for the transformed forms will have an empty
463        ;; intersection -- which in turn means that the compiler will conclude
464        ;; that the call never returns, and all hell breaks lose when it *does*
465        ;; return at runtime. (This affects not just +, but other operators are
466        ;; well.)
467        ;;
468        ;; See also: SAFE-CTYPE-FOR-SINGLE-COERCION-P
469        ;;
470        ;; FIXME: If we ever add SSE-support for x86, this conditional needs to
471        ;; change.
472        #!+x86
473        (not (typep x `(or (integer * (,most-negative-exactly-single-float-fixnum))
474                           (integer (,most-positive-exactly-single-float-fixnum) *))))
475        (<= most-negative-single-float x most-positive-single-float))))
476
477 ;;; Apply a binary operator OP to two bounds X and Y. The result is
478 ;;; NIL if either is NIL. Otherwise bound is computed and the result
479 ;;; is open if either X or Y is open.
480 ;;;
481 ;;; FIXME: only used in this file, not needed in target runtime
482
483 ;;; ANSI contaigon specifies coercion to floating point if one of the
484 ;;; arguments is floating point. Here we should check to be sure that
485 ;;; the other argument is within the bounds of that floating point
486 ;;; type.
487
488 (defmacro safely-binop (op x y)
489   `(cond
490      ((typep ,x 'double-float)
491       (when (safe-double-coercion-p ,y)
492         (,op ,x ,y)))
493      ((typep ,y 'double-float)
494       (when (safe-double-coercion-p ,x)
495         (,op ,x ,y)))
496      ((typep ,x 'single-float)
497       (when (safe-single-coercion-p ,y)
498         (,op ,x ,y)))
499      ((typep ,y 'single-float)
500       (when (safe-single-coercion-p ,x)
501         (,op ,x ,y)))
502      (t (,op ,x ,y))))
503
504 (defmacro bound-binop (op x y)
505   (with-unique-names (xb yb res)
506     `(and ,x ,y
507           (with-float-traps-masked (:underflow :overflow :inexact :divide-by-zero)
508             (let* ((,xb (type-bound-number ,x))
509                    (,yb (type-bound-number ,y))
510                    (,res (safely-binop ,op ,xb ,yb)))
511               (set-bound ,res
512                          (and (or (consp ,x) (consp ,y))
513                               ;; Open bounds can very easily be messed up
514                               ;; by FP rounding, so take care here.
515                               ,(case op
516                                  (*
517                                   ;; Multiplying a greater-than-zero with
518                                   ;; less than one can round to zero.
519                                   `(or (not (fp-zero-p ,res))
520                                        (cond ((and (consp ,x) (fp-zero-p ,xb))
521                                               (>= (abs ,yb) 1))
522                                              ((and (consp ,y) (fp-zero-p ,yb))
523                                               (>= (abs ,xb) 1)))))
524                                  (/
525                                   ;; Dividing a greater-than-zero with
526                                   ;; greater than one can round to zero.
527                                   `(or (not (fp-zero-p ,res))
528                                        (cond ((and (consp ,x) (fp-zero-p ,xb))
529                                               (<= (abs ,yb) 1))
530                                              ((and (consp ,y) (fp-zero-p ,yb))
531                                               (<= (abs ,xb) 1)))))
532                                  ((+ -)
533                                   ;; Adding or subtracting greater-than-zero
534                                   ;; can end up with identity.
535                                   `(and (not (fp-zero-p ,xb))
536                                         (not (fp-zero-p ,yb))))))))))))
537
538 (defun coercion-loses-precision-p (val type)
539   (typecase val
540     (single-float)
541     (double-float (subtypep type 'single-float))
542     (rational (subtypep type 'float))
543     (t (bug "Unexpected arguments to bounds coercion: ~S ~S" val type))))
544
545 (defun coerce-for-bound (val type)
546   (if (consp val)
547       (let ((xbound (coerce-for-bound (car val) type)))
548         (if (coercion-loses-precision-p (car val) type)
549             xbound
550             (list xbound)))
551       (cond
552         ((subtypep type 'double-float)
553          (if (<= most-negative-double-float val most-positive-double-float)
554              (coerce val type)))
555         ((or (subtypep type 'single-float) (subtypep type 'float))
556          ;; coerce to float returns a single-float
557          (if (<= most-negative-single-float val most-positive-single-float)
558              (coerce val type)))
559         (t (coerce val type)))))
560
561 (defun coerce-and-truncate-floats (val type)
562   (when val
563     (if (consp val)
564         (let ((xbound (coerce-for-bound (car val) type)))
565           (if (coercion-loses-precision-p (car val) type)
566               xbound
567               (list xbound)))
568         (cond
569           ((subtypep type 'double-float)
570            (if (<= most-negative-double-float val most-positive-double-float)
571                (coerce val type)
572                (if (< val most-negative-double-float)
573                    most-negative-double-float most-positive-double-float)))
574           ((or (subtypep type 'single-float) (subtypep type 'float))
575            ;; coerce to float returns a single-float
576            (if (<= most-negative-single-float val most-positive-single-float)
577                (coerce val type)
578                (if (< val most-negative-single-float)
579                    most-negative-single-float most-positive-single-float)))
580           (t (coerce val type))))))
581
582 ;;; Convert a numeric-type object to an interval object.
583 (defun numeric-type->interval (x)
584   (declare (type numeric-type x))
585   (make-interval :low (numeric-type-low x)
586                  :high (numeric-type-high x)))
587
588 (defun type-approximate-interval (type)
589   (declare (type ctype type))
590   (let ((types (prepare-arg-for-derive-type type))
591         (result nil))
592     (dolist (type types)
593       (let ((type (if (member-type-p type)
594                       (convert-member-type type)
595                       type)))
596         (unless (numeric-type-p type)
597           (return-from type-approximate-interval nil))
598         (let ((interval (numeric-type->interval type)))
599           (setq result
600                 (if result
601                     (interval-approximate-union result interval)
602                     interval)))))
603     result))
604
605 (defun copy-interval-limit (limit)
606   (if (numberp limit)
607       limit
608       (copy-list limit)))
609
610 (defun copy-interval (x)
611   (declare (type interval x))
612   (make-interval :low (copy-interval-limit (interval-low x))
613                  :high (copy-interval-limit (interval-high x))))
614
615 ;;; Given a point P contained in the interval X, split X into two
616 ;;; intervals at the point P. If CLOSE-LOWER is T, then the left
617 ;;; interval contains P. If CLOSE-UPPER is T, the right interval
618 ;;; contains P. You can specify both to be T or NIL.
619 (defun interval-split (p x &optional close-lower close-upper)
620   (declare (type number p)
621            (type interval x))
622   (list (make-interval :low (copy-interval-limit (interval-low x))
623                        :high (if close-lower p (list p)))
624         (make-interval :low (if close-upper (list p) p)
625                        :high (copy-interval-limit (interval-high x)))))
626
627 ;;; Return the closure of the interval. That is, convert open bounds
628 ;;; to closed bounds.
629 (defun interval-closure (x)
630   (declare (type interval x))
631   (make-interval :low (type-bound-number (interval-low x))
632                  :high (type-bound-number (interval-high x))))
633
634 ;;; For an interval X, if X >= POINT, return '+. If X <= POINT, return
635 ;;; '-. Otherwise return NIL.
636 (defun interval-range-info (x &optional (point 0))
637   (declare (type interval x))
638   (let ((lo (interval-low x))
639         (hi (interval-high x)))
640     (cond ((and lo (signed-zero->= (type-bound-number lo) point))
641            '+)
642           ((and hi (signed-zero->= point (type-bound-number hi)))
643            '-)
644           (t
645            nil))))
646
647 ;;; Test to see whether the interval X is bounded. HOW determines the
648 ;;; test, and should be either ABOVE, BELOW, or BOTH.
649 (defun interval-bounded-p (x how)
650   (declare (type interval x))
651   (ecase how
652     (above
653      (interval-high x))
654     (below
655      (interval-low x))
656     (both
657      (and (interval-low x) (interval-high x)))))
658
659 ;;; See whether the interval X contains the number P, taking into
660 ;;; account that the interval might not be closed.
661 (defun interval-contains-p (p x)
662   (declare (type number p)
663            (type interval x))
664   ;; Does the interval X contain the number P?  This would be a lot
665   ;; easier if all intervals were closed!
666   (let ((lo (interval-low x))
667         (hi (interval-high x)))
668     (cond ((and lo hi)
669            ;; The interval is bounded
670            (if (and (signed-zero-<= (type-bound-number lo) p)
671                     (signed-zero-<= p (type-bound-number hi)))
672                ;; P is definitely in the closure of the interval.
673                ;; We just need to check the end points now.
674                (cond ((signed-zero-= p (type-bound-number lo))
675                       (numberp lo))
676                      ((signed-zero-= p (type-bound-number hi))
677                       (numberp hi))
678                      (t t))
679                nil))
680           (hi
681            ;; Interval with upper bound
682            (if (signed-zero-< p (type-bound-number hi))
683                t
684                (and (numberp hi) (signed-zero-= p hi))))
685           (lo
686            ;; Interval with lower bound
687            (if (signed-zero-> p (type-bound-number lo))
688                t
689                (and (numberp lo) (signed-zero-= p lo))))
690           (t
691            ;; Interval with no bounds
692            t))))
693
694 ;;; Determine whether two intervals X and Y intersect. Return T if so.
695 ;;; If CLOSED-INTERVALS-P is T, the treat the intervals as if they
696 ;;; were closed. Otherwise the intervals are treated as they are.
697 ;;;
698 ;;; Thus if X = [0, 1) and Y = (1, 2), then they do not intersect
699 ;;; because no element in X is in Y. However, if CLOSED-INTERVALS-P
700 ;;; is T, then they do intersect because we use the closure of X = [0,
701 ;;; 1] and Y = [1, 2] to determine intersection.
702 (defun interval-intersect-p (x y &optional closed-intervals-p)
703   (declare (type interval x y))
704   (and (interval-intersection/difference (if closed-intervals-p
705                                              (interval-closure x)
706                                              x)
707                                          (if closed-intervals-p
708                                              (interval-closure y)
709                                              y))
710        t))
711
712 ;;; Are the two intervals adjacent?  That is, is there a number
713 ;;; between the two intervals that is not an element of either
714 ;;; interval?  If so, they are not adjacent. For example [0, 1) and
715 ;;; [1, 2] are adjacent but [0, 1) and (1, 2] are not because 1 lies
716 ;;; between both intervals.
717 (defun interval-adjacent-p (x y)
718   (declare (type interval x y))
719   (flet ((adjacent (lo hi)
720            ;; Check to see whether lo and hi are adjacent. If either is
721            ;; nil, they can't be adjacent.
722            (when (and lo hi (= (type-bound-number lo) (type-bound-number hi)))
723              ;; The bounds are equal. They are adjacent if one of
724              ;; them is closed (a number). If both are open (consp),
725              ;; then there is a number that lies between them.
726              (or (numberp lo) (numberp hi)))))
727     (or (adjacent (interval-low y) (interval-high x))
728         (adjacent (interval-low x) (interval-high y)))))
729
730 ;;; Compute the intersection and difference between two intervals.
731 ;;; Two values are returned: the intersection and the difference.
732 ;;;
733 ;;; Let the two intervals be X and Y, and let I and D be the two
734 ;;; values returned by this function. Then I = X intersect Y. If I
735 ;;; is NIL (the empty set), then D is X union Y, represented as the
736 ;;; list of X and Y. If I is not the empty set, then D is (X union Y)
737 ;;; - I, which is a list of two intervals.
738 ;;;
739 ;;; For example, let X = [1,5] and Y = [-1,3). Then I = [1,3) and D =
740 ;;; [-1,1) union [3,5], which is returned as a list of two intervals.
741 (defun interval-intersection/difference (x y)
742   (declare (type interval x y))
743   (let ((x-lo (interval-low x))
744         (x-hi (interval-high x))
745         (y-lo (interval-low y))
746         (y-hi (interval-high y)))
747     (labels
748         ((opposite-bound (p)
749            ;; If p is an open bound, make it closed. If p is a closed
750            ;; bound, make it open.
751            (if (listp p)
752                (first p)
753                (list p)))
754          (test-number (p int bound)
755            ;; Test whether P is in the interval.
756            (let ((pn (type-bound-number p)))
757              (when (interval-contains-p pn (interval-closure int))
758                ;; Check for endpoints.
759                (let* ((lo (interval-low int))
760                       (hi (interval-high int))
761                       (lon (type-bound-number lo))
762                       (hin (type-bound-number hi)))
763                  (cond
764                    ;; Interval may be a point.
765                    ((and lon hin (= lon hin pn))
766                     (and (numberp p) (numberp lo) (numberp hi)))
767                    ;; Point matches the low end.
768                    ;; [P] [P,?} => TRUE     [P] (P,?} => FALSE
769                    ;; (P  [P,?} => TRUE      P) [P,?} => FALSE
770                    ;; (P  (P,?} => TRUE      P) (P,?} => FALSE
771                    ((and lon (= pn lon))
772                     (or (and (numberp p) (numberp lo))
773                         (and (consp p) (eq :low bound))))
774                    ;; [P] {?,P] => TRUE     [P] {?,P) => FALSE
775                    ;;  P) {?,P] => TRUE     (P  {?,P] => FALSE
776                    ;;  P) {?,P) => TRUE     (P  {?,P) => FALSE
777                    ((and hin (= pn hin))
778                     (or (and (numberp p) (numberp hi))
779                         (and (consp p) (eq :high bound))))
780                    ;; Not an endpoint, all is well.
781                    (t
782                     t))))))
783          (test-lower-bound (p int)
784            ;; P is a lower bound of an interval.
785            (if p
786                (test-number p int :low)
787                (not (interval-bounded-p int 'below))))
788          (test-upper-bound (p int)
789            ;; P is an upper bound of an interval.
790            (if p
791                (test-number p int :high)
792                (not (interval-bounded-p int 'above)))))
793       (let ((x-lo-in-y (test-lower-bound x-lo y))
794             (x-hi-in-y (test-upper-bound x-hi y))
795             (y-lo-in-x (test-lower-bound y-lo x))
796             (y-hi-in-x (test-upper-bound y-hi x)))
797         (cond ((or x-lo-in-y x-hi-in-y y-lo-in-x y-hi-in-x)
798                ;; Intervals intersect. Let's compute the intersection
799                ;; and the difference.
800                (multiple-value-bind (lo left-lo left-hi)
801                    (cond (x-lo-in-y (values x-lo y-lo (opposite-bound x-lo)))
802                          (y-lo-in-x (values y-lo x-lo (opposite-bound y-lo))))
803                  (multiple-value-bind (hi right-lo right-hi)
804                      (cond (x-hi-in-y
805                             (values x-hi (opposite-bound x-hi) y-hi))
806                            (y-hi-in-x
807                             (values y-hi (opposite-bound y-hi) x-hi)))
808                    (values (make-interval :low lo :high hi)
809                            (list (make-interval :low left-lo
810                                                 :high left-hi)
811                                  (make-interval :low right-lo
812                                                 :high right-hi))))))
813               (t
814                (values nil (list x y))))))))
815
816 ;;; If intervals X and Y intersect, return a new interval that is the
817 ;;; union of the two. If they do not intersect, return NIL.
818 (defun interval-merge-pair (x y)
819   (declare (type interval x y))
820   ;; If x and y intersect or are adjacent, create the union.
821   ;; Otherwise return nil
822   (when (or (interval-intersect-p x y)
823             (interval-adjacent-p x y))
824     (flet ((select-bound (x1 x2 min-op max-op)
825              (let ((x1-val (type-bound-number x1))
826                    (x2-val (type-bound-number x2)))
827                (cond ((and x1 x2)
828                       ;; Both bounds are finite. Select the right one.
829                       (cond ((funcall min-op x1-val x2-val)
830                              ;; x1 is definitely better.
831                              x1)
832                             ((funcall max-op x1-val x2-val)
833                              ;; x2 is definitely better.
834                              x2)
835                             (t
836                              ;; Bounds are equal. Select either
837                              ;; value and make it open only if
838                              ;; both were open.
839                              (set-bound x1-val (and (consp x1) (consp x2))))))
840                      (t
841                       ;; At least one bound is not finite. The
842                       ;; non-finite bound always wins.
843                       nil)))))
844       (let* ((x-lo (copy-interval-limit (interval-low x)))
845              (x-hi (copy-interval-limit (interval-high x)))
846              (y-lo (copy-interval-limit (interval-low y)))
847              (y-hi (copy-interval-limit (interval-high y))))
848         (make-interval :low (select-bound x-lo y-lo #'< #'>)
849                        :high (select-bound x-hi y-hi #'> #'<))))))
850
851 ;;; return the minimal interval, containing X and Y
852 (defun interval-approximate-union (x y)
853   (cond ((interval-merge-pair x y))
854         ((interval-< x y)
855          (make-interval :low (copy-interval-limit (interval-low x))
856                         :high (copy-interval-limit (interval-high y))))
857         (t
858          (make-interval :low (copy-interval-limit (interval-low y))
859                         :high (copy-interval-limit (interval-high x))))))
860
861 ;;; basic arithmetic operations on intervals. We probably should do
862 ;;; true interval arithmetic here, but it's complicated because we
863 ;;; have float and integer types and bounds can be open or closed.
864
865 ;;; the negative of an interval
866 (defun interval-neg (x)
867   (declare (type interval x))
868   (make-interval :low (bound-func #'- (interval-high x) t)
869                  :high (bound-func #'- (interval-low x) t)))
870
871 ;;; Add two intervals.
872 (defun interval-add (x y)
873   (declare (type interval x y))
874   (make-interval :low (bound-binop + (interval-low x) (interval-low y))
875                  :high (bound-binop + (interval-high x) (interval-high y))))
876
877 ;;; Subtract two intervals.
878 (defun interval-sub (x y)
879   (declare (type interval x y))
880   (make-interval :low (bound-binop - (interval-low x) (interval-high y))
881                  :high (bound-binop - (interval-high x) (interval-low y))))
882
883 ;;; Multiply two intervals.
884 (defun interval-mul (x y)
885   (declare (type interval x y))
886   (flet ((bound-mul (x y)
887            (cond ((or (null x) (null y))
888                   ;; Multiply by infinity is infinity
889                   nil)
890                  ((or (and (numberp x) (zerop x))
891                       (and (numberp y) (zerop y)))
892                   ;; Multiply by closed zero is special. The result
893                   ;; is always a closed bound. But don't replace this
894                   ;; with zero; we want the multiplication to produce
895                   ;; the correct signed zero, if needed. Use SIGNUM
896                   ;; to avoid trying to multiply huge bignums with 0.0.
897                   (* (signum (type-bound-number x)) (signum (type-bound-number y))))
898                  ((or (and (floatp x) (float-infinity-p x))
899                       (and (floatp y) (float-infinity-p y)))
900                   ;; Infinity times anything is infinity
901                   nil)
902                  (t
903                   ;; General multiply. The result is open if either is open.
904                   (bound-binop * x y)))))
905     (let ((x-range (interval-range-info x))
906           (y-range (interval-range-info y)))
907       (cond ((null x-range)
908              ;; Split x into two and multiply each separately
909              (destructuring-bind (x- x+) (interval-split 0 x t t)
910                (interval-merge-pair (interval-mul x- y)
911                                     (interval-mul x+ y))))
912             ((null y-range)
913              ;; Split y into two and multiply each separately
914              (destructuring-bind (y- y+) (interval-split 0 y t t)
915                (interval-merge-pair (interval-mul x y-)
916                                     (interval-mul x y+))))
917             ((eq x-range '-)
918              (interval-neg (interval-mul (interval-neg x) y)))
919             ((eq y-range '-)
920              (interval-neg (interval-mul x (interval-neg y))))
921             ((and (eq x-range '+) (eq y-range '+))
922              ;; If we are here, X and Y are both positive.
923              (make-interval
924               :low (bound-mul (interval-low x) (interval-low y))
925               :high (bound-mul (interval-high x) (interval-high y))))
926             (t
927              (bug "excluded case in INTERVAL-MUL"))))))
928
929 ;;; Divide two intervals.
930 (defun interval-div (top bot)
931   (declare (type interval top bot))
932   (flet ((bound-div (x y y-low-p)
933            ;; Compute x/y
934            (cond ((null y)
935                   ;; Divide by infinity means result is 0. However,
936                   ;; we need to watch out for the sign of the result,
937                   ;; to correctly handle signed zeros. We also need
938                   ;; to watch out for positive or negative infinity.
939                   (if (floatp (type-bound-number x))
940                       (if y-low-p
941                           (- (float-sign (type-bound-number x) 0.0))
942                           (float-sign (type-bound-number x) 0.0))
943                       0))
944                  ((zerop (type-bound-number y))
945                   ;; Divide by zero means result is infinity
946                   nil)
947                  (t
948                   (bound-binop / x y)))))
949     (let ((top-range (interval-range-info top))
950           (bot-range (interval-range-info bot)))
951       (cond ((null bot-range)
952              ;; The denominator contains zero, so anything goes!
953              (make-interval :low nil :high nil))
954             ((eq bot-range '-)
955              ;; Denominator is negative so flip the sign, compute the
956              ;; result, and flip it back.
957              (interval-neg (interval-div top (interval-neg bot))))
958             ((null top-range)
959              ;; Split top into two positive and negative parts, and
960              ;; divide each separately
961              (destructuring-bind (top- top+) (interval-split 0 top t t)
962                (interval-merge-pair (interval-div top- bot)
963                                     (interval-div top+ bot))))
964             ((eq top-range '-)
965              ;; Top is negative so flip the sign, divide, and flip the
966              ;; sign of the result.
967              (interval-neg (interval-div (interval-neg top) bot)))
968             ((and (eq top-range '+) (eq bot-range '+))
969              ;; the easy case
970              (make-interval
971               :low (bound-div (interval-low top) (interval-high bot) t)
972               :high (bound-div (interval-high top) (interval-low bot) nil)))
973             (t
974              (bug "excluded case in INTERVAL-DIV"))))))
975
976 ;;; Apply the function F to the interval X. If X = [a, b], then the
977 ;;; result is [f(a), f(b)]. It is up to the user to make sure the
978 ;;; result makes sense. It will if F is monotonic increasing (or, if
979 ;;; the interval is closed, non-decreasing).
980 ;;;
981 ;;; (Actually most uses of INTERVAL-FUNC are coercions to float types,
982 ;;; which are not monotonic increasing, so default to calling
983 ;;; BOUND-FUNC with a non-strict argument).
984 (defun interval-func (f x &optional increasing)
985   (declare (type function f)
986            (type interval x))
987   (let ((lo (bound-func f (interval-low x) increasing))
988         (hi (bound-func f (interval-high x) increasing)))
989     (make-interval :low lo :high hi)))
990
991 ;;; Return T if X < Y. That is every number in the interval X is
992 ;;; always less than any number in the interval Y.
993 (defun interval-< (x y)
994   (declare (type interval x y))
995   ;; X < Y only if X is bounded above, Y is bounded below, and they
996   ;; don't overlap.
997   (when (and (interval-bounded-p x 'above)
998              (interval-bounded-p y 'below))
999     ;; Intervals are bounded in the appropriate way. Make sure they
1000     ;; don't overlap.
1001     (let ((left (interval-high x))
1002           (right (interval-low y)))
1003       (cond ((> (type-bound-number left)
1004                 (type-bound-number right))
1005              ;; The intervals definitely overlap, so result is NIL.
1006              nil)
1007             ((< (type-bound-number left)
1008                 (type-bound-number right))
1009              ;; The intervals definitely don't touch, so result is T.
1010              t)
1011             (t
1012              ;; Limits are equal. Check for open or closed bounds.
1013              ;; Don't overlap if one or the other are open.
1014              (or (consp left) (consp right)))))))
1015
1016 ;;; Return T if X >= Y. That is, every number in the interval X is
1017 ;;; always greater than any number in the interval Y.
1018 (defun interval->= (x y)
1019   (declare (type interval x y))
1020   ;; X >= Y if lower bound of X >= upper bound of Y
1021   (when (and (interval-bounded-p x 'below)
1022              (interval-bounded-p y 'above))
1023     (>= (type-bound-number (interval-low x))
1024         (type-bound-number (interval-high y)))))
1025
1026 ;;; Return T if X = Y.
1027 (defun interval-= (x y)
1028   (declare (type interval x y))
1029   (and (interval-bounded-p x 'both)
1030        (interval-bounded-p y 'both)
1031        (flet ((bound (v)
1032                 (if (numberp v)
1033                     v
1034                     ;; Open intervals cannot be =
1035                     (return-from interval-= nil))))
1036          ;; Both intervals refer to the same point
1037          (= (bound (interval-high x)) (bound (interval-low x))
1038             (bound (interval-high y)) (bound (interval-low y))))))
1039
1040 ;;; Return T if X /= Y
1041 (defun interval-/= (x y)
1042   (not (interval-intersect-p x y)))
1043
1044 ;;; Return an interval that is the absolute value of X. Thus, if
1045 ;;; X = [-1 10], the result is [0, 10].
1046 (defun interval-abs (x)
1047   (declare (type interval x))
1048   (case (interval-range-info x)
1049     (+
1050      (copy-interval x))
1051     (-
1052      (interval-neg x))
1053     (t
1054      (destructuring-bind (x- x+) (interval-split 0 x t t)
1055        (interval-merge-pair (interval-neg x-) x+)))))
1056
1057 ;;; Compute the square of an interval.
1058 (defun interval-sqr (x)
1059   (declare (type interval x))
1060   (interval-func (lambda (x) (* x x)) (interval-abs x)))
1061 \f
1062 ;;;; numeric DERIVE-TYPE methods
1063
1064 ;;; a utility for defining derive-type methods of integer operations. If
1065 ;;; the types of both X and Y are integer types, then we compute a new
1066 ;;; integer type with bounds determined by FUN when applied to X and Y.
1067 ;;; Otherwise, we use NUMERIC-CONTAGION.
1068 (defun derive-integer-type-aux (x y fun)
1069   (declare (type function fun))
1070   (if (and (numeric-type-p x) (numeric-type-p y)
1071            (eq (numeric-type-class x) 'integer)
1072            (eq (numeric-type-class y) 'integer)
1073            (eq (numeric-type-complexp x) :real)
1074            (eq (numeric-type-complexp y) :real))
1075       (multiple-value-bind (low high) (funcall fun x y)
1076         (make-numeric-type :class 'integer
1077                            :complexp :real
1078                            :low low
1079                            :high high))
1080       (numeric-contagion x y)))
1081
1082 (defun derive-integer-type (x y fun)
1083   (declare (type lvar x y) (type function fun))
1084   (let ((x (lvar-type x))
1085         (y (lvar-type y)))
1086     (derive-integer-type-aux x y fun)))
1087
1088 ;;; simple utility to flatten a list
1089 (defun flatten-list (x)
1090   (labels ((flatten-and-append (tree list)
1091              (cond ((null tree) list)
1092                    ((atom tree) (cons tree list))
1093                    (t (flatten-and-append
1094                        (car tree) (flatten-and-append (cdr tree) list))))))
1095     (flatten-and-append x nil)))
1096
1097 ;;; Take some type of lvar and massage it so that we get a list of the
1098 ;;; constituent types. If ARG is *EMPTY-TYPE*, return NIL to indicate
1099 ;;; failure.
1100 (defun prepare-arg-for-derive-type (arg)
1101   (flet ((listify (arg)
1102            (typecase arg
1103              (numeric-type
1104               (list arg))
1105              (union-type
1106               (union-type-types arg))
1107              (t
1108               (list arg)))))
1109     (unless (eq arg *empty-type*)
1110       ;; Make sure all args are some type of numeric-type. For member
1111       ;; types, convert the list of members into a union of equivalent
1112       ;; single-element member-type's.
1113       (let ((new-args nil))
1114         (dolist (arg (listify arg))
1115           (if (member-type-p arg)
1116               ;; Run down the list of members and convert to a list of
1117               ;; member types.
1118               (mapc-member-type-members
1119                (lambda (member)
1120                  (push (if (numberp member)
1121                            (make-member-type :members (list member))
1122                            *empty-type*)
1123                        new-args))
1124                arg)
1125               (push arg new-args)))
1126         (unless (member *empty-type* new-args)
1127           new-args)))))
1128
1129 ;;; Convert from the standard type convention for which -0.0 and 0.0
1130 ;;; are equal to an intermediate convention for which they are
1131 ;;; considered different which is more natural for some of the
1132 ;;; optimisers.
1133 (defun convert-numeric-type (type)
1134   (declare (type numeric-type type))
1135   ;;; Only convert real float interval delimiters types.
1136   (if (eq (numeric-type-complexp type) :real)
1137       (let* ((lo (numeric-type-low type))
1138              (lo-val (type-bound-number lo))
1139              (lo-float-zero-p (and lo (floatp lo-val) (= lo-val 0.0)))
1140              (hi (numeric-type-high type))
1141              (hi-val (type-bound-number hi))
1142              (hi-float-zero-p (and hi (floatp hi-val) (= hi-val 0.0))))
1143         (if (or lo-float-zero-p hi-float-zero-p)
1144             (make-numeric-type
1145              :class (numeric-type-class type)
1146              :format (numeric-type-format type)
1147              :complexp :real
1148              :low (if lo-float-zero-p
1149                       (if (consp lo)
1150                           (list (float 0.0 lo-val))
1151                           (float (load-time-value (make-unportable-float :single-float-negative-zero)) lo-val))
1152                       lo)
1153              :high (if hi-float-zero-p
1154                        (if (consp hi)
1155                            (list (float (load-time-value (make-unportable-float :single-float-negative-zero)) hi-val))
1156                            (float 0.0 hi-val))
1157                        hi))
1158             type))
1159       ;; Not real float.
1160       type))
1161
1162 ;;; Convert back from the intermediate convention for which -0.0 and
1163 ;;; 0.0 are considered different to the standard type convention for
1164 ;;; which and equal.
1165 (defun convert-back-numeric-type (type)
1166   (declare (type numeric-type type))
1167   ;;; Only convert real float interval delimiters types.
1168   (if (eq (numeric-type-complexp type) :real)
1169       (let* ((lo (numeric-type-low type))
1170              (lo-val (type-bound-number lo))
1171              (lo-float-zero-p
1172               (and lo (floatp lo-val) (= lo-val 0.0)
1173                    (float-sign lo-val)))
1174              (hi (numeric-type-high type))
1175              (hi-val (type-bound-number hi))
1176              (hi-float-zero-p
1177               (and hi (floatp hi-val) (= hi-val 0.0)
1178                    (float-sign hi-val))))
1179         (cond
1180           ;; (float +0.0 +0.0) => (member 0.0)
1181           ;; (float -0.0 -0.0) => (member -0.0)
1182           ((and lo-float-zero-p hi-float-zero-p)
1183            ;; shouldn't have exclusive bounds here..
1184            (aver (and (not (consp lo)) (not (consp hi))))
1185            (if (= lo-float-zero-p hi-float-zero-p)
1186                ;; (float +0.0 +0.0) => (member 0.0)
1187                ;; (float -0.0 -0.0) => (member -0.0)
1188                (specifier-type `(member ,lo-val))
1189                ;; (float -0.0 +0.0) => (float 0.0 0.0)
1190                ;; (float +0.0 -0.0) => (float 0.0 0.0)
1191                (make-numeric-type :class (numeric-type-class type)
1192                                   :format (numeric-type-format type)
1193                                   :complexp :real
1194                                   :low hi-val
1195                                   :high hi-val)))
1196           (lo-float-zero-p
1197            (cond
1198              ;; (float -0.0 x) => (float 0.0 x)
1199              ((and (not (consp lo)) (minusp lo-float-zero-p))
1200               (make-numeric-type :class (numeric-type-class type)
1201                                  :format (numeric-type-format type)
1202                                  :complexp :real
1203                                  :low (float 0.0 lo-val)
1204                                  :high hi))
1205              ;; (float (+0.0) x) => (float (0.0) x)
1206              ((and (consp lo) (plusp lo-float-zero-p))
1207               (make-numeric-type :class (numeric-type-class type)
1208                                  :format (numeric-type-format type)
1209                                  :complexp :real
1210                                  :low (list (float 0.0 lo-val))
1211                                  :high hi))
1212              (t
1213               ;; (float +0.0 x) => (or (member 0.0) (float (0.0) x))
1214               ;; (float (-0.0) x) => (or (member 0.0) (float (0.0) x))
1215               (list (make-member-type :members (list (float 0.0 lo-val)))
1216                     (make-numeric-type :class (numeric-type-class type)
1217                                        :format (numeric-type-format type)
1218                                        :complexp :real
1219                                        :low (list (float 0.0 lo-val))
1220                                        :high hi)))))
1221           (hi-float-zero-p
1222            (cond
1223              ;; (float x +0.0) => (float x 0.0)
1224              ((and (not (consp hi)) (plusp hi-float-zero-p))
1225               (make-numeric-type :class (numeric-type-class type)
1226                                  :format (numeric-type-format type)
1227                                  :complexp :real
1228                                  :low lo
1229                                  :high (float 0.0 hi-val)))
1230              ;; (float x (-0.0)) => (float x (0.0))
1231              ((and (consp hi) (minusp hi-float-zero-p))
1232               (make-numeric-type :class (numeric-type-class type)
1233                                  :format (numeric-type-format type)
1234                                  :complexp :real
1235                                  :low lo
1236                                  :high (list (float 0.0 hi-val))))
1237              (t
1238               ;; (float x (+0.0)) => (or (member -0.0) (float x (0.0)))
1239               ;; (float x -0.0) => (or (member -0.0) (float x (0.0)))
1240               (list (make-member-type :members (list (float (load-time-value (make-unportable-float :single-float-negative-zero)) hi-val)))
1241                     (make-numeric-type :class (numeric-type-class type)
1242                                        :format (numeric-type-format type)
1243                                        :complexp :real
1244                                        :low lo
1245                                        :high (list (float 0.0 hi-val)))))))
1246           (t
1247            type)))
1248       ;; not real float
1249       type))
1250
1251 ;;; Convert back a possible list of numeric types.
1252 (defun convert-back-numeric-type-list (type-list)
1253   (typecase type-list
1254     (list
1255      (let ((results '()))
1256        (dolist (type type-list)
1257          (if (numeric-type-p type)
1258              (let ((result (convert-back-numeric-type type)))
1259                (if (listp result)
1260                    (setf results (append results result))
1261                    (push result results)))
1262              (push type results)))
1263        results))
1264     (numeric-type
1265      (convert-back-numeric-type type-list))
1266     (union-type
1267      (convert-back-numeric-type-list (union-type-types type-list)))
1268     (t
1269      type-list)))
1270
1271 ;;; Take a list of types and return a canonical type specifier,
1272 ;;; combining any MEMBER types together. If both positive and negative
1273 ;;; MEMBER types are present they are converted to a float type.
1274 ;;; XXX This would be far simpler if the type-union methods could handle
1275 ;;; member/number unions.
1276 ;;;
1277 ;;; If we're about to generate an overly complex union of numeric types, start
1278 ;;; collapse the ranges together.
1279 ;;;
1280 ;;; FIXME: The MEMBER canonicalization parts of MAKE-DERIVED-UNION-TYPE and
1281 ;;; entire CONVERT-MEMBER-TYPE probably belong in the kernel's type logic,
1282 ;;; invoked always, instead of in the compiler, invoked only during some type
1283 ;;; optimizations.
1284 (defvar *derived-numeric-union-complexity-limit* 6)
1285
1286 (defun make-derived-union-type (type-list)
1287   (let ((xset (alloc-xset))
1288         (fp-zeroes '())
1289         (misc-types '())
1290         (numeric-type *empty-type*))
1291     (dolist (type type-list)
1292       (cond ((member-type-p type)
1293              (mapc-member-type-members
1294               (lambda (member)
1295                 (if (fp-zero-p member)
1296                     (unless (member member fp-zeroes)
1297                       (pushnew member fp-zeroes))
1298                     (add-to-xset member xset)))
1299               type))
1300             ((numeric-type-p type)
1301              (let ((*approximate-numeric-unions*
1302                     (when (and (union-type-p numeric-type)
1303                                (nthcdr *derived-numeric-union-complexity-limit*
1304                                        (union-type-types numeric-type)))
1305                       t)))
1306                (setf numeric-type (type-union type numeric-type))))
1307             (t
1308              (push type misc-types))))
1309     (if (and (xset-empty-p xset) (not fp-zeroes))
1310         (apply #'type-union numeric-type misc-types)
1311         (apply #'type-union (make-member-type :xset xset :fp-zeroes fp-zeroes)
1312                numeric-type misc-types))))
1313
1314 ;;; Convert a member type with a single member to a numeric type.
1315 (defun convert-member-type (arg)
1316   (let* ((members (member-type-members arg))
1317          (member (first members))
1318          (member-type (type-of member)))
1319     (aver (not (rest members)))
1320     (specifier-type (cond ((typep member 'integer)
1321                            `(integer ,member ,member))
1322                           ((memq member-type '(short-float single-float
1323                                                double-float long-float))
1324                            `(,member-type ,member ,member))
1325                           (t
1326                            member-type)))))
1327
1328 ;;; This is used in defoptimizers for computing the resulting type of
1329 ;;; a function.
1330 ;;;
1331 ;;; Given the lvar ARG, derive the resulting type using the
1332 ;;; DERIVE-FUN. DERIVE-FUN takes exactly one argument which is some
1333 ;;; "atomic" lvar type like numeric-type or member-type (containing
1334 ;;; just one element). It should return the resulting type, which can
1335 ;;; be a list of types.
1336 ;;;
1337 ;;; For the case of member types, if a MEMBER-FUN is given it is
1338 ;;; called to compute the result otherwise the member type is first
1339 ;;; converted to a numeric type and the DERIVE-FUN is called.
1340 (defun one-arg-derive-type (arg derive-fun member-fun
1341                                 &optional (convert-type t))
1342   (declare (type function derive-fun)
1343            (type (or null function) member-fun))
1344   (let ((arg-list (prepare-arg-for-derive-type (lvar-type arg))))
1345     (when arg-list
1346       (flet ((deriver (x)
1347                (typecase x
1348                  (member-type
1349                   (if member-fun
1350                       (with-float-traps-masked
1351                           (:underflow :overflow :divide-by-zero)
1352                         (specifier-type
1353                          `(eql ,(funcall member-fun
1354                                          (first (member-type-members x))))))
1355                       ;; Otherwise convert to a numeric type.
1356                       (let ((result-type-list
1357                              (funcall derive-fun (convert-member-type x))))
1358                         (if convert-type
1359                             (convert-back-numeric-type-list result-type-list)
1360                             result-type-list))))
1361                  (numeric-type
1362                   (if convert-type
1363                       (convert-back-numeric-type-list
1364                        (funcall derive-fun (convert-numeric-type x)))
1365                       (funcall derive-fun x)))
1366                  (t
1367                   *universal-type*))))
1368         ;; Run down the list of args and derive the type of each one,
1369         ;; saving all of the results in a list.
1370         (let ((results nil))
1371           (dolist (arg arg-list)
1372             (let ((result (deriver arg)))
1373               (if (listp result)
1374                   (setf results (append results result))
1375                   (push result results))))
1376           (if (rest results)
1377               (make-derived-union-type results)
1378               (first results)))))))
1379
1380 ;;; Same as ONE-ARG-DERIVE-TYPE, except we assume the function takes
1381 ;;; two arguments. DERIVE-FUN takes 3 args in this case: the two
1382 ;;; original args and a third which is T to indicate if the two args
1383 ;;; really represent the same lvar. This is useful for deriving the
1384 ;;; type of things like (* x x), which should always be positive. If
1385 ;;; we didn't do this, we wouldn't be able to tell.
1386 (defun two-arg-derive-type (arg1 arg2 derive-fun fun
1387                                  &optional (convert-type t))
1388   (declare (type function derive-fun fun))
1389   (flet ((deriver (x y same-arg)
1390            (cond ((and (member-type-p x) (member-type-p y))
1391                   (let* ((x (first (member-type-members x)))
1392                          (y (first (member-type-members y)))
1393                          (result (ignore-errors
1394                                    (with-float-traps-masked
1395                                        (:underflow :overflow :divide-by-zero
1396                                                    :invalid)
1397                                      (funcall fun x y)))))
1398                     (cond ((null result) *empty-type*)
1399                           ((and (floatp result) (float-nan-p result))
1400                            (make-numeric-type :class 'float
1401                                               :format (type-of result)
1402                                               :complexp :real))
1403                           (t
1404                            (specifier-type `(eql ,result))))))
1405                  ((and (member-type-p x) (numeric-type-p y))
1406                   (let* ((x (convert-member-type x))
1407                          (y (if convert-type (convert-numeric-type y) y))
1408                          (result (funcall derive-fun x y same-arg)))
1409                     (if convert-type
1410                         (convert-back-numeric-type-list result)
1411                         result)))
1412                  ((and (numeric-type-p x) (member-type-p y))
1413                   (let* ((x (if convert-type (convert-numeric-type x) x))
1414                          (y (convert-member-type y))
1415                          (result (funcall derive-fun x y same-arg)))
1416                     (if convert-type
1417                         (convert-back-numeric-type-list result)
1418                         result)))
1419                  ((and (numeric-type-p x) (numeric-type-p y))
1420                   (let* ((x (if convert-type (convert-numeric-type x) x))
1421                          (y (if convert-type (convert-numeric-type y) y))
1422                          (result (funcall derive-fun x y same-arg)))
1423                     (if convert-type
1424                         (convert-back-numeric-type-list result)
1425                         result)))
1426                  (t
1427                   *universal-type*))))
1428     (let ((same-arg (same-leaf-ref-p arg1 arg2))
1429           (a1 (prepare-arg-for-derive-type (lvar-type arg1)))
1430           (a2 (prepare-arg-for-derive-type (lvar-type arg2))))
1431       (when (and a1 a2)
1432         (let ((results nil))
1433           (if same-arg
1434               ;; Since the args are the same LVARs, just run down the
1435               ;; lists.
1436               (dolist (x a1)
1437                 (let ((result (deriver x x same-arg)))
1438                   (if (listp result)
1439                       (setf results (append results result))
1440                       (push result results))))
1441               ;; Try all pairwise combinations.
1442               (dolist (x a1)
1443                 (dolist (y a2)
1444                   (let ((result (or (deriver x y same-arg)
1445                                     (numeric-contagion x y))))
1446                     (if (listp result)
1447                         (setf results (append results result))
1448                         (push result results))))))
1449           (if (rest results)
1450               (make-derived-union-type results)
1451               (first results)))))))
1452 \f
1453 #+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1454 (progn
1455 (defoptimizer (+ derive-type) ((x y))
1456   (derive-integer-type
1457    x y
1458    #'(lambda (x y)
1459        (flet ((frob (x y)
1460                 (if (and x y)
1461                     (+ x y)
1462                     nil)))
1463          (values (frob (numeric-type-low x) (numeric-type-low y))
1464                  (frob (numeric-type-high x) (numeric-type-high y)))))))
1465
1466 (defoptimizer (- derive-type) ((x y))
1467   (derive-integer-type
1468    x y
1469    #'(lambda (x y)
1470        (flet ((frob (x y)
1471                 (if (and x y)
1472                     (- x y)
1473                     nil)))
1474          (values (frob (numeric-type-low x) (numeric-type-high y))
1475                  (frob (numeric-type-high x) (numeric-type-low y)))))))
1476
1477 (defoptimizer (* derive-type) ((x y))
1478   (derive-integer-type
1479    x y
1480    #'(lambda (x y)
1481        (let ((x-low (numeric-type-low x))
1482              (x-high (numeric-type-high x))
1483              (y-low (numeric-type-low y))
1484              (y-high (numeric-type-high y)))
1485          (cond ((not (and x-low y-low))
1486                 (values nil nil))
1487                ((or (minusp x-low) (minusp y-low))
1488                 (if (and x-high y-high)
1489                     (let ((max (* (max (abs x-low) (abs x-high))
1490                                   (max (abs y-low) (abs y-high)))))
1491                       (values (- max) max))
1492                     (values nil nil)))
1493                (t
1494                 (values (* x-low y-low)
1495                         (if (and x-high y-high)
1496                             (* x-high y-high)
1497                             nil))))))))
1498
1499 (defoptimizer (/ derive-type) ((x y))
1500   (numeric-contagion (lvar-type x) (lvar-type y)))
1501
1502 ) ; PROGN
1503
1504 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1505 (progn
1506 (defun +-derive-type-aux (x y same-arg)
1507   (if (and (numeric-type-real-p x)
1508            (numeric-type-real-p y))
1509       (let ((result
1510              (if same-arg
1511                  (let ((x-int (numeric-type->interval x)))
1512                    (interval-add x-int x-int))
1513                  (interval-add (numeric-type->interval x)
1514                                (numeric-type->interval y))))
1515             (result-type (numeric-contagion x y)))
1516         ;; If the result type is a float, we need to be sure to coerce
1517         ;; the bounds into the correct type.
1518         (when (eq (numeric-type-class result-type) 'float)
1519           (setf result (interval-func
1520                         #'(lambda (x)
1521                             (coerce-for-bound x (or (numeric-type-format result-type)
1522                                                     'float)))
1523                         result)))
1524         (make-numeric-type
1525          :class (if (and (eq (numeric-type-class x) 'integer)
1526                          (eq (numeric-type-class y) 'integer))
1527                     ;; The sum of integers is always an integer.
1528                     'integer
1529                     (numeric-type-class result-type))
1530          :format (numeric-type-format result-type)
1531          :low (interval-low result)
1532          :high (interval-high result)))
1533       ;; general contagion
1534       (numeric-contagion x y)))
1535
1536 (defoptimizer (+ derive-type) ((x y))
1537   (two-arg-derive-type x y #'+-derive-type-aux #'+))
1538
1539 (defun --derive-type-aux (x y same-arg)
1540   (if (and (numeric-type-real-p x)
1541            (numeric-type-real-p y))
1542       (let ((result
1543              ;; (- X X) is always 0.
1544              (if same-arg
1545                  (make-interval :low 0 :high 0)
1546                  (interval-sub (numeric-type->interval x)
1547                                (numeric-type->interval y))))
1548             (result-type (numeric-contagion x y)))
1549         ;; If the result type is a float, we need to be sure to coerce
1550         ;; the bounds into the correct type.
1551         (when (eq (numeric-type-class result-type) 'float)
1552           (setf result (interval-func
1553                         #'(lambda (x)
1554                             (coerce-for-bound x (or (numeric-type-format result-type)
1555                                                     'float)))
1556                         result)))
1557         (make-numeric-type
1558          :class (if (and (eq (numeric-type-class x) 'integer)
1559                          (eq (numeric-type-class y) 'integer))
1560                     ;; The difference of integers is always an integer.
1561                     'integer
1562                     (numeric-type-class result-type))
1563          :format (numeric-type-format result-type)
1564          :low (interval-low result)
1565          :high (interval-high result)))
1566       ;; general contagion
1567       (numeric-contagion x y)))
1568
1569 (defoptimizer (- derive-type) ((x y))
1570   (two-arg-derive-type x y #'--derive-type-aux #'-))
1571
1572 (defun *-derive-type-aux (x y same-arg)
1573   (if (and (numeric-type-real-p x)
1574            (numeric-type-real-p y))
1575       (let ((result
1576              ;; (* X X) is always positive, so take care to do it right.
1577              (if same-arg
1578                  (interval-sqr (numeric-type->interval x))
1579                  (interval-mul (numeric-type->interval x)
1580                                (numeric-type->interval y))))
1581             (result-type (numeric-contagion x y)))
1582         ;; If the result type is a float, we need to be sure to coerce
1583         ;; the bounds into the correct type.
1584         (when (eq (numeric-type-class result-type) 'float)
1585           (setf result (interval-func
1586                         #'(lambda (x)
1587                             (coerce-for-bound x (or (numeric-type-format result-type)
1588                                                     'float)))
1589                         result)))
1590         (make-numeric-type
1591          :class (if (and (eq (numeric-type-class x) 'integer)
1592                          (eq (numeric-type-class y) 'integer))
1593                     ;; The product of integers is always an integer.
1594                     'integer
1595                     (numeric-type-class result-type))
1596          :format (numeric-type-format result-type)
1597          :low (interval-low result)
1598          :high (interval-high result)))
1599       (numeric-contagion x y)))
1600
1601 (defoptimizer (* derive-type) ((x y))
1602   (two-arg-derive-type x y #'*-derive-type-aux #'*))
1603
1604 (defun /-derive-type-aux (x y same-arg)
1605   (if (and (numeric-type-real-p x)
1606            (numeric-type-real-p y))
1607       (let ((result
1608              ;; (/ X X) is always 1, except if X can contain 0. In
1609              ;; that case, we shouldn't optimize the division away
1610              ;; because we want 0/0 to signal an error.
1611              (if (and same-arg
1612                       (not (interval-contains-p
1613                             0 (interval-closure (numeric-type->interval y)))))
1614                  (make-interval :low 1 :high 1)
1615                  (interval-div (numeric-type->interval x)
1616                                (numeric-type->interval y))))
1617             (result-type (numeric-contagion x y)))
1618         ;; If the result type is a float, we need to be sure to coerce
1619         ;; the bounds into the correct type.
1620         (when (eq (numeric-type-class result-type) 'float)
1621           (setf result (interval-func
1622                         #'(lambda (x)
1623                             (coerce-for-bound x (or (numeric-type-format result-type)
1624                                                     'float)))
1625                         result)))
1626         (make-numeric-type :class (numeric-type-class result-type)
1627                            :format (numeric-type-format result-type)
1628                            :low (interval-low result)
1629                            :high (interval-high result)))
1630       (numeric-contagion x y)))
1631
1632 (defoptimizer (/ derive-type) ((x y))
1633   (two-arg-derive-type x y #'/-derive-type-aux #'/))
1634
1635 ) ; PROGN
1636
1637 (defun ash-derive-type-aux (n-type shift same-arg)
1638   (declare (ignore same-arg))
1639   ;; KLUDGE: All this ASH optimization is suppressed under CMU CL for
1640   ;; some bignum cases because as of version 2.4.6 for Debian and 18d,
1641   ;; CMU CL blows up on (ASH 1000000000 -100000000000) (i.e. ASH of
1642   ;; two bignums yielding zero) and it's hard to avoid that
1643   ;; calculation in here.
1644   #+(and cmu sb-xc-host)
1645   (when (and (or (typep (numeric-type-low n-type) 'bignum)
1646                  (typep (numeric-type-high n-type) 'bignum))
1647              (or (typep (numeric-type-low shift) 'bignum)
1648                  (typep (numeric-type-high shift) 'bignum)))
1649     (return-from ash-derive-type-aux *universal-type*))
1650   (flet ((ash-outer (n s)
1651            (when (and (fixnump s)
1652                       (<= s 64)
1653                       (> s sb!xc:most-negative-fixnum))
1654              (ash n s)))
1655          ;; KLUDGE: The bare 64's here should be related to
1656          ;; symbolic machine word size values somehow.
1657
1658          (ash-inner (n s)
1659            (if (and (fixnump s)
1660                     (> s sb!xc:most-negative-fixnum))
1661              (ash n (min s 64))
1662              (if (minusp n) -1 0))))
1663     (or (and (csubtypep n-type (specifier-type 'integer))
1664              (csubtypep shift (specifier-type 'integer))
1665              (let ((n-low (numeric-type-low n-type))
1666                    (n-high (numeric-type-high n-type))
1667                    (s-low (numeric-type-low shift))
1668                    (s-high (numeric-type-high shift)))
1669                (make-numeric-type :class 'integer  :complexp :real
1670                                   :low (when n-low
1671                                          (if (minusp n-low)
1672                                            (ash-outer n-low s-high)
1673                                            (ash-inner n-low s-low)))
1674                                   :high (when n-high
1675                                           (if (minusp n-high)
1676                                             (ash-inner n-high s-low)
1677                                             (ash-outer n-high s-high))))))
1678         *universal-type*)))
1679
1680 (defoptimizer (ash derive-type) ((n shift))
1681   (two-arg-derive-type n shift #'ash-derive-type-aux #'ash))
1682
1683 #+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1684 (macrolet ((frob (fun)
1685              `#'(lambda (type type2)
1686                   (declare (ignore type2))
1687                   (let ((lo (numeric-type-low type))
1688                         (hi (numeric-type-high type)))
1689                     (values (if hi (,fun hi) nil) (if lo (,fun lo) nil))))))
1690
1691   (defoptimizer (%negate derive-type) ((num))
1692     (derive-integer-type num num (frob -))))
1693
1694 (defun lognot-derive-type-aux (int)
1695   (derive-integer-type-aux int int
1696                            (lambda (type type2)
1697                              (declare (ignore type2))
1698                              (let ((lo (numeric-type-low type))
1699                                    (hi (numeric-type-high type)))
1700                                (values (if hi (lognot hi) nil)
1701                                        (if lo (lognot lo) nil)
1702                                        (numeric-type-class type)
1703                                        (numeric-type-format type))))))
1704
1705 (defoptimizer (lognot derive-type) ((int))
1706   (lognot-derive-type-aux (lvar-type int)))
1707
1708 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1709 (defoptimizer (%negate derive-type) ((num))
1710   (flet ((negate-bound (b)
1711            (and b
1712                 (set-bound (- (type-bound-number b))
1713                            (consp b)))))
1714     (one-arg-derive-type num
1715                          (lambda (type)
1716                            (modified-numeric-type
1717                             type
1718                             :low (negate-bound (numeric-type-high type))
1719                             :high (negate-bound (numeric-type-low type))))
1720                          #'-)))
1721
1722 #+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1723 (defoptimizer (abs derive-type) ((num))
1724   (let ((type (lvar-type num)))
1725     (if (and (numeric-type-p type)
1726              (eq (numeric-type-class type) 'integer)
1727              (eq (numeric-type-complexp type) :real))
1728         (let ((lo (numeric-type-low type))
1729               (hi (numeric-type-high type)))
1730           (make-numeric-type :class 'integer :complexp :real
1731                              :low (cond ((and hi (minusp hi))
1732                                          (abs hi))
1733                                         (lo
1734                                          (max 0 lo))
1735                                         (t
1736                                          0))
1737                              :high (if (and hi lo)
1738                                        (max (abs hi) (abs lo))
1739                                        nil)))
1740         (numeric-contagion type type))))
1741
1742 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1743 (defun abs-derive-type-aux (type)
1744   (cond ((eq (numeric-type-complexp type) :complex)
1745          ;; The absolute value of a complex number is always a
1746          ;; non-negative float.
1747          (let* ((format (case (numeric-type-class type)
1748                           ((integer rational) 'single-float)
1749                           (t (numeric-type-format type))))
1750                 (bound-format (or format 'float)))
1751            (make-numeric-type :class 'float
1752                               :format format
1753                               :complexp :real
1754                               :low (coerce 0 bound-format)
1755                               :high nil)))
1756         (t
1757          ;; The absolute value of a real number is a non-negative real
1758          ;; of the same type.
1759          (let* ((abs-bnd (interval-abs (numeric-type->interval type)))
1760                 (class (numeric-type-class type))
1761                 (format (numeric-type-format type))
1762                 (bound-type (or format class 'real)))
1763            (make-numeric-type
1764             :class class
1765             :format format
1766             :complexp :real
1767             :low (coerce-and-truncate-floats (interval-low abs-bnd) bound-type)
1768             :high (coerce-and-truncate-floats
1769                    (interval-high abs-bnd) bound-type))))))
1770
1771 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1772 (defoptimizer (abs derive-type) ((num))
1773   (one-arg-derive-type num #'abs-derive-type-aux #'abs))
1774
1775 #+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1776 (defoptimizer (truncate derive-type) ((number divisor))
1777   (let ((number-type (lvar-type number))
1778         (divisor-type (lvar-type divisor))
1779         (integer-type (specifier-type 'integer)))
1780     (if (and (numeric-type-p number-type)
1781              (csubtypep number-type integer-type)
1782              (numeric-type-p divisor-type)
1783              (csubtypep divisor-type integer-type))
1784         (let ((number-low (numeric-type-low number-type))
1785               (number-high (numeric-type-high number-type))
1786               (divisor-low (numeric-type-low divisor-type))
1787               (divisor-high (numeric-type-high divisor-type)))
1788           (values-specifier-type
1789            `(values ,(integer-truncate-derive-type number-low number-high
1790                                                    divisor-low divisor-high)
1791                     ,(integer-rem-derive-type number-low number-high
1792                                               divisor-low divisor-high))))
1793         *universal-type*)))
1794
1795 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1796 (progn
1797
1798 (defun rem-result-type (number-type divisor-type)
1799   ;; Figure out what the remainder type is. The remainder is an
1800   ;; integer if both args are integers; a rational if both args are
1801   ;; rational; and a float otherwise.
1802   (cond ((and (csubtypep number-type (specifier-type 'integer))
1803               (csubtypep divisor-type (specifier-type 'integer)))
1804          'integer)
1805         ((and (csubtypep number-type (specifier-type 'rational))
1806               (csubtypep divisor-type (specifier-type 'rational)))
1807          'rational)
1808         ((and (csubtypep number-type (specifier-type 'float))
1809               (csubtypep divisor-type (specifier-type 'float)))
1810          ;; Both are floats so the result is also a float, of
1811          ;; the largest type.
1812          (or (float-format-max (numeric-type-format number-type)
1813                                (numeric-type-format divisor-type))
1814              'float))
1815         ((and (csubtypep number-type (specifier-type 'float))
1816               (csubtypep divisor-type (specifier-type 'rational)))
1817          ;; One of the arguments is a float and the other is a
1818          ;; rational. The remainder is a float of the same
1819          ;; type.
1820          (or (numeric-type-format number-type) 'float))
1821         ((and (csubtypep divisor-type (specifier-type 'float))
1822               (csubtypep number-type (specifier-type 'rational)))
1823          ;; One of the arguments is a float and the other is a
1824          ;; rational. The remainder is a float of the same
1825          ;; type.
1826          (or (numeric-type-format divisor-type) 'float))
1827         (t
1828          ;; Some unhandled combination. This usually means both args
1829          ;; are REAL so the result is a REAL.
1830          'real)))
1831
1832 (defun truncate-derive-type-quot (number-type divisor-type)
1833   (let* ((rem-type (rem-result-type number-type divisor-type))
1834          (number-interval (numeric-type->interval number-type))
1835          (divisor-interval (numeric-type->interval divisor-type)))
1836     ;;(declare (type (member '(integer rational float)) rem-type))
1837     ;; We have real numbers now.
1838     (cond ((eq rem-type 'integer)
1839            ;; Since the remainder type is INTEGER, both args are
1840            ;; INTEGERs.
1841            (let* ((res (integer-truncate-derive-type
1842                         (interval-low number-interval)
1843                         (interval-high number-interval)
1844                         (interval-low divisor-interval)
1845                         (interval-high divisor-interval))))
1846              (specifier-type (if (listp res) res 'integer))))
1847           (t
1848            (let ((quot (truncate-quotient-bound
1849                         (interval-div number-interval
1850                                       divisor-interval))))
1851              (specifier-type `(integer ,(or (interval-low quot) '*)
1852                                        ,(or (interval-high quot) '*))))))))
1853
1854 (defun truncate-derive-type-rem (number-type divisor-type)
1855   (let* ((rem-type (rem-result-type number-type divisor-type))
1856          (number-interval (numeric-type->interval number-type))
1857          (divisor-interval (numeric-type->interval divisor-type))
1858          (rem (truncate-rem-bound number-interval divisor-interval)))
1859     ;;(declare (type (member '(integer rational float)) rem-type))
1860     ;; We have real numbers now.
1861     (cond ((eq rem-type 'integer)
1862            ;; Since the remainder type is INTEGER, both args are
1863            ;; INTEGERs.
1864            (specifier-type `(,rem-type ,(or (interval-low rem) '*)
1865                                        ,(or (interval-high rem) '*))))
1866           (t
1867            (multiple-value-bind (class format)
1868                (ecase rem-type
1869                  (integer
1870                   (values 'integer nil))
1871                  (rational
1872                   (values 'rational nil))
1873                  ((or single-float double-float #!+long-float long-float)
1874                   (values 'float rem-type))
1875                  (float
1876                   (values 'float nil))
1877                  (real
1878                   (values nil nil)))
1879              (when (member rem-type '(float single-float double-float
1880                                             #!+long-float long-float))
1881                (setf rem (interval-func #'(lambda (x)
1882                                             (coerce-for-bound x rem-type))
1883                                         rem)))
1884              (make-numeric-type :class class
1885                                 :format format
1886                                 :low (interval-low rem)
1887                                 :high (interval-high rem)))))))
1888
1889 (defun truncate-derive-type-quot-aux (num div same-arg)
1890   (declare (ignore same-arg))
1891   (if (and (numeric-type-real-p num)
1892            (numeric-type-real-p div))
1893       (truncate-derive-type-quot num div)
1894       *empty-type*))
1895
1896 (defun truncate-derive-type-rem-aux (num div same-arg)
1897   (declare (ignore same-arg))
1898   (if (and (numeric-type-real-p num)
1899            (numeric-type-real-p div))
1900       (truncate-derive-type-rem num div)
1901       *empty-type*))
1902
1903 (defoptimizer (truncate derive-type) ((number divisor))
1904   (let ((quot (two-arg-derive-type number divisor
1905                                    #'truncate-derive-type-quot-aux #'truncate))
1906         (rem (two-arg-derive-type number divisor
1907                                   #'truncate-derive-type-rem-aux #'rem)))
1908     (when (and quot rem)
1909       (make-values-type :required (list quot rem)))))
1910
1911 (defun ftruncate-derive-type-quot (number-type divisor-type)
1912   ;; The bounds are the same as for truncate. However, the first
1913   ;; result is a float of some type. We need to determine what that
1914   ;; type is. Basically it's the more contagious of the two types.
1915   (let ((q-type (truncate-derive-type-quot number-type divisor-type))
1916         (res-type (numeric-contagion number-type divisor-type)))
1917     (make-numeric-type :class 'float
1918                        :format (numeric-type-format res-type)
1919                        :low (numeric-type-low q-type)
1920                        :high (numeric-type-high q-type))))
1921
1922 (defun ftruncate-derive-type-quot-aux (n d same-arg)
1923   (declare (ignore same-arg))
1924   (if (and (numeric-type-real-p n)
1925            (numeric-type-real-p d))
1926       (ftruncate-derive-type-quot n d)
1927       *empty-type*))
1928
1929 (defoptimizer (ftruncate derive-type) ((number divisor))
1930   (let ((quot
1931          (two-arg-derive-type number divisor
1932                               #'ftruncate-derive-type-quot-aux #'ftruncate))
1933         (rem (two-arg-derive-type number divisor
1934                                   #'truncate-derive-type-rem-aux #'rem)))
1935     (when (and quot rem)
1936       (make-values-type :required (list quot rem)))))
1937
1938 (defun %unary-truncate-derive-type-aux (number)
1939   (truncate-derive-type-quot number (specifier-type '(integer 1 1))))
1940
1941 (defoptimizer (%unary-truncate derive-type) ((number))
1942   (one-arg-derive-type number
1943                        #'%unary-truncate-derive-type-aux
1944                        #'%unary-truncate))
1945
1946 (defoptimizer (%unary-truncate/single-float derive-type) ((number))
1947   (one-arg-derive-type number
1948                        #'%unary-truncate-derive-type-aux
1949                        #'%unary-truncate))
1950
1951 (defoptimizer (%unary-truncate/double-float derive-type) ((number))
1952   (one-arg-derive-type number
1953                        #'%unary-truncate-derive-type-aux
1954                        #'%unary-truncate))
1955
1956 (defoptimizer (%unary-ftruncate derive-type) ((number))
1957   (let ((divisor (specifier-type '(integer 1 1))))
1958     (one-arg-derive-type number
1959                          #'(lambda (n)
1960                              (ftruncate-derive-type-quot-aux n divisor nil))
1961                          #'%unary-ftruncate)))
1962
1963 (defoptimizer (%unary-round derive-type) ((number))
1964   (one-arg-derive-type number
1965                        (lambda (n)
1966                          (block nil
1967                            (unless (numeric-type-real-p n)
1968                              (return *empty-type*))
1969                            (let* ((interval (numeric-type->interval n))
1970                                   (low      (interval-low interval))
1971                                   (high     (interval-high interval)))
1972                              (when (consp low)
1973                                (setf low (car low)))
1974                              (when (consp high)
1975                                (setf high (car high)))
1976                              (specifier-type
1977                               `(integer ,(if low
1978                                              (round low)
1979                                              '*)
1980                                         ,(if high
1981                                              (round high)
1982                                              '*))))))
1983                        #'%unary-round))
1984
1985 ;;; Define optimizers for FLOOR and CEILING.
1986 (macrolet
1987     ((def (name q-name r-name)
1988        (let ((q-aux (symbolicate q-name "-AUX"))
1989              (r-aux (symbolicate r-name "-AUX")))
1990          `(progn
1991            ;; Compute type of quotient (first) result.
1992            (defun ,q-aux (number-type divisor-type)
1993              (let* ((number-interval
1994                      (numeric-type->interval number-type))
1995                     (divisor-interval
1996                      (numeric-type->interval divisor-type))
1997                     (quot (,q-name (interval-div number-interval
1998                                                  divisor-interval))))
1999                (specifier-type `(integer ,(or (interval-low quot) '*)
2000                                          ,(or (interval-high quot) '*)))))
2001            ;; Compute type of remainder.
2002            (defun ,r-aux (number-type divisor-type)
2003              (let* ((divisor-interval
2004                      (numeric-type->interval divisor-type))
2005                     (rem (,r-name divisor-interval))
2006                     (result-type (rem-result-type number-type divisor-type)))
2007                (multiple-value-bind (class format)
2008                    (ecase result-type
2009                      (integer
2010                       (values 'integer nil))
2011                      (rational
2012                       (values 'rational nil))
2013                      ((or single-float double-float #!+long-float long-float)
2014                       (values 'float result-type))
2015                      (float
2016                       (values 'float nil))
2017                      (real
2018                       (values nil nil)))
2019                  (when (member result-type '(float single-float double-float
2020                                              #!+long-float long-float))
2021                    ;; Make sure that the limits on the interval have
2022                    ;; the right type.
2023                    (setf rem (interval-func (lambda (x)
2024                                               (coerce-for-bound x result-type))
2025                                             rem)))
2026                  (make-numeric-type :class class
2027                                     :format format
2028                                     :low (interval-low rem)
2029                                     :high (interval-high rem)))))
2030            ;; the optimizer itself
2031            (defoptimizer (,name derive-type) ((number divisor))
2032              (flet ((derive-q (n d same-arg)
2033                       (declare (ignore same-arg))
2034                       (if (and (numeric-type-real-p n)
2035                                (numeric-type-real-p d))
2036                           (,q-aux n d)
2037                           *empty-type*))
2038                     (derive-r (n d same-arg)
2039                       (declare (ignore same-arg))
2040                       (if (and (numeric-type-real-p n)
2041                                (numeric-type-real-p d))
2042                           (,r-aux n d)
2043                           *empty-type*)))
2044                (let ((quot (two-arg-derive-type
2045                             number divisor #'derive-q #',name))
2046                      (rem (two-arg-derive-type
2047                            number divisor #'derive-r #'mod)))
2048                  (when (and quot rem)
2049                    (make-values-type :required (list quot rem))))))))))
2050
2051   (def floor floor-quotient-bound floor-rem-bound)
2052   (def ceiling ceiling-quotient-bound ceiling-rem-bound))
2053
2054 ;;; Define optimizers for FFLOOR and FCEILING
2055 (macrolet ((def (name q-name r-name)
2056              (let ((q-aux (symbolicate "F" q-name "-AUX"))
2057                    (r-aux (symbolicate r-name "-AUX")))
2058                `(progn
2059                   ;; Compute type of quotient (first) result.
2060                   (defun ,q-aux (number-type divisor-type)
2061                     (let* ((number-interval
2062                             (numeric-type->interval number-type))
2063                            (divisor-interval
2064                             (numeric-type->interval divisor-type))
2065                            (quot (,q-name (interval-div number-interval
2066                                                         divisor-interval)))
2067                            (res-type (numeric-contagion number-type
2068                                                         divisor-type)))
2069                       (make-numeric-type
2070                        :class (numeric-type-class res-type)
2071                        :format (numeric-type-format res-type)
2072                        :low  (interval-low quot)
2073                        :high (interval-high quot))))
2074
2075                   (defoptimizer (,name derive-type) ((number divisor))
2076                     (flet ((derive-q (n d same-arg)
2077                              (declare (ignore same-arg))
2078                              (if (and (numeric-type-real-p n)
2079                                       (numeric-type-real-p d))
2080                                  (,q-aux n d)
2081                                  *empty-type*))
2082                            (derive-r (n d same-arg)
2083                              (declare (ignore same-arg))
2084                              (if (and (numeric-type-real-p n)
2085                                       (numeric-type-real-p d))
2086                                  (,r-aux n d)
2087                                  *empty-type*)))
2088                       (let ((quot (two-arg-derive-type
2089                                    number divisor #'derive-q #',name))
2090                             (rem (two-arg-derive-type
2091                                   number divisor #'derive-r #'mod)))
2092                         (when (and quot rem)
2093                           (make-values-type :required (list quot rem))))))))))
2094
2095   (def ffloor floor-quotient-bound floor-rem-bound)
2096   (def fceiling ceiling-quotient-bound ceiling-rem-bound))
2097
2098 ;;; functions to compute the bounds on the quotient and remainder for
2099 ;;; the FLOOR function
2100 (defun floor-quotient-bound (quot)
2101   ;; Take the floor of the quotient and then massage it into what we
2102   ;; need.
2103   (let ((lo (interval-low quot))
2104         (hi (interval-high quot)))
2105     ;; Take the floor of the lower bound. The result is always a
2106     ;; closed lower bound.
2107     (setf lo (if lo
2108                  (floor (type-bound-number lo))
2109                  nil))
2110     ;; For the upper bound, we need to be careful.
2111     (setf hi
2112           (cond ((consp hi)
2113                  ;; An open bound. We need to be careful here because
2114                  ;; the floor of '(10.0) is 9, but the floor of
2115                  ;; 10.0 is 10.
2116                  (multiple-value-bind (q r) (floor (first hi))
2117                    (if (zerop r)
2118                        (1- q)
2119                        q)))
2120                 (hi
2121                  ;; A closed bound, so the answer is obvious.
2122                  (floor hi))
2123                 (t
2124                  hi)))
2125     (make-interval :low lo :high hi)))
2126 (defun floor-rem-bound (div)
2127   ;; The remainder depends only on the divisor. Try to get the
2128   ;; correct sign for the remainder if we can.
2129   (case (interval-range-info div)
2130     (+
2131      ;; The divisor is always positive.
2132      (let ((rem (interval-abs div)))
2133        (setf (interval-low rem) 0)
2134        (when (and (numberp (interval-high rem))
2135                   (not (zerop (interval-high rem))))
2136          ;; The remainder never contains the upper bound. However,
2137          ;; watch out for the case where the high limit is zero!
2138          (setf (interval-high rem) (list (interval-high rem))))
2139        rem))
2140     (-
2141      ;; The divisor is always negative.
2142      (let ((rem (interval-neg (interval-abs div))))
2143        (setf (interval-high rem) 0)
2144        (when (numberp (interval-low rem))
2145          ;; The remainder never contains the lower bound.
2146          (setf (interval-low rem) (list (interval-low rem))))
2147        rem))
2148     (otherwise
2149      ;; The divisor can be positive or negative. All bets off. The
2150      ;; magnitude of remainder is the maximum value of the divisor.
2151      (let ((limit (type-bound-number (interval-high (interval-abs div)))))
2152        ;; The bound never reaches the limit, so make the interval open.
2153        (make-interval :low (if limit
2154                                (list (- limit))
2155                                limit)
2156                       :high (list limit))))))
2157 #| Test cases
2158 (floor-quotient-bound (make-interval :low 0.3 :high 10.3))
2159 => #S(INTERVAL :LOW 0 :HIGH 10)
2160 (floor-quotient-bound (make-interval :low 0.3 :high '(10.3)))
2161 => #S(INTERVAL :LOW 0 :HIGH 10)
2162 (floor-quotient-bound (make-interval :low 0.3 :high 10))
2163 => #S(INTERVAL :LOW 0 :HIGH 10)
2164 (floor-quotient-bound (make-interval :low 0.3 :high '(10)))
2165 => #S(INTERVAL :LOW 0 :HIGH 9)
2166 (floor-quotient-bound (make-interval :low '(0.3) :high 10.3))
2167 => #S(INTERVAL :LOW 0 :HIGH 10)
2168 (floor-quotient-bound (make-interval :low '(0.0) :high 10.3))
2169 => #S(INTERVAL :LOW 0 :HIGH 10)
2170 (floor-quotient-bound (make-interval :low '(-1.3) :high 10.3))
2171 => #S(INTERVAL :LOW -2 :HIGH 10)
2172 (floor-quotient-bound (make-interval :low '(-1.0) :high 10.3))
2173 => #S(INTERVAL :LOW -1 :HIGH 10)
2174 (floor-quotient-bound (make-interval :low -1.0 :high 10.3))
2175 => #S(INTERVAL :LOW -1 :HIGH 10)
2176
2177 (floor-rem-bound (make-interval :low 0.3 :high 10.3))
2178 => #S(INTERVAL :LOW 0 :HIGH '(10.3))
2179 (floor-rem-bound (make-interval :low 0.3 :high '(10.3)))
2180 => #S(INTERVAL :LOW 0 :HIGH '(10.3))
2181 (floor-rem-bound (make-interval :low -10 :high -2.3))
2182 #S(INTERVAL :LOW (-10) :HIGH 0)
2183 (floor-rem-bound (make-interval :low 0.3 :high 10))
2184 => #S(INTERVAL :LOW 0 :HIGH '(10))
2185 (floor-rem-bound (make-interval :low '(-1.3) :high 10.3))
2186 => #S(INTERVAL :LOW '(-10.3) :HIGH '(10.3))
2187 (floor-rem-bound (make-interval :low '(-20.3) :high 10.3))
2188 => #S(INTERVAL :LOW (-20.3) :HIGH (20.3))
2189 |#
2190 \f
2191 ;;; same functions for CEILING
2192 (defun ceiling-quotient-bound (quot)
2193   ;; Take the ceiling of the quotient and then massage it into what we
2194   ;; need.
2195   (let ((lo (interval-low quot))
2196         (hi (interval-high quot)))
2197     ;; Take the ceiling of the upper bound. The result is always a
2198     ;; closed upper bound.
2199     (setf hi (if hi
2200                  (ceiling (type-bound-number hi))
2201                  nil))
2202     ;; For the lower bound, we need to be careful.
2203     (setf lo
2204           (cond ((consp lo)
2205                  ;; An open bound. We need to be careful here because
2206                  ;; the ceiling of '(10.0) is 11, but the ceiling of
2207                  ;; 10.0 is 10.
2208                  (multiple-value-bind (q r) (ceiling (first lo))
2209                    (if (zerop r)
2210                        (1+ q)
2211                        q)))
2212                 (lo
2213                  ;; A closed bound, so the answer is obvious.
2214                  (ceiling lo))
2215                 (t
2216                  lo)))
2217     (make-interval :low lo :high hi)))
2218 (defun ceiling-rem-bound (div)
2219   ;; The remainder depends only on the divisor. Try to get the
2220   ;; correct sign for the remainder if we can.
2221   (case (interval-range-info div)
2222     (+
2223      ;; Divisor is always positive. The remainder is negative.
2224      (let ((rem (interval-neg (interval-abs div))))
2225        (setf (interval-high rem) 0)
2226        (when (and (numberp (interval-low rem))
2227                   (not (zerop (interval-low rem))))
2228          ;; The remainder never contains the upper bound. However,
2229          ;; watch out for the case when the upper bound is zero!
2230          (setf (interval-low rem) (list (interval-low rem))))
2231        rem))
2232     (-
2233      ;; Divisor is always negative. The remainder is positive
2234      (let ((rem (interval-abs div)))
2235        (setf (interval-low rem) 0)
2236        (when (numberp (interval-high rem))
2237          ;; The remainder never contains the lower bound.
2238          (setf (interval-high rem) (list (interval-high rem))))
2239        rem))
2240     (otherwise
2241      ;; The divisor can be positive or negative. All bets off. The
2242      ;; magnitude of remainder is the maximum value of the divisor.
2243      (let ((limit (type-bound-number (interval-high (interval-abs div)))))
2244        ;; The bound never reaches the limit, so make the interval open.
2245        (make-interval :low (if limit
2246                                (list (- limit))
2247                                limit)
2248                       :high (list limit))))))
2249
2250 #| Test cases
2251 (ceiling-quotient-bound (make-interval :low 0.3 :high 10.3))
2252 => #S(INTERVAL :LOW 1 :HIGH 11)
2253 (ceiling-quotient-bound (make-interval :low 0.3 :high '(10.3)))
2254 => #S(INTERVAL :LOW 1 :HIGH 11)
2255 (ceiling-quotient-bound (make-interval :low 0.3 :high 10))
2256 => #S(INTERVAL :LOW 1 :HIGH 10)
2257 (ceiling-quotient-bound (make-interval :low 0.3 :high '(10)))
2258 => #S(INTERVAL :LOW 1 :HIGH 10)
2259 (ceiling-quotient-bound (make-interval :low '(0.3) :high 10.3))
2260 => #S(INTERVAL :LOW 1 :HIGH 11)
2261 (ceiling-quotient-bound (make-interval :low '(0.0) :high 10.3))
2262 => #S(INTERVAL :LOW 1 :HIGH 11)
2263 (ceiling-quotient-bound (make-interval :low '(-1.3) :high 10.3))
2264 => #S(INTERVAL :LOW -1 :HIGH 11)
2265 (ceiling-quotient-bound (make-interval :low '(-1.0) :high 10.3))
2266 => #S(INTERVAL :LOW 0 :HIGH 11)
2267 (ceiling-quotient-bound (make-interval :low -1.0 :high 10.3))
2268 => #S(INTERVAL :LOW -1 :HIGH 11)
2269
2270 (ceiling-rem-bound (make-interval :low 0.3 :high 10.3))
2271 => #S(INTERVAL :LOW (-10.3) :HIGH 0)
2272 (ceiling-rem-bound (make-interval :low 0.3 :high '(10.3)))
2273 => #S(INTERVAL :LOW 0 :HIGH '(10.3))
2274 (ceiling-rem-bound (make-interval :low -10 :high -2.3))
2275 => #S(INTERVAL :LOW 0 :HIGH (10))
2276 (ceiling-rem-bound (make-interval :low 0.3 :high 10))
2277 => #S(INTERVAL :LOW (-10) :HIGH 0)
2278 (ceiling-rem-bound (make-interval :low '(-1.3) :high 10.3))
2279 => #S(INTERVAL :LOW (-10.3) :HIGH (10.3))
2280 (ceiling-rem-bound (make-interval :low '(-20.3) :high 10.3))
2281 => #S(INTERVAL :LOW (-20.3) :HIGH (20.3))
2282 |#
2283 \f
2284 (defun truncate-quotient-bound (quot)
2285   ;; For positive quotients, truncate is exactly like floor. For
2286   ;; negative quotients, truncate is exactly like ceiling. Otherwise,
2287   ;; it's the union of the two pieces.
2288   (case (interval-range-info quot)
2289     (+
2290      ;; just like FLOOR
2291      (floor-quotient-bound quot))
2292     (-
2293      ;; just like CEILING
2294      (ceiling-quotient-bound quot))
2295     (otherwise
2296      ;; Split the interval into positive and negative pieces, compute
2297      ;; the result for each piece and put them back together.
2298      (destructuring-bind (neg pos) (interval-split 0 quot t t)
2299        (interval-merge-pair (ceiling-quotient-bound neg)
2300                             (floor-quotient-bound pos))))))
2301
2302 (defun truncate-rem-bound (num div)
2303   ;; This is significantly more complicated than FLOOR or CEILING. We
2304   ;; need both the number and the divisor to determine the range. The
2305   ;; basic idea is to split the ranges of NUM and DEN into positive
2306   ;; and negative pieces and deal with each of the four possibilities
2307   ;; in turn.
2308   (case (interval-range-info num)
2309     (+
2310      (case (interval-range-info div)
2311        (+
2312         (floor-rem-bound div))
2313        (-
2314         (ceiling-rem-bound div))
2315        (otherwise
2316         (destructuring-bind (neg pos) (interval-split 0 div t t)
2317           (interval-merge-pair (truncate-rem-bound num neg)
2318                                (truncate-rem-bound num pos))))))
2319     (-
2320      (case (interval-range-info div)
2321        (+
2322         (ceiling-rem-bound div))
2323        (-
2324         (floor-rem-bound div))
2325        (otherwise
2326         (destructuring-bind (neg pos) (interval-split 0 div t t)
2327           (interval-merge-pair (truncate-rem-bound num neg)
2328                                (truncate-rem-bound num pos))))))
2329     (otherwise
2330      (destructuring-bind (neg pos) (interval-split 0 num t t)
2331        (interval-merge-pair (truncate-rem-bound neg div)
2332                             (truncate-rem-bound pos div))))))
2333 ) ; PROGN
2334
2335 ;;; Derive useful information about the range. Returns three values:
2336 ;;; - '+ if its positive, '- negative, or nil if it overlaps 0.
2337 ;;; - The abs of the minimal value (i.e. closest to 0) in the range.
2338 ;;; - The abs of the maximal value if there is one, or nil if it is
2339 ;;;   unbounded.
2340 (defun numeric-range-info (low high)
2341   (cond ((and low (not (minusp low)))
2342          (values '+ low high))
2343         ((and high (not (plusp high)))
2344          (values '- (- high) (if low (- low) nil)))
2345         (t
2346          (values nil 0 (and low high (max (- low) high))))))
2347
2348 (defun integer-truncate-derive-type
2349        (number-low number-high divisor-low divisor-high)
2350   ;; The result cannot be larger in magnitude than the number, but the
2351   ;; sign might change. If we can determine the sign of either the
2352   ;; number or the divisor, we can eliminate some of the cases.
2353   (multiple-value-bind (number-sign number-min number-max)
2354       (numeric-range-info number-low number-high)
2355     (multiple-value-bind (divisor-sign divisor-min divisor-max)
2356         (numeric-range-info divisor-low divisor-high)
2357       (when (and divisor-max (zerop divisor-max))
2358         ;; We've got a problem: guaranteed division by zero.
2359         (return-from integer-truncate-derive-type t))
2360       (when (zerop divisor-min)
2361         ;; We'll assume that they aren't going to divide by zero.
2362         (incf divisor-min))
2363       (cond ((and number-sign divisor-sign)
2364              ;; We know the sign of both.
2365              (if (eq number-sign divisor-sign)
2366                  ;; Same sign, so the result will be positive.
2367                  `(integer ,(if divisor-max
2368                                 (truncate number-min divisor-max)
2369                                 0)
2370                            ,(if number-max
2371                                 (truncate number-max divisor-min)
2372                                 '*))
2373                  ;; Different signs, the result will be negative.
2374                  `(integer ,(if number-max
2375                                 (- (truncate number-max divisor-min))
2376                                 '*)
2377                            ,(if divisor-max
2378                                 (- (truncate number-min divisor-max))
2379                                 0))))
2380             ((eq divisor-sign '+)
2381              ;; The divisor is positive. Therefore, the number will just
2382              ;; become closer to zero.
2383              `(integer ,(if number-low
2384                             (truncate number-low divisor-min)
2385                             '*)
2386                        ,(if number-high
2387                             (truncate number-high divisor-min)
2388                             '*)))
2389             ((eq divisor-sign '-)
2390              ;; The divisor is negative. Therefore, the absolute value of
2391              ;; the number will become closer to zero, but the sign will also
2392              ;; change.
2393              `(integer ,(if number-high
2394                             (- (truncate number-high divisor-min))
2395                             '*)
2396                        ,(if number-low
2397                             (- (truncate number-low divisor-min))
2398                             '*)))
2399             ;; The divisor could be either positive or negative.
2400             (number-max
2401              ;; The number we are dividing has a bound. Divide that by the
2402              ;; smallest posible divisor.
2403              (let ((bound (truncate number-max divisor-min)))
2404                `(integer ,(- bound) ,bound)))
2405             (t
2406              ;; The number we are dividing is unbounded, so we can't tell
2407              ;; anything about the result.
2408              `integer)))))
2409
2410 #+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
2411 (defun integer-rem-derive-type
2412        (number-low number-high divisor-low divisor-high)
2413   (if (and divisor-low divisor-high)
2414       ;; We know the range of the divisor, and the remainder must be
2415       ;; smaller than the divisor. We can tell the sign of the
2416       ;; remainder if we know the sign of the number.
2417       (let ((divisor-max (1- (max (abs divisor-low) (abs divisor-high)))))
2418         `(integer ,(if (or (null number-low)
2419                            (minusp number-low))
2420                        (- divisor-max)
2421                        0)
2422                   ,(if (or (null number-high)
2423                            (plusp number-high))
2424                        divisor-max
2425                        0)))
2426       ;; The divisor is potentially either very positive or very
2427       ;; negative. Therefore, the remainder is unbounded, but we might
2428       ;; be able to tell something about the sign from the number.
2429       `(integer ,(if (and number-low (not (minusp number-low)))
2430                      ;; The number we are dividing is positive.
2431                      ;; Therefore, the remainder must be positive.
2432                      0
2433                      '*)
2434                 ,(if (and number-high (not (plusp number-high)))
2435                      ;; The number we are dividing is negative.
2436                      ;; Therefore, the remainder must be negative.
2437                      0
2438                      '*))))
2439
2440 #+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
2441 (defoptimizer (random derive-type) ((bound &optional state))
2442   (let ((type (lvar-type bound)))
2443     (when (numeric-type-p type)
2444       (let ((class (numeric-type-class type))
2445             (high (numeric-type-high type))
2446             (format (numeric-type-format type)))
2447         (make-numeric-type
2448          :class class
2449          :format format
2450          :low (coerce 0 (or format class 'real))
2451          :high (cond ((not high) nil)
2452                      ((eq class 'integer) (max (1- high) 0))
2453                      ((or (consp high) (zerop high)) high)
2454                      (t `(,high))))))))
2455
2456 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
2457 (defun random-derive-type-aux (type)
2458   (let ((class (numeric-type-class type))
2459         (high (numeric-type-high type))
2460         (format (numeric-type-format type)))
2461     (make-numeric-type
2462          :class class
2463          :format format
2464          :low (coerce 0 (or format class 'real))
2465          :high (cond ((not high) nil)
2466                      ((eq class 'integer) (max (1- high) 0))
2467                      ((or (consp high) (zerop high)) high)
2468                      (t `(,high))))))
2469
2470 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
2471 (defoptimizer (random derive-type) ((bound &optional state))
2472   (one-arg-derive-type bound #'random-derive-type-aux nil))
2473 \f
2474 ;;;; miscellaneous derive-type methods
2475
2476 (defoptimizer (integer-length derive-type) ((x))
2477   (let ((x-type (lvar-type x)))
2478     (when (numeric-type-p x-type)
2479       ;; If the X is of type (INTEGER LO HI), then the INTEGER-LENGTH
2480       ;; of X is (INTEGER (MIN lo hi) (MAX lo hi), basically.  Be
2481       ;; careful about LO or HI being NIL, though.  Also, if 0 is
2482       ;; contained in X, the lower bound is obviously 0.
2483       (flet ((null-or-min (a b)
2484                (and a b (min (integer-length a)
2485                              (integer-length b))))
2486              (null-or-max (a b)
2487                (and a b (max (integer-length a)
2488                              (integer-length b)))))
2489         (let* ((min (numeric-type-low x-type))
2490                (max (numeric-type-high x-type))
2491                (min-len (null-or-min min max))
2492                (max-len (null-or-max min max)))
2493           (when (ctypep 0 x-type)
2494             (setf min-len 0))
2495           (specifier-type `(integer ,(or min-len '*) ,(or max-len '*))))))))
2496
2497 (defoptimizer (isqrt derive-type) ((x))
2498   (let ((x-type (lvar-type x)))
2499     (when (numeric-type-p x-type)
2500       (let* ((lo (numeric-type-low x-type))
2501              (hi (numeric-type-high x-type))
2502              (lo-res (if lo (isqrt lo) '*))
2503              (hi-res (if hi (isqrt hi) '*)))
2504         (specifier-type `(integer ,lo-res ,hi-res))))))
2505
2506 (defoptimizer (char-code derive-type) ((char))
2507   (let ((type (type-intersection (lvar-type char) (specifier-type 'character))))
2508     (cond ((member-type-p type)
2509            (specifier-type
2510             `(member
2511               ,@(loop for member in (member-type-members type)
2512                       when (characterp member)
2513                       collect (char-code member)))))
2514           ((sb!kernel::character-set-type-p type)
2515            (specifier-type
2516             `(or
2517               ,@(loop for (low . high)
2518                       in (character-set-type-pairs type)
2519                       collect `(integer ,low ,high)))))
2520           ((csubtypep type (specifier-type 'base-char))
2521            (specifier-type
2522             `(mod ,base-char-code-limit)))
2523           (t
2524            (specifier-type
2525             `(mod ,sb!xc:char-code-limit))))))
2526
2527 (defoptimizer (code-char derive-type) ((code))
2528   (let ((type (lvar-type code)))
2529     ;; FIXME: unions of integral ranges?  It ought to be easier to do
2530     ;; this, given that CHARACTER-SET is basically an integral range
2531     ;; type.  -- CSR, 2004-10-04
2532     (when (numeric-type-p type)
2533       (let* ((lo (numeric-type-low type))
2534              (hi (numeric-type-high type))
2535              (type (specifier-type `(character-set ((,lo . ,hi))))))
2536         (cond
2537           ;; KLUDGE: when running on the host, we lose a slight amount
2538           ;; of precision so that we don't have to "unparse" types
2539           ;; that formally we can't, such as (CHARACTER-SET ((0
2540           ;; . 0))).  -- CSR, 2004-10-06
2541           #+sb-xc-host
2542           ((csubtypep type (specifier-type 'standard-char)) type)
2543           #+sb-xc-host
2544           ((csubtypep type (specifier-type 'base-char))
2545            (specifier-type 'base-char))
2546           #+sb-xc-host
2547           ((csubtypep type (specifier-type 'extended-char))
2548            (specifier-type 'extended-char))
2549           (t #+sb-xc-host (specifier-type 'character)
2550              #-sb-xc-host type))))))
2551
2552 (defoptimizer (values derive-type) ((&rest values))
2553   (make-values-type :required (mapcar #'lvar-type values)))
2554
2555 (defun signum-derive-type-aux (type)
2556   (if (eq (numeric-type-complexp type) :complex)
2557       (let* ((format (case (numeric-type-class type)
2558                           ((integer rational) 'single-float)
2559                           (t (numeric-type-format type))))
2560                 (bound-format (or format 'float)))
2561            (make-numeric-type :class 'float
2562                               :format format
2563                               :complexp :complex
2564                               :low (coerce -1 bound-format)
2565                               :high (coerce 1 bound-format)))
2566       (let* ((interval (numeric-type->interval type))
2567              (range-info (interval-range-info interval))
2568              (contains-0-p (interval-contains-p 0 interval))
2569              (class (numeric-type-class type))
2570              (format (numeric-type-format type))
2571              (one (coerce 1 (or format class 'real)))
2572              (zero (coerce 0 (or format class 'real)))
2573              (minus-one (coerce -1 (or format class 'real)))
2574              (plus (make-numeric-type :class class :format format
2575                                       :low one :high one))
2576              (minus (make-numeric-type :class class :format format
2577                                        :low minus-one :high minus-one))
2578              ;; KLUDGE: here we have a fairly horrible hack to deal
2579              ;; with the schizophrenia in the type derivation engine.
2580              ;; The problem is that the type derivers reinterpret
2581              ;; numeric types as being exact; so (DOUBLE-FLOAT 0d0
2582              ;; 0d0) within the derivation mechanism doesn't include
2583              ;; -0d0.  Ugh.  So force it in here, instead.
2584              (zero (make-numeric-type :class class :format format
2585                                       :low (- zero) :high zero)))
2586         (case range-info
2587           (+ (if contains-0-p (type-union plus zero) plus))
2588           (- (if contains-0-p (type-union minus zero) minus))
2589           (t (type-union minus zero plus))))))
2590
2591 (defoptimizer (signum derive-type) ((num))
2592   (one-arg-derive-type num #'signum-derive-type-aux nil))
2593 \f
2594 ;;;; byte operations
2595 ;;;;
2596 ;;;; We try to turn byte operations into simple logical operations.
2597 ;;;; First, we convert byte specifiers into separate size and position
2598 ;;;; arguments passed to internal %FOO functions. We then attempt to
2599 ;;;; transform the %FOO functions into boolean operations when the
2600 ;;;; size and position are constant and the operands are fixnums.
2601
2602 (macrolet (;; Evaluate body with SIZE-VAR and POS-VAR bound to
2603            ;; expressions that evaluate to the SIZE and POSITION of
2604            ;; the byte-specifier form SPEC. We may wrap a let around
2605            ;; the result of the body to bind some variables.
2606            ;;
2607            ;; If the spec is a BYTE form, then bind the vars to the
2608            ;; subforms. otherwise, evaluate SPEC and use the BYTE-SIZE
2609            ;; and BYTE-POSITION. The goal of this transformation is to
2610            ;; avoid consing up byte specifiers and then immediately
2611            ;; throwing them away.
2612            (with-byte-specifier ((size-var pos-var spec) &body body)
2613              (once-only ((spec `(macroexpand ,spec))
2614                          (temp '(gensym)))
2615                         `(if (and (consp ,spec)
2616                                   (eq (car ,spec) 'byte)
2617                                   (= (length ,spec) 3))
2618                         (let ((,size-var (second ,spec))
2619                               (,pos-var (third ,spec)))
2620                           ,@body)
2621                         (let ((,size-var `(byte-size ,,temp))
2622                               (,pos-var `(byte-position ,,temp)))
2623                           `(let ((,,temp ,,spec))
2624                              ,,@body))))))
2625
2626   (define-source-transform ldb (spec int)
2627     (with-byte-specifier (size pos spec)
2628       `(%ldb ,size ,pos ,int)))
2629
2630   (define-source-transform dpb (newbyte spec int)
2631     (with-byte-specifier (size pos spec)
2632       `(%dpb ,newbyte ,size ,pos ,int)))
2633
2634   (define-source-transform mask-field (spec int)
2635     (with-byte-specifier (size pos spec)
2636       `(%mask-field ,size ,pos ,int)))
2637
2638   (define-source-transform deposit-field (newbyte spec int)
2639     (with-byte-specifier (size pos spec)
2640       `(%deposit-field ,newbyte ,size ,pos ,int))))
2641
2642 (defoptimizer (%ldb derive-type) ((size posn num))
2643   (let ((size (lvar-type size)))
2644     (if (and (numeric-type-p size)
2645              (csubtypep size (specifier-type 'integer)))
2646         (let ((size-high (numeric-type-high size)))
2647           (if (and size-high (<= size-high sb!vm:n-word-bits))
2648               (specifier-type `(unsigned-byte* ,size-high))
2649               (specifier-type 'unsigned-byte)))
2650         *universal-type*)))
2651
2652 (defoptimizer (%mask-field derive-type) ((size posn num))
2653   (let ((size (lvar-type size))
2654         (posn (lvar-type posn)))
2655     (if (and (numeric-type-p size)
2656              (csubtypep size (specifier-type 'integer))
2657              (numeric-type-p posn)
2658              (csubtypep posn (specifier-type 'integer)))
2659         (let ((size-high (numeric-type-high size))
2660               (posn-high (numeric-type-high posn)))
2661           (if (and size-high posn-high
2662                    (<= (+ size-high posn-high) sb!vm:n-word-bits))
2663               (specifier-type `(unsigned-byte* ,(+ size-high posn-high)))
2664               (specifier-type 'unsigned-byte)))
2665         *universal-type*)))
2666
2667 (defun %deposit-field-derive-type-aux (size posn int)
2668   (let ((size (lvar-type size))
2669         (posn (lvar-type posn))
2670         (int (lvar-type int)))
2671     (when (and (numeric-type-p size)
2672                (numeric-type-p posn)
2673                (numeric-type-p int))
2674       (let ((size-high (numeric-type-high size))
2675             (posn-high (numeric-type-high posn))
2676             (high (numeric-type-high int))
2677             (low (numeric-type-low int)))
2678         (when (and size-high posn-high high low
2679                    ;; KLUDGE: we need this cutoff here, otherwise we
2680                    ;; will merrily derive the type of %DPB as
2681                    ;; (UNSIGNED-BYTE 1073741822), and then attempt to
2682                    ;; canonicalize this type to (INTEGER 0 (1- (ASH 1
2683                    ;; 1073741822))), with hilarious consequences.  We
2684                    ;; cutoff at 4*SB!VM:N-WORD-BITS to allow inference
2685                    ;; over a reasonable amount of shifting, even on
2686                    ;; the alpha/32 port, where N-WORD-BITS is 32 but
2687                    ;; machine integers are 64-bits.  -- CSR,
2688                    ;; 2003-09-12
2689                    (<= (+ size-high posn-high) (* 4 sb!vm:n-word-bits)))
2690           (let ((raw-bit-count (max (integer-length high)
2691                                     (integer-length low)
2692                                     (+ size-high posn-high))))
2693             (specifier-type
2694              (if (minusp low)
2695                  `(signed-byte ,(1+ raw-bit-count))
2696                  `(unsigned-byte* ,raw-bit-count)))))))))
2697
2698 (defoptimizer (%dpb derive-type) ((newbyte size posn int))
2699   (%deposit-field-derive-type-aux size posn int))
2700
2701 (defoptimizer (%deposit-field derive-type) ((newbyte size posn int))
2702   (%deposit-field-derive-type-aux size posn int))
2703
2704 (deftransform %ldb ((size posn int)
2705                     (fixnum fixnum integer)
2706                     (unsigned-byte #.sb!vm:n-word-bits))
2707   "convert to inline logical operations"
2708   `(logand (ash int (- posn))
2709            (ash ,(1- (ash 1 sb!vm:n-word-bits))
2710                 (- size ,sb!vm:n-word-bits))))
2711
2712 (deftransform %mask-field ((size posn int)
2713                            (fixnum fixnum integer)
2714                            (unsigned-byte #.sb!vm:n-word-bits))
2715   "convert to inline logical operations"
2716   `(logand int
2717            (ash (ash ,(1- (ash 1 sb!vm:n-word-bits))
2718                      (- size ,sb!vm:n-word-bits))
2719                 posn)))
2720
2721 ;;; Note: for %DPB and %DEPOSIT-FIELD, we can't use
2722 ;;;   (OR (SIGNED-BYTE N) (UNSIGNED-BYTE N))
2723 ;;; as the result type, as that would allow result types that cover
2724 ;;; the range -2^(n-1) .. 1-2^n, instead of allowing result types of
2725 ;;; (UNSIGNED-BYTE N) and result types of (SIGNED-BYTE N).
2726
2727 (deftransform %dpb ((new size posn int)
2728                     *
2729                     (unsigned-byte #.sb!vm:n-word-bits))
2730   "convert to inline logical operations"
2731   `(let ((mask (ldb (byte size 0) -1)))
2732      (logior (ash (logand new mask) posn)
2733              (logand int (lognot (ash mask posn))))))
2734
2735 (deftransform %dpb ((new size posn int)
2736                     *
2737                     (signed-byte #.sb!vm:n-word-bits))
2738   "convert to inline logical operations"
2739   `(let ((mask (ldb (byte size 0) -1)))
2740      (logior (ash (logand new mask) posn)
2741              (logand int (lognot (ash mask posn))))))
2742
2743 (deftransform %deposit-field ((new size posn int)
2744                               *
2745                               (unsigned-byte #.sb!vm:n-word-bits))
2746   "convert to inline logical operations"
2747   `(let ((mask (ash (ldb (byte size 0) -1) posn)))
2748      (logior (logand new mask)
2749              (logand int (lognot mask)))))
2750
2751 (deftransform %deposit-field ((new size posn int)
2752                               *
2753                               (signed-byte #.sb!vm:n-word-bits))
2754   "convert to inline logical operations"
2755   `(let ((mask (ash (ldb (byte size 0) -1) posn)))
2756      (logior (logand new mask)
2757              (logand int (lognot mask)))))
2758
2759 (defoptimizer (mask-signed-field derive-type) ((size x))
2760   (let ((size (lvar-type size)))
2761     (if (numeric-type-p size)
2762         (let ((size-high (numeric-type-high size)))
2763           (if (and size-high (<= 1 size-high sb!vm:n-word-bits))
2764               (specifier-type `(signed-byte ,size-high))
2765               *universal-type*))
2766         *universal-type*)))
2767 \f
2768 ;;; Rightward ASH
2769 #!+ash-right-vops
2770 (progn
2771   (defun %ash/right (integer amount)
2772     (ash integer (- amount)))
2773
2774   (deftransform ash ((integer amount))
2775     "Convert ASH of signed word to %ASH/RIGHT"
2776     (unless (and (csubtypep (lvar-type integer) ; do that ourselves to avoid
2777                             (specifier-type 'sb!vm:signed-word)) ; optimization
2778                  (csubtypep (lvar-type amount)  ; notes.
2779                             (specifier-type '(integer * 0))))
2780       (give-up-ir1-transform))
2781     (when (constant-lvar-p amount)
2782       (give-up-ir1-transform))
2783     (let ((use (lvar-uses amount)))
2784       (cond ((and (combination-p use)
2785                   (eql '%negate (lvar-fun-name (combination-fun use))))
2786              (splice-fun-args amount '%negate 1)
2787              `(lambda (integer amount)
2788                 (declare (type unsigned-byte amount))
2789                 (%ash/right integer (if (>= amount ,sb!vm:n-word-bits)
2790                                         ,(1- sb!vm:n-word-bits)
2791                                         amount))))
2792             (t
2793              `(%ash/right integer (if (<= amount ,(- sb!vm:n-word-bits))
2794                                       ,(1- sb!vm:n-word-bits)
2795                                       (- amount)))))))
2796
2797   (deftransform ash ((integer amount))
2798     "Convert ASH of word to %ASH/RIGHT"
2799     (unless (and (csubtypep (lvar-type integer)
2800                             (specifier-type 'sb!vm:word))
2801                  (csubtypep (lvar-type amount)
2802                             (specifier-type '(integer * 0))))
2803       (give-up-ir1-transform))
2804     (when (constant-lvar-p amount)
2805       (give-up-ir1-transform))
2806     (let ((use (lvar-uses amount)))
2807       (cond ((and (combination-p use)
2808                   (eql '%negate (lvar-fun-name (combination-fun use))))
2809              (splice-fun-args amount '%negate 1)
2810              `(lambda (integer amount)
2811                 (declare (type unsigned-byte amount))
2812                 (if (>= amount ,sb!vm:n-word-bits)
2813                     0
2814                     (%ash/right integer amount))))
2815             (t
2816              `(if (<= amount ,(- sb!vm:n-word-bits))
2817                   0
2818                   (%ash/right integer (- amount)))))))
2819
2820   (deftransform %ash/right ((integer amount) (integer (constant-arg unsigned-byte)))
2821     "Convert %ASH/RIGHT by constant back to ASH"
2822     `(ash integer ,(- (lvar-value amount))))
2823
2824   (deftransform %ash/right ((integer amount) * * :node node)
2825     "strength reduce large variable right shift"
2826     (let ((return-type (single-value-type (node-derived-type node))))
2827       (cond ((type= return-type (specifier-type '(eql 0)))
2828              0)
2829             ((type= return-type (specifier-type '(eql -1)))
2830              -1)
2831             ((csubtypep return-type (specifier-type '(member -1 0)))
2832              `(ash integer ,(- sb!vm:n-word-bits)))
2833             (t
2834              (give-up-ir1-transform)))))
2835
2836   (defun %ash/right-derive-type-aux (n-type shift same-arg)
2837     (declare (ignore same-arg))
2838     (or (and (or (csubtypep n-type (specifier-type 'sb!vm:signed-word))
2839                  (csubtypep n-type (specifier-type 'word)))
2840              (csubtypep shift (specifier-type `(mod ,sb!vm:n-word-bits)))
2841              (let ((n-low (numeric-type-low n-type))
2842                    (n-high (numeric-type-high n-type))
2843                    (s-low (numeric-type-low shift))
2844                    (s-high (numeric-type-high shift)))
2845                (make-numeric-type :class 'integer :complexp :real
2846                                   :low (when n-low
2847                                          (if (minusp n-low)
2848                                              (ash n-low (- s-low))
2849                                              (ash n-low (- s-high))))
2850                                   :high (when n-high
2851                                           (if (minusp n-high)
2852                                               (ash n-high (- s-high))
2853                                               (ash n-high (- s-low)))))))
2854         *universal-type*))
2855
2856   (defoptimizer (%ash/right derive-type) ((n shift))
2857     (two-arg-derive-type n shift #'%ash/right-derive-type-aux #'%ash/right))
2858   )
2859 \f
2860 ;;; Modular functions
2861
2862 ;;; (ldb (byte s 0) (foo                 x  y ...)) =
2863 ;;; (ldb (byte s 0) (foo (ldb (byte s 0) x) y ...))
2864 ;;;
2865 ;;; and similar for other arguments.
2866
2867 (defun make-modular-fun-type-deriver (prototype kind width signedp)
2868   (declare (ignore kind))
2869   #!-sb-fluid
2870   (binding* ((info (info :function :info prototype) :exit-if-null)
2871              (fun (fun-info-derive-type info) :exit-if-null)
2872              (mask-type (specifier-type
2873                          (ecase signedp
2874                              ((nil) (let ((mask (1- (ash 1 width))))
2875                                       `(integer ,mask ,mask)))
2876                              ((t) `(signed-byte ,width))))))
2877     (lambda (call)
2878       (let ((res (funcall fun call)))
2879         (when res
2880           (if (eq signedp nil)
2881               (logand-derive-type-aux res mask-type))))))
2882   #!+sb-fluid
2883   (lambda (call)
2884     (binding* ((info (info :function :info prototype) :exit-if-null)
2885                (fun (fun-info-derive-type info) :exit-if-null)
2886                (res (funcall fun call) :exit-if-null)
2887                (mask-type (specifier-type
2888                            (ecase signedp
2889                              ((nil) (let ((mask (1- (ash 1 width))))
2890                                       `(integer ,mask ,mask)))
2891                              ((t) `(signed-byte ,width))))))
2892       (if (eq signedp nil)
2893           (logand-derive-type-aux res mask-type)))))
2894
2895 ;;; Try to recursively cut all uses of LVAR to WIDTH bits.
2896 ;;;
2897 ;;; For good functions, we just recursively cut arguments; their
2898 ;;; "goodness" means that the result will not increase (in the
2899 ;;; (unsigned-byte +infinity) sense). An ordinary modular function is
2900 ;;; replaced with the version, cutting its result to WIDTH or more
2901 ;;; bits. For most functions (e.g. for +) we cut all arguments; for
2902 ;;; others (e.g. for ASH) we have "optimizers", cutting only necessary
2903 ;;; arguments (maybe to a different width) and returning the name of a
2904 ;;; modular version, if it exists, or NIL. If we have changed
2905 ;;; anything, we need to flush old derived types, because they have
2906 ;;; nothing in common with the new code.
2907 (defun cut-to-width (lvar kind width signedp)
2908   (declare (type lvar lvar) (type (integer 0) width))
2909   (let ((type (specifier-type (if (zerop width)
2910                                   '(eql 0)
2911                                   `(,(ecase signedp
2912                                        ((nil) 'unsigned-byte)
2913                                        ((t) 'signed-byte))
2914                                      ,width)))))
2915     (labels ((reoptimize-node (node name)
2916                (setf (node-derived-type node)
2917                      (fun-type-returns
2918                       (info :function :type name)))
2919                (setf (lvar-%derived-type (node-lvar node)) nil)
2920                (setf (node-reoptimize node) t)
2921                (setf (block-reoptimize (node-block node)) t)
2922                (reoptimize-component (node-component node) :maybe))
2923              (insert-lvar-cut (lvar)
2924                "Insert a LOGAND/MASK-SIGNED-FIELD to cut the value of LVAR
2925                 to the required bit width. Returns T if any change was made.
2926
2927                 When the destination of LVAR will definitely cut LVAR's value
2928                 to width (i.e. it's a logand or mask-signed-field with constant
2929                 other argument), do nothing. Otherwise, splice LOGAND/M-S-F in."
2930                (binding* ((dest (lvar-dest lvar) :exit-if-null)
2931                           (nil  (combination-p dest) :exit-if-null)
2932                           (name (lvar-fun-name (combination-fun dest) t))
2933                           (args (combination-args dest)))
2934                  (case name
2935                    (logand
2936                     (when (= 2 (length args))
2937                       (let ((other (if (eql (first args) lvar)
2938                                        (second args)
2939                                        (first args))))
2940                         (when (and (constant-lvar-p other)
2941                                    (ctypep (lvar-value other) type)
2942                                    (not signedp))
2943                           (return-from insert-lvar-cut)))))
2944                    (mask-signed-field
2945                     (when (and signedp
2946                                (eql lvar (second args))
2947                                (constant-lvar-p (first args))
2948                                (<= (lvar-value (first args)) width))
2949                       (return-from insert-lvar-cut)))))
2950                (filter-lvar lvar
2951                             (if signedp
2952                                 `(mask-signed-field ,width 'dummy)
2953                                 `(logand 'dummy ,(ldb (byte width 0) -1))))
2954                (do-uses (node lvar)
2955                  (setf (block-reoptimize (node-block node)) t)
2956                  (reoptimize-component (node-component node) :maybe))
2957                t)
2958              (cut-node (node &aux did-something over-wide)
2959                "Try to cut a node to width. The primary return value is
2960                 whether we managed to cut (cleverly), and the second whether
2961                 anything was changed.  The third return value tells whether
2962                 the cut value might be wider than expected."
2963                (when (block-delete-p (node-block node))
2964                  (return-from cut-node (values t nil)))
2965                (typecase node
2966                  (ref
2967                   (typecase (ref-leaf node)
2968                     (constant
2969                      (let* ((constant-value (constant-value (ref-leaf node)))
2970                             (new-value (if signedp
2971                                            (mask-signed-field width constant-value)
2972                                            (ldb (byte width 0) constant-value))))
2973                        (cond ((= constant-value new-value)
2974                               (values t nil)) ; we knew what to do and did nothing
2975                              (t
2976                               (change-ref-leaf node (make-constant new-value)
2977                                                :recklessly t)
2978                               (let ((lvar (node-lvar node)))
2979                                 (setf (lvar-%derived-type lvar)
2980                                       (and (lvar-has-single-use-p lvar)
2981                                            (make-values-type :required (list (ctype-of new-value))))))
2982                               (setf (block-reoptimize (node-block node)) t)
2983                               (reoptimize-component (node-component node) :maybe)
2984                               (values t t)))))))
2985                  (combination
2986                   (when (eq (basic-combination-kind node) :known)
2987                     (let* ((fun-ref (lvar-use (combination-fun node)))
2988                            (fun-name (lvar-fun-name (combination-fun node)))
2989                            (modular-fun (find-modular-version fun-name kind
2990                                                               signedp width)))
2991                       (cond ((not modular-fun)
2992                              ;; don't know what to do here
2993                              (values nil nil))
2994                             ((let ((dtype (single-value-type
2995                                            (node-derived-type node))))
2996                                (and
2997                                 (case fun-name
2998                                   (logand
2999                                    (csubtypep dtype
3000                                               (specifier-type 'unsigned-byte)))
3001                                   (logior
3002                                    (csubtypep dtype
3003                                               (specifier-type '(integer * 0))))
3004                                   (mask-signed-field
3005                                    t)
3006                                   (t nil))
3007                                 (csubtypep dtype type)))
3008                              ;; nothing to do
3009                              (values t nil))
3010                             (t
3011                              (binding* ((name (etypecase modular-fun
3012                                                 ((eql :good) fun-name)
3013                                                 (modular-fun-info
3014                                                  (modular-fun-info-name modular-fun))
3015                                                 (function
3016                                                  (funcall modular-fun node width)))
3017                                               :exit-if-null))
3018                                (unless (eql modular-fun :good)
3019                                  (setq did-something t
3020                                        over-wide t)
3021                                  (change-ref-leaf
3022                                   fun-ref
3023                                   (find-free-fun name "in a strange place"))
3024                                  (setf (combination-kind node) :full))
3025                                (unless (functionp modular-fun)
3026                                  (dolist (arg (basic-combination-args node))
3027                                    (multiple-value-bind (change wide)
3028                                        (cut-lvar arg)
3029                                      (setf did-something (or did-something change)
3030                                            over-wide (or over-wide wide)))))
3031                                (when did-something
3032                                  (reoptimize-node node name))
3033                                (values t did-something over-wide)))))))))
3034              (cut-lvar (lvar &key head
3035                         &aux did-something must-insert over-wide)
3036                "Cut all the LVAR's use nodes. If any of them wasn't handled
3037                 and its type is too wide for the operation we wish to perform
3038                 insert an explicit bit-width narrowing operation (LOGAND or
3039                 MASK-SIGNED-FIELD) between the LVAR (*) and its destination.
3040                 The narrowing operation might not be inserted if the LVAR's
3041                 destination is already such an operation, to avoid endless
3042                 recursion.
3043
3044                 If we're at the head, forcibly insert a cut operation if the
3045                 result might be too wide.
3046
3047                 (*) We can't easily do that for each node, and doing so might
3048                 result in code bloat, anyway. (I'm also not sure it would be
3049                 correct for complicated C/D FG)"
3050                (do-uses (node lvar)
3051                  (multiple-value-bind (handled any-change wide)
3052                      (cut-node node)
3053                    (setf did-something (or did-something any-change)
3054                          must-insert (or must-insert
3055                                          (not (or handled
3056                                                   (csubtypep (single-value-type
3057                                                               (node-derived-type node))
3058                                                              type))))
3059                          over-wide (or over-wide wide))))
3060                (when (or must-insert
3061                          (and head over-wide))
3062                  (setf did-something (or (insert-lvar-cut lvar) did-something)
3063                        ;; we're just the right width after an explicit cut.
3064                        over-wide nil))
3065                (values did-something over-wide)))
3066       (cut-lvar lvar :head t))))
3067
3068 (defun best-modular-version (width signedp)
3069   ;; 1. exact width-matched :untagged
3070   ;; 2. >/>= width-matched :tagged
3071   ;; 3. >/>= width-matched :untagged
3072   (let* ((uuwidths (modular-class-widths *untagged-unsigned-modular-class*))
3073          (uswidths (modular-class-widths *untagged-signed-modular-class*))
3074          (uwidths (if (and uuwidths uswidths)
3075                       (merge 'list (copy-list uuwidths) (copy-list uswidths)
3076                              #'< :key #'car)
3077                       (or uuwidths uswidths)))
3078          (twidths (modular-class-widths *tagged-modular-class*)))
3079     (let ((exact (find (cons width signedp) uwidths :test #'equal)))
3080       (when exact
3081         (return-from best-modular-version (values width :untagged signedp))))
3082     (flet ((inexact-match (w)
3083              (cond
3084                ((eq signedp (cdr w)) (<= width (car w)))
3085                ((eq signedp nil) (< width (car w))))))
3086       (let ((tgt (find-if #'inexact-match twidths)))
3087         (when tgt
3088           (return-from best-modular-version
3089             (values (car tgt) :tagged (cdr tgt)))))
3090       (let ((ugt (find-if #'inexact-match uwidths)))
3091         (when ugt
3092           (return-from best-modular-version
3093             (values (car ugt) :untagged (cdr ugt))))))))
3094
3095 (defun integer-type-numeric-bounds (type)
3096   (typecase type
3097     (numeric-type (values (numeric-type-low type)
3098                           (numeric-type-high type)))
3099     (union-type
3100      (let ((low  nil)
3101            (high nil))
3102        (dolist (type (union-type-types type) (values low high))
3103          (unless (and (numeric-type-p type)
3104                       (eql (numeric-type-class type) 'integer))
3105            (return (values nil nil)))
3106          (let ((this-low (numeric-type-low type))
3107                (this-high (numeric-type-high type)))
3108            (unless (and this-low this-high)
3109              (return (values nil nil)))
3110            (setf low  (min this-low  (or low  this-low))
3111                  high (max this-high (or high this-high)))))))))
3112
3113 (defoptimizer (logand optimizer) ((x y) node)
3114   (let ((result-type (single-value-type (node-derived-type node))))
3115     (multiple-value-bind (low high)
3116         (integer-type-numeric-bounds result-type)
3117       (when (and (numberp low)
3118                  (numberp high)
3119                  (>= low 0))
3120         (let ((width (integer-length high)))
3121           (multiple-value-bind (w kind signedp)
3122               (best-modular-version width nil)
3123             (when w
3124               ;; FIXME: This should be (CUT-TO-WIDTH NODE KIND WIDTH SIGNEDP).
3125               ;;
3126               ;; FIXME: I think the FIXME (which is from APD) above
3127               ;; implies that CUT-TO-WIDTH should do /everything/
3128               ;; that's required, including reoptimizing things
3129               ;; itself that it knows are necessary.  At the moment,
3130               ;; CUT-TO-WIDTH sets up some new calls with
3131               ;; combination-type :FULL, which later get noticed as
3132               ;; known functions and properly converted.
3133               ;;
3134               ;; We cut to W not WIDTH if SIGNEDP is true, because
3135               ;; signed constant replacement needs to know which bit
3136               ;; in the field is the signed bit.
3137               (let ((xact (cut-to-width x kind (if signedp w width) signedp))
3138                     (yact (cut-to-width y kind (if signedp w width) signedp)))
3139                 (declare (ignore xact yact))
3140                 nil) ; After fixing above, replace with T, meaning
3141                                         ; "don't reoptimize this (LOGAND) node any more".
3142               )))))))
3143
3144 (defoptimizer (mask-signed-field optimizer) ((width x) node)
3145   (let ((result-type (single-value-type (node-derived-type node))))
3146     (multiple-value-bind (low high)
3147         (integer-type-numeric-bounds result-type)
3148       (when (and (numberp low) (numberp high))
3149         (let ((width (max (integer-length high) (integer-length low))))
3150           (multiple-value-bind (w kind)
3151               (best-modular-version (1+ width) t)
3152             (when w
3153               ;; FIXME: This should be (CUT-TO-WIDTH NODE KIND W T).
3154               ;; [ see comment above in LOGAND optimizer ]
3155               (cut-to-width x kind w t)
3156               nil                ; After fixing above, replace with T.
3157               )))))))
3158
3159 (defoptimizer (logior optimizer) ((x y) node)
3160   (let ((result-type (single-value-type (node-derived-type node))))
3161     (multiple-value-bind (low high)
3162         (integer-type-numeric-bounds result-type)
3163       (when (and (numberp low)
3164                  (numberp high)
3165                  (<= high 0))
3166         (let ((width (integer-length low)))
3167           (multiple-value-bind (w kind)
3168               (best-modular-version (1+ width) t)
3169             (when w
3170               ;; FIXME: see comment in LOGAND optimizer
3171               (let ((xact (cut-to-width x kind w t))
3172                     (yact (cut-to-width y kind w t)))
3173                 (declare (ignore xact yact))
3174                 nil) ; After fixing above, replace with T
3175               )))))))
3176 \f
3177 ;;; miscellanous numeric transforms
3178
3179 ;;; If a constant appears as the first arg, swap the args.
3180 (deftransform commutative-arg-swap ((x y) * * :defun-only t :node node)
3181   (if (and (constant-lvar-p x)
3182            (not (constant-lvar-p y)))
3183       `(,(lvar-fun-name (basic-combination-fun node))
3184         (truly-the ,(lvar-type y) y)
3185         ,(lvar-value x))
3186       (give-up-ir1-transform)))
3187
3188 (dolist (x '(= char= two-arg-char-equal + * logior logand logxor logtest))
3189   (%deftransform x '(function * *) #'commutative-arg-swap
3190                  "place constant arg last"))
3191
3192 ;;; Handle the case of a constant BOOLE-CODE.
3193 (deftransform boole ((op x y) * *)
3194   "convert to inline logical operations"
3195   (unless (constant-lvar-p op)
3196     (give-up-ir1-transform "BOOLE code is not a constant."))
3197   (let ((control (lvar-value op)))
3198     (case control
3199       (#.sb!xc:boole-clr 0)
3200       (#.sb!xc:boole-set -1)
3201       (#.sb!xc:boole-1 'x)
3202       (#.sb!xc:boole-2 'y)
3203       (#.sb!xc:boole-c1 '(lognot x))
3204       (#.sb!xc:boole-c2 '(lognot y))
3205       (#.sb!xc:boole-and '(logand x y))
3206       (#.sb!xc:boole-ior '(logior x y))
3207       (#.sb!xc:boole-xor '(logxor x y))
3208       (#.sb!xc:boole-eqv '(logeqv x y))
3209       (#.sb!xc:boole-nand '(lognand x y))
3210       (#.sb!xc:boole-nor '(lognor x y))
3211       (#.sb!xc:boole-andc1 '(logandc1 x y))
3212       (#.sb!xc:boole-andc2 '(logandc2 x y))
3213       (#.sb!xc:boole-orc1 '(logorc1 x y))
3214       (#.sb!xc:boole-orc2 '(logorc2 x y))
3215       (t
3216        (abort-ir1-transform "~S is an illegal control arg to BOOLE."
3217                             control)))))
3218 \f
3219 ;;;; converting special case multiply/divide to shifts
3220
3221 ;;; If arg is a constant power of two, turn * into a shift.
3222 (deftransform * ((x y) (integer integer) *)
3223   "convert x*2^k to shift"
3224   (unless (constant-lvar-p y)
3225     (give-up-ir1-transform))
3226   (let* ((y (lvar-value y))
3227          (y-abs (abs y))
3228          (len (1- (integer-length y-abs))))
3229     (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
3230       (give-up-ir1-transform))
3231     (if (minusp y)
3232         `(- (ash x ,len))
3233         `(ash x ,len))))
3234
3235 ;;; These must come before the ones below, so that they are tried
3236 ;;; first. Since %FLOOR and %CEILING are inlined, this allows
3237 ;;; the general case to be handled by TRUNCATE transforms.
3238 (deftransform floor ((x y))
3239   `(%floor x y))
3240
3241 (deftransform ceiling ((x y))
3242   `(%ceiling x y))
3243
3244 ;;; If arg is a constant power of two, turn FLOOR into a shift and
3245 ;;; mask. If CEILING, add in (1- (ABS Y)), do FLOOR and correct a
3246 ;;; remainder.
3247 (flet ((frob (y ceil-p)
3248          (unless (constant-lvar-p y)
3249            (give-up-ir1-transform))
3250          (let* ((y (lvar-value y))
3251                 (y-abs (abs y))
3252                 (len (1- (integer-length y-abs))))
3253            (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
3254              (give-up-ir1-transform))
3255            (let ((shift (- len))
3256                  (mask (1- y-abs))
3257                  (delta (if ceil-p (* (signum y) (1- y-abs)) 0)))
3258              `(let ((x (+ x ,delta)))
3259                 ,(if (minusp y)
3260                      `(values (ash (- x) ,shift)
3261                               (- (- (logand (- x) ,mask)) ,delta))
3262                      `(values (ash x ,shift)
3263                               (- (logand x ,mask) ,delta))))))))
3264   (deftransform floor ((x y) (integer integer) *)
3265     "convert division by 2^k to shift"
3266     (frob y nil))
3267   (deftransform ceiling ((x y) (integer integer) *)
3268     "convert division by 2^k to shift"
3269     (frob y t)))
3270
3271 ;;; Do the same for MOD.
3272 (deftransform mod ((x y) (integer integer) *)
3273   "convert remainder mod 2^k to LOGAND"
3274   (unless (constant-lvar-p y)
3275     (give-up-ir1-transform))
3276   (let* ((y (lvar-value y))
3277          (y-abs (abs y))
3278          (len (1- (integer-length y-abs))))
3279     (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
3280       (give-up-ir1-transform))
3281     (let ((mask (1- y-abs)))
3282       (if (minusp y)
3283           `(- (logand (- x) ,mask))
3284           `(logand x ,mask)))))
3285
3286 ;;; If arg is a constant power of two, turn TRUNCATE into a shift and mask.
3287 (deftransform truncate ((x y) (integer integer))
3288   "convert division by 2^k to shift"
3289   (unless (constant-lvar-p y)
3290     (give-up-ir1-transform))
3291   (let* ((y (lvar-value y))
3292          (y-abs (abs y))
3293          (len (1- (integer-length y-abs))))
3294     (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
3295       (give-up-ir1-transform))
3296     (let* ((shift (- len))
3297            (mask (1- y-abs)))
3298       `(if (minusp x)
3299            (values ,(if (minusp y)
3300                         `(ash (- x) ,shift)
3301                         `(- (ash (- x) ,shift)))
3302                    (- (logand (- x) ,mask)))
3303            (values ,(if (minusp y)
3304                         `(ash (- ,mask x) ,shift)
3305                         `(ash x ,shift))
3306                    (logand x ,mask))))))
3307
3308 ;;; And the same for REM.
3309 (deftransform rem ((x y) (integer integer) *)
3310   "convert remainder mod 2^k to LOGAND"
3311   (unless (constant-lvar-p y)
3312     (give-up-ir1-transform))
3313   (let* ((y (lvar-value y))
3314          (y-abs (abs y))
3315          (len (1- (integer-length y-abs))))
3316     (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
3317       (give-up-ir1-transform))
3318     (let ((mask (1- y-abs)))
3319       `(if (minusp x)
3320            (- (logand (- x) ,mask))
3321            (logand x ,mask)))))
3322
3323 ;;; Return an expression to calculate the integer quotient of X and
3324 ;;; constant Y, using multiplication, shift and add/sub instead of
3325 ;;; division. Both arguments must be unsigned, fit in a machine word and
3326 ;;; Y must neither be zero nor a power of two. The quotient is rounded
3327 ;;; towards zero.
3328 ;;; The algorithm is taken from the paper "Division by Invariant
3329 ;;; Integers using Multiplication", 1994 by Torbj\"{o}rn Granlund and
3330 ;;; Peter L. Montgomery, Figures 4.2 and 6.2, modified to exclude the
3331 ;;; case of division by powers of two.
3332 ;;; The algorithm includes an adaptive precision argument.  Use it, since
3333 ;;; we often have sub-word value ranges.  Careful, in this case, we need
3334 ;;; p s.t 2^p > n, not the ceiling of the binary log.
3335 ;;; Also, for some reason, the paper prefers shifting to masking.  Mask
3336 ;;; instead.  Masking is equivalent to shifting right, then left again;
3337 ;;; all the intermediate values are still words, so we just have to shift
3338 ;;; right a bit more to compensate, at the end.
3339 ;;;
3340 ;;; The following two examples show an average case and the worst case
3341 ;;; with respect to the complexity of the generated expression, under
3342 ;;; a word size of 64 bits:
3343 ;;;
3344 ;;; (UNSIGNED-DIV-TRANSFORMER 10 MOST-POSITIVE-WORD) ->
3345 ;;; (ASH (%MULTIPLY (LOGANDC2 X 0) 14757395258967641293) -3)
3346 ;;;
3347 ;;; (UNSIGNED-DIV-TRANSFORMER 7 MOST-POSITIVE-WORD) ->
3348 ;;; (LET* ((NUM X)
3349 ;;;        (T1 (%MULTIPLY NUM 2635249153387078803)))
3350 ;;;   (ASH (LDB (BYTE 64 0)
3351 ;;;             (+ T1 (ASH (LDB (BYTE 64 0)
3352 ;;;                             (- NUM T1))
3353 ;;;                        -1)))
3354 ;;;        -2))
3355 ;;;
3356 (defun gen-unsigned-div-by-constant-expr (y max-x)
3357   (declare (type (integer 3 #.most-positive-word) y)
3358            (type word max-x))
3359   (aver (not (zerop (logand y (1- y)))))
3360   (labels ((ld (x)
3361              ;; the floor of the binary logarithm of (positive) X
3362              (integer-length (1- x)))
3363            (choose-multiplier (y precision)
3364              (do* ((l (ld y))
3365                    (shift l (1- shift))
3366                    (expt-2-n+l (expt 2 (+ sb!vm:n-word-bits l)))
3367                    (m-low (truncate expt-2-n+l y) (ash m-low -1))
3368                    (m-high (truncate (+ expt-2-n+l
3369                                         (ash expt-2-n+l (- precision)))
3370                                      y)
3371                            (ash m-high -1)))
3372                   ((not (and (< (ash m-low -1) (ash m-high -1))
3373                              (> shift 0)))
3374                    (values m-high shift)))))
3375     (let ((n (expt 2 sb!vm:n-word-bits))
3376           (precision (integer-length max-x))
3377           (shift1 0))
3378       (multiple-value-bind (m shift2)
3379           (choose-multiplier y precision)
3380         (when (and (>= m n) (evenp y))
3381           (setq shift1 (ld (logand y (- y))))
3382           (multiple-value-setq (m shift2)
3383             (choose-multiplier (/ y (ash 1 shift1))
3384                                (- precision shift1))))
3385         (cond ((>= m n)
3386                (flet ((word (x)
3387                         `(truly-the word ,x)))
3388                  `(let* ((num x)
3389                          (t1 (%multiply-high num ,(- m n))))
3390                     (ash ,(word `(+ t1 (ash ,(word `(- num t1))
3391                                             -1)))
3392                          ,(- 1 shift2)))))
3393               ((and (zerop shift1) (zerop shift2))
3394                (let ((max (truncate max-x y)))
3395                  ;; Explicit TRULY-THE needed to get the FIXNUM=>FIXNUM
3396                  ;; VOP.
3397                  `(truly-the (integer 0 ,max)
3398                              (%multiply-high x ,m))))
3399               (t
3400                `(ash (%multiply-high (logandc2 x ,(1- (ash 1 shift1))) ,m)
3401                      ,(- (+ shift1 shift2)))))))))
3402
3403 ;;; If the divisor is constant and both args are positive and fit in a
3404 ;;; machine word, replace the division by a multiplication and possibly
3405 ;;; some shifts and an addition. Calculate the remainder by a second
3406 ;;; multiplication and a subtraction. Dead code elimination will
3407 ;;; suppress the latter part if only the quotient is needed. If the type
3408 ;;; of the dividend allows to derive that the quotient will always have
3409 ;;; the same value, emit much simpler code to handle that. (This case
3410 ;;; may be rare but it's easy to detect and the compiler doesn't find
3411 ;;; this optimization on its own.)
3412 (deftransform truncate ((x y) (word (constant-arg word))
3413                         *
3414                         :policy (and (> speed compilation-speed)
3415                                      (> speed space)))
3416   "convert integer division to multiplication"
3417   (let* ((y      (lvar-value y))
3418          (x-type (lvar-type x))
3419          (max-x  (or (and (numeric-type-p x-type)
3420                           (numeric-type-high x-type))
3421                      most-positive-word)))
3422     ;; Division by zero, one or powers of two is handled elsewhere.
3423     (when (zerop (logand y (1- y)))
3424       (give-up-ir1-transform))
3425     `(let* ((quot ,(gen-unsigned-div-by-constant-expr y max-x))
3426             (rem (ldb (byte #.sb!vm:n-word-bits 0)
3427                       (- x (* quot ,y)))))
3428        (values quot rem))))
3429 \f
3430 ;;;; arithmetic and logical identity operation elimination
3431
3432 ;;; Flush calls to various arith functions that convert to the
3433 ;;; identity function or a constant.
3434 (macrolet ((def (name identity result)
3435              `(deftransform ,name ((x y) (* (constant-arg (member ,identity))) *)
3436                 "fold identity operations"
3437                 ',result)))
3438   (def ash 0 x)
3439   (def logand -1 x)
3440   (def logand 0 0)
3441   (def logior 0 x)
3442   (def logior -1 -1)
3443   (def logxor -1 (lognot x))
3444   (def logxor 0 x))
3445
3446 (defun least-zero-bit (x)
3447   (and (/= x -1)
3448        (1- (integer-length (logxor x (1+ x))))))
3449
3450 (deftransform logand ((x y) (* (constant-arg t)) *)
3451   "fold identity operation"
3452   (let* ((y (lvar-value y))
3453          (width (or (least-zero-bit y) '*)))
3454     (unless (and (neq width 0) ; (logand x 0) handled elsewhere
3455                  (csubtypep (lvar-type x)
3456                             (specifier-type `(unsigned-byte ,width))))
3457       (give-up-ir1-transform))
3458     'x))
3459
3460 (deftransform mask-signed-field ((size x) ((constant-arg t) *) *)
3461   "fold identity operation"
3462   (let ((size (lvar-value size)))
3463     (unless (csubtypep (lvar-type x) (specifier-type `(signed-byte ,size)))
3464       (give-up-ir1-transform))
3465     'x))
3466
3467 (deftransform logior ((x y) (* (constant-arg t)) *)
3468   "fold identity operation"
3469   (let* ((y (lvar-value y))
3470          (width (or (least-zero-bit (lognot y))
3471                     (give-up-ir1-transform)))) ; (logior x 0) handled elsewhere
3472     (unless (csubtypep (lvar-type x)
3473                        (specifier-type `(integer ,(- (ash 1 width)) -1)))
3474       (give-up-ir1-transform))
3475     'x))
3476
3477 ;;; Pick off easy association opportunities for constant folding.
3478 ;;; More complicated stuff that also depends on commutativity
3479 ;;; (e.g. (f (f x k1) (f y k2)) => (f (f x y) (f k1 k2))) should
3480 ;;; probably be handled with a more general tree-rewriting pass.
3481 (macrolet ((def (operator &key (type 'integer) (folded operator))
3482              `(deftransform ,operator ((x z) (,type (constant-arg ,type)))
3483                 ,(format nil "associate ~A/~A of constants"
3484                          operator folded)
3485                 (binding* ((node  (if (lvar-has-single-use-p x)
3486                                       (lvar-use x)
3487                                       (give-up-ir1-transform)))
3488                            (nil (or (and (combination-p node)
3489                                          (eq (lvar-fun-name
3490                                               (combination-fun node))
3491                                              ',folded))
3492                                     (give-up-ir1-transform)))
3493                            (y   (second (combination-args node)))
3494                            (nil (or (constant-lvar-p y)
3495                                     (give-up-ir1-transform)))
3496                            (y   (lvar-value y)))
3497                   (unless (typep y ',type)
3498                     (give-up-ir1-transform))
3499                   (splice-fun-args x ',folded 2)
3500                   `(lambda (x y z)
3501                      (declare (ignore y z))
3502                      ;; (operator (folded x y) z)
3503                      ;; == (operator x (folded z y))
3504                      (,',operator x ',(,folded (lvar-value z) y)))))))
3505   (def logand)
3506   (def logior)
3507   (def logxor)
3508   (def logtest :folded logand)
3509   (def + :type rational)
3510   (def + :type rational :folded -)
3511   (def * :type rational)
3512   (def * :type rational :folded /))
3513
3514 (deftransform mask-signed-field ((width x) ((constant-arg unsigned-byte) *))
3515   "Fold mask-signed-field/mask-signed-field of constant width"
3516   (binding* ((node  (if (lvar-has-single-use-p x)
3517                         (lvar-use x)
3518                         (give-up-ir1-transform)))
3519              (nil (or (combination-p node)
3520                       (give-up-ir1-transform)))
3521              (nil (or (eq (lvar-fun-name (combination-fun node))
3522                           'mask-signed-field)
3523                       (give-up-ir1-transform)))
3524              (x-width (first (combination-args node)))
3525              (nil (or (constant-lvar-p x-width)
3526                       (give-up-ir1-transform)))
3527              (x-width (lvar-value x-width)))
3528     (unless (typep x-width 'unsigned-byte)
3529       (give-up-ir1-transform))
3530     (splice-fun-args x 'mask-signed-field 2)
3531     `(lambda (width x-width x)
3532        (declare (ignore width x-width))
3533        (mask-signed-field ,(min (lvar-value width) x-width) x))))
3534
3535 ;;; These are restricted to rationals, because (- 0 0.0) is 0.0, not -0.0, and
3536 ;;; (* 0 -4.0) is -0.0.
3537 (deftransform - ((x y) ((constant-arg (member 0)) rational) *)
3538   "convert (- 0 x) to negate"
3539   '(%negate y))
3540 (deftransform * ((x y) (rational (constant-arg (member 0))) *)
3541   "convert (* x 0) to 0"
3542   0)
3543
3544 (deftransform %negate ((x) (rational))
3545   "Eliminate %negate/%negate of rationals"
3546   (splice-fun-args x '%negate 1)
3547   '(the rational x))
3548
3549 (deftransform %negate ((x) (number))
3550   "Combine %negate/*"
3551   (let ((use (lvar-uses x))
3552         arg)
3553     (unless (and (combination-p use)
3554                  (eql '* (lvar-fun-name (combination-fun use)))
3555                  (constant-lvar-p (setf arg (second (combination-args use))))
3556                  (numberp (setf arg (lvar-value arg))))
3557       (give-up-ir1-transform))
3558     (splice-fun-args x '* 2)
3559     `(lambda (x y)
3560        (declare (ignore y))
3561        (* x ,(- arg)))))
3562
3563 ;;; Return T if in an arithmetic op including lvars X and Y, the
3564 ;;; result type is not affected by the type of X. That is, Y is at
3565 ;;; least as contagious as X.
3566 #+nil
3567 (defun not-more-contagious (x y)
3568   (declare (type continuation x y))
3569   (let ((x (lvar-type x))
3570         (y (lvar-type y)))
3571     (values (type= (numeric-contagion x y)
3572                    (numeric-contagion y y)))))
3573 ;;; Patched version by Raymond Toy. dtc: Should be safer although it
3574 ;;; XXX needs more work as valid transforms are missed; some cases are
3575 ;;; specific to particular transform functions so the use of this
3576 ;;; function may need a re-think.
3577 (defun not-more-contagious (x y)
3578   (declare (type lvar x y))
3579   (flet ((simple-numeric-type (num)
3580            (and (numeric-type-p num)
3581                 ;; Return non-NIL if NUM is integer, rational, or a float
3582                 ;; of some type (but not FLOAT)
3583                 (case (numeric-type-class num)
3584                   ((integer rational)
3585                    t)
3586                   (float
3587                    (numeric-type-format num))
3588                   (t
3589                    nil)))))
3590     (let ((x (lvar-type x))
3591           (y (lvar-type y)))
3592       (if (and (simple-numeric-type x)
3593                (simple-numeric-type y))
3594           (values (type= (numeric-contagion x y)
3595                          (numeric-contagion y y)))))))
3596
3597 (def!type exact-number ()
3598   '(or rational (complex rational)))
3599
3600 ;;; Fold (+ x 0).
3601 ;;;
3602 ;;; Only safely applicable for exact numbers. For floating-point
3603 ;;; x, one would have to first show that neither x or y are signed
3604 ;;; 0s, and that x isn't an SNaN.
3605 (deftransform + ((x y) (exact-number (constant-arg (eql 0))) *)
3606   "fold zero arg"
3607   'x)
3608
3609 ;;; Fold (- x 0).
3610 (deftransform - ((x y) (exact-number (constant-arg (eql 0))) *)
3611   "fold zero arg"
3612   'x)
3613
3614 ;;; Fold (OP x +/-1)
3615 ;;;
3616 ;;; %NEGATE might not always signal correctly.
3617 (macrolet
3618     ((def (name result minus-result)
3619          `(deftransform ,name ((x y)
3620                                (exact-number (constant-arg (member 1 -1))))
3621             "fold identity operations"
3622             (if (minusp (lvar-value y)) ',minus-result ',result))))
3623   (def * x (%negate x))
3624   (def / x (%negate x))
3625   (def expt x (/ 1 x)))
3626
3627 ;;; Fold (expt x n) into multiplications for small integral values of
3628 ;;; N; convert (expt x 1/2) to sqrt.
3629 (deftransform expt ((x y) (t (constant-arg real)) *)
3630   "recode as multiplication or sqrt"
3631   (let ((val (lvar-value y)))
3632     ;; If Y would cause the result to be promoted to the same type as
3633     ;; Y, we give up. If not, then the result will be the same type
3634     ;; as X, so we can replace the exponentiation with simple
3635     ;; multiplication and division for small integral powers.
3636     (unless (not-more-contagious y x)
3637       (give-up-ir1-transform))
3638     (cond ((zerop val)
3639            (let ((x-type (lvar-type x)))
3640              (cond ((csubtypep x-type (specifier-type '(or rational
3641                                                         (complex rational))))
3642                     '1)
3643                    ((csubtypep x-type (specifier-type 'real))
3644                     `(if (rationalp x)
3645                          1
3646                          (float 1 x)))
3647                    ((csubtypep x-type (specifier-type 'complex))
3648                     ;; both parts are float
3649                     `(1+ (* x ,val)))
3650                    (t (give-up-ir1-transform)))))
3651           ((= val 2) '(* x x))
3652           ((= val -2) '(/ (* x x)))
3653           ((= val 3) '(* x x x))
3654           ((= val -3) '(/ (* x x x)))
3655           ((= val 1/2) '(sqrt x))
3656           ((= val -1/2) '(/ (sqrt x)))
3657           (t (give-up-ir1-transform)))))
3658
3659 (deftransform expt ((x y) ((constant-arg (member -1 -1.0 -1.0d0)) integer) *)
3660   "recode as an ODDP check"
3661   (let ((val (lvar-value x)))
3662     (if (eql -1 val)
3663         '(- 1 (* 2 (logand 1 y)))
3664         `(if (oddp y)
3665              ,val
3666              ,(abs val)))))
3667
3668 ;;; KLUDGE: Shouldn't (/ 0.0 0.0), etc. cause exceptions in these
3669 ;;; transformations?
3670 ;;; Perhaps we should have to prove that the denominator is nonzero before
3671 ;;; doing them?  -- WHN 19990917
3672 (macrolet ((def (name)
3673              `(deftransform ,name ((x y) ((constant-arg (integer 0 0)) integer)
3674                                    *)
3675                 "fold zero arg"
3676                 0)))
3677   (def ash)
3678   (def /))
3679
3680 (macrolet ((def (name)
3681              `(deftransform ,name ((x y) ((constant-arg (integer 0 0)) integer)
3682                                    *)
3683                 "fold zero arg"
3684                 '(values 0 0))))
3685   (def truncate)
3686   (def round)
3687   (def floor)
3688   (def ceiling))
3689
3690 (macrolet ((def (name &optional float)
3691              (let ((x (if float '(float x) 'x)))
3692                `(deftransform ,name ((x y) (integer (constant-arg (member 1 -1)))
3693                                      *)
3694                   "fold division by 1"
3695                   `(values ,(if (minusp (lvar-value y))
3696                                 '(%negate ,x)
3697                                 ',x)  0)))))
3698   (def truncate)
3699   (def round)
3700   (def floor)
3701   (def ceiling)
3702   (def ftruncate t)
3703   (def fround t)
3704   (def ffloor t)
3705   (def fceiling t))
3706
3707 \f
3708 ;;;; character operations
3709
3710 (deftransform two-arg-char-equal ((a b) (base-char base-char) *
3711                                   :policy (> speed space))
3712   "open code"
3713   '(let* ((ac (char-code a))
3714           (bc (char-code b))
3715           (sum (logxor ac bc)))
3716      (or (zerop sum)
3717          (when (eql sum #x20)
3718            (let ((sum (+ ac bc)))
3719              (or (and (> sum 161) (< sum 213))
3720                  (and (> sum 415) (< sum 461))
3721                  (and (> sum 463) (< sum 477))))))))
3722
3723 (deftransform two-arg-char-equal ((a b) (* (constant-arg character)) *
3724                                   :node node)
3725   (let ((char (lvar-value b)))
3726     (if (both-case-p char)
3727         (let ((reverse (if (upper-case-p char)
3728                            (char-downcase char)
3729                            (char-upcase char))))
3730           (if (policy node (> speed space))
3731               `(or (char= a ,char)
3732                    (char= a ,reverse))
3733               `(char-equal-constant a ,char ,reverse)))
3734         '(char= a b))))
3735
3736 (deftransform char-upcase ((x) (base-char))
3737   "open code"
3738   '(let ((n-code (char-code x)))
3739      (if (or (and (> n-code #o140)      ; Octal 141 is #\a.
3740                   (< n-code #o173))     ; Octal 172 is #\z.
3741              (and (> n-code #o337)
3742                   (< n-code #o367))
3743              (and (> n-code #o367)
3744                   (< n-code #o377)))
3745          (code-char (logxor #x20 n-code))
3746          x)))
3747
3748 (deftransform char-downcase ((x) (base-char))
3749   "open code"
3750   '(let ((n-code (char-code x)))
3751      (if (or (and (> n-code 64)         ; 65 is #\A.
3752                   (< n-code 91))        ; 90 is #\Z.
3753              (and (> n-code 191)
3754                   (< n-code 215))
3755              (and (> n-code 215)
3756                   (< n-code 223)))
3757          (code-char (logxor #x20 n-code))
3758          x)))
3759 \f
3760 ;;;; equality predicate transforms
3761
3762 ;;; Return true if X and Y are lvars whose only use is a
3763 ;;; reference to the same leaf, and the value of the leaf cannot
3764 ;;; change.
3765 (defun same-leaf-ref-p (x y)
3766   (declare (type lvar x y))
3767   (let ((x-use (principal-lvar-use x))
3768         (y-use (principal-lvar-use y)))
3769     (and (ref-p x-use)
3770          (ref-p y-use)
3771          (eq (ref-leaf x-use) (ref-leaf y-use))
3772          (constant-reference-p x-use))))
3773
3774 ;;; If X and Y are the same leaf, then the result is true. Otherwise,
3775 ;;; if there is no intersection between the types of the arguments,
3776 ;;; then the result is definitely false.
3777 (deftransform simple-equality-transform ((x y) * *
3778                                          :defun-only t)
3779   (cond
3780     ((same-leaf-ref-p x y) t)
3781     ((not (types-equal-or-intersect (lvar-type x) (lvar-type y)))
3782          nil)
3783     (t (give-up-ir1-transform))))
3784
3785 (macrolet ((def (x)
3786              `(%deftransform ',x '(function * *) #'simple-equality-transform)))
3787   (def eq)
3788   (def char=))
3789
3790 ;;; This is similar to SIMPLE-EQUALITY-TRANSFORM, except that we also
3791 ;;; try to convert to a type-specific predicate or EQ:
3792 ;;; -- If both args are characters, convert to CHAR=. This is better than
3793 ;;;    just converting to EQ, since CHAR= may have special compilation
3794 ;;;    strategies for non-standard representations, etc.
3795 ;;; -- If either arg is definitely a fixnum, we check to see if X is
3796 ;;;    constant and if so, put X second. Doing this results in better
3797 ;;;    code from the backend, since the backend assumes that any constant
3798 ;;;    argument comes second.
3799 ;;; -- If either arg is definitely not a number or a fixnum, then we
3800 ;;;    can compare with EQ.
3801 ;;; -- Otherwise, we try to put the arg we know more about second. If X
3802 ;;;    is constant then we put it second. If X is a subtype of Y, we put
3803 ;;;    it second. These rules make it easier for the back end to match
3804 ;;;    these interesting cases.
3805 (deftransform eql ((x y) * * :node node)
3806   "convert to simpler equality predicate"
3807   (let ((x-type (lvar-type x))
3808         (y-type (lvar-type y))
3809         (char-type (specifier-type 'character)))
3810     (flet ((fixnum-type-p (type)
3811              (csubtypep type (specifier-type 'fixnum))))
3812       (cond
3813         ((same-leaf-ref-p x y) t)
3814         ((not (types-equal-or-intersect x-type y-type))
3815          nil)
3816         ((and (csubtypep x-type char-type)
3817               (csubtypep y-type char-type))
3818          '(char= x y))
3819         ((or (eq-comparable-type-p x-type) (eq-comparable-type-p y-type))
3820          (if (and (constant-lvar-p x) (not (constant-lvar-p y)))
3821              '(eq y x)
3822              '(eq x y)))
3823         ((and (not (constant-lvar-p y))
3824               (or (constant-lvar-p x)
3825                   (and (csubtypep x-type y-type)
3826                        (not (csubtypep y-type x-type)))))
3827          '(eql y x))
3828         (t
3829          (give-up-ir1-transform))))))
3830
3831 ;;; similarly to the EQL transform above, we attempt to constant-fold
3832 ;;; or convert to a simpler predicate: mostly we have to be careful
3833 ;;; with strings and bit-vectors.
3834 (deftransform equal ((x y) * *)
3835   "convert to simpler equality predicate"
3836   (let ((x-type (lvar-type x))
3837         (y-type (lvar-type y))
3838         (combination-type (specifier-type '(or bit-vector string
3839                                             cons pathname))))
3840     (flet ((both-csubtypep (type)
3841              (let ((ctype (specifier-type type)))
3842                (and (csubtypep x-type ctype)
3843                     (csubtypep y-type ctype)))))
3844       (cond
3845         ((same-leaf-ref-p x y) t)
3846         ((both-csubtypep 'string)
3847          '(string= x y))
3848         ((both-csubtypep 'bit-vector)
3849          '(bit-vector-= x y))
3850         ((both-csubtypep 'pathname)
3851          '(pathname= x y))
3852         ((or (not (types-equal-or-intersect x-type combination-type))
3853              (not (types-equal-or-intersect y-type combination-type)))
3854          (if (types-equal-or-intersect x-type y-type)
3855              '(eql x y)
3856              ;; Can't simply check for type intersection if both types are combination-type
3857              ;; since array specialization would mean types don't intersect, even when EQUAL
3858              ;; doesn't care for specialization.
3859              ;; Previously checking for intersection in the outer COND resulted in
3860              ;;
3861              ;; (equal (the (cons (or simple-bit-vector
3862              ;;                       simple-base-string))
3863              ;;             x)
3864              ;;        (the (cons (or (and bit-vector (not simple-array))
3865              ;;                       (simple-array character (*))))
3866              ;;             y))
3867              ;; being incorrectly folded to NIL
3868              nil))
3869         (t (give-up-ir1-transform))))))
3870
3871 (deftransform equalp ((x y) * *)
3872   "convert to simpler equality predicate"
3873   (let ((x-type (lvar-type x))
3874         (y-type (lvar-type y))
3875         (combination-type (specifier-type '(or number array
3876                                             character
3877                                             cons pathname
3878                                             instance hash-table))))
3879     (flet ((both-csubtypep (type)
3880              (let ((ctype (specifier-type type)))
3881                (and (csubtypep x-type ctype)
3882                     (csubtypep y-type ctype)))))
3883       (cond
3884         ((same-leaf-ref-p x y) t)
3885         ((both-csubtypep 'string)
3886          '(string-equal x y))
3887         ((both-csubtypep 'bit-vector)
3888          '(bit-vector-= x y))
3889         ((both-csubtypep 'pathname)
3890          '(pathname= x y))
3891         ((both-csubtypep 'character)
3892          '(char-equal x y))
3893         ((both-csubtypep 'number)
3894          '(= x y))
3895         ((both-csubtypep 'hash-table)
3896          '(hash-table-equalp x y))
3897         ((or (not (types-equal-or-intersect x-type combination-type))
3898              (not (types-equal-or-intersect y-type combination-type)))
3899          ;; See the comment about specialized types in the EQUAL transform above
3900          (if (types-equal-or-intersect y-type x-type)
3901              '(eq x y)
3902              nil))
3903         (t (give-up-ir1-transform))))))
3904
3905 ;;; Convert to EQL if both args are rational and complexp is specified
3906 ;;; and the same for both.
3907 (deftransform = ((x y) (number number) *)
3908   "open code"
3909   (let ((x-type (lvar-type x))
3910         (y-type (lvar-type y)))
3911     (cond ((or (and (csubtypep x-type (specifier-type 'float))
3912                     (csubtypep y-type (specifier-type 'float)))
3913                (and (csubtypep x-type (specifier-type '(complex float)))
3914                     (csubtypep y-type (specifier-type '(complex float))))
3915                #!+complex-float-vops
3916                (and (csubtypep x-type (specifier-type '(or single-float (complex single-float))))
3917                     (csubtypep y-type (specifier-type '(or single-float (complex single-float)))))
3918                #!+complex-float-vops
3919                (and (csubtypep x-type (specifier-type '(or double-float (complex double-float))))
3920                     (csubtypep y-type (specifier-type '(or double-float (complex double-float))))))
3921            ;; They are both floats. Leave as = so that -0.0 is
3922            ;; handled correctly.
3923            (give-up-ir1-transform))
3924           ((or (and (csubtypep x-type (specifier-type 'rational))
3925                     (csubtypep y-type (specifier-type 'rational)))
3926                (and (csubtypep x-type
3927                                (specifier-type '(complex rational)))
3928                     (csubtypep y-type
3929                                (specifier-type '(complex rational)))))
3930            ;; They are both rationals and complexp is the same.
3931            ;; Convert to EQL.
3932            '(eql x y))
3933           (t
3934            (give-up-ir1-transform
3935             "The operands might not be the same type.")))))
3936
3937 (defun maybe-float-lvar-p (lvar)
3938   (neq *empty-type* (type-intersection (specifier-type 'float)
3939                                        (lvar-type lvar))))
3940
3941 (flet ((maybe-invert (node op inverted x y)
3942          ;; Don't invert if either argument can be a float (NaNs)
3943          (cond
3944            ((or (maybe-float-lvar-p x) (maybe-float-lvar-p y))
3945             (delay-ir1-transform node :constraint)
3946             `(or (,op x y) (= x y)))
3947            (t
3948             `(if (,inverted x y) nil t)))))
3949   (deftransform >= ((x y) (number number) * :node node)
3950     "invert or open code"
3951     (maybe-invert node '> '< x y))
3952   (deftransform <= ((x y) (number number) * :node node)
3953     "invert or open code"
3954     (maybe-invert node '< '> x y)))
3955
3956 ;;; See whether we can statically determine (< X Y) using type
3957 ;;; information. If X's high bound is < Y's low, then X < Y.
3958 ;;; Similarly, if X's low is >= to Y's high, the X >= Y (so return
3959 ;;; NIL). If not, at least make sure any constant arg is second.
3960 (macrolet ((def (name inverse reflexive-p surely-true surely-false)
3961              `(deftransform ,name ((x y))
3962                 "optimize using intervals"
3963                 (if (and (same-leaf-ref-p x y)
3964                          ;; For non-reflexive functions we don't need
3965                          ;; to worry about NaNs: (non-ref-op NaN NaN) => false,
3966                          ;; but with reflexive ones we don't know...
3967                          ,@(when reflexive-p
3968                                  '((and (not (maybe-float-lvar-p x))
3969                                         (not (maybe-float-lvar-p y))))))
3970                     ,reflexive-p
3971                     (let ((ix (or (type-approximate-interval (lvar-type x))
3972                                   (give-up-ir1-transform)))
3973                           (iy (or (type-approximate-interval (lvar-type y))
3974                                   (give-up-ir1-transform))))
3975                       (cond (,surely-true
3976                              t)
3977                             (,surely-false
3978                              nil)
3979                             ((and (constant-lvar-p x)
3980                                   (not (constant-lvar-p y)))
3981                              `(,',inverse y x))
3982                             (t
3983                              (give-up-ir1-transform))))))))
3984   (def = = t (interval-= ix iy) (interval-/= ix iy))
3985   (def /= /= nil (interval-/= ix iy) (interval-= ix iy))
3986   (def < > nil (interval-< ix iy) (interval->= ix iy))
3987   (def > < nil (interval-< iy ix) (interval->= iy ix))
3988   (def <= >= t (interval->= iy ix) (interval-< iy ix))
3989   (def >= <= t (interval->= ix iy) (interval-< ix iy)))
3990
3991 (defun ir1-transform-char< (x y first second inverse)
3992   (cond
3993     ((same-leaf-ref-p x y) nil)
3994     ;; If we had interval representation of character types, as we
3995     ;; might eventually have to to support 2^21 characters, then here
3996     ;; we could do some compile-time computation as in transforms for
3997     ;; < above. -- CSR, 2003-07-01
3998     ((and (constant-lvar-p first)
3999           (not (constant-lvar-p second)))
4000      `(,inverse y x))
4001     (t (give-up-ir1-transform))))
4002
4003 (deftransform char< ((x y) (character character) *)
4004   (ir1-transform-char< x y x y 'char>))
4005
4006 (deftransform char> ((x y) (character character) *)
4007   (ir1-transform-char< y x x y 'char<))
4008 \f
4009 ;;;; converting N-arg comparisons
4010 ;;;;
4011 ;;;; We convert calls to N-arg comparison functions such as < into
4012 ;;;; two-arg calls. This transformation is enabled for all such
4013 ;;;; comparisons in this file. If any of these predicates are not
4014 ;;;; open-coded, then the transformation should be removed at some
4015 ;;;; point to avoid pessimization.
4016
4017 ;;; This function is used for source transformation of N-arg
4018 ;;; comparison functions other than inequality. We deal both with
4019 ;;; converting to two-arg calls and inverting the sense of the test,
4020 ;;; if necessary. If the call has two args, then we pass or return a
4021 ;;; negated test as appropriate. If it is a degenerate one-arg call,
4022 ;;; then we transform to code that returns true. Otherwise, we bind
4023 ;;; all the arguments and expand into a bunch of IFs.
4024 (defun multi-compare (predicate args not-p type &optional force-two-arg-p)
4025   (let ((nargs (length args)))
4026     (cond ((< nargs 1) (values nil t))
4027           ((= nargs 1) `(progn (the ,type ,@args) t))
4028           ((= nargs 2)
4029            (if not-p
4030                `(if (,predicate ,(first args) ,(second args)) nil t)
4031                (if force-two-arg-p
4032                    `(,predicate ,(first args) ,(second args))
4033                    (values nil t))))
4034           (t
4035            (do* ((i (1- nargs) (1- i))
4036                  (last nil current)
4037                  (current (gensym) (gensym))
4038                  (vars (list current) (cons current vars))
4039                  (result t (if not-p
4040                                `(if (,predicate ,current ,last)
4041                                     nil ,result)
4042                                `(if (,predicate ,current ,last)
4043                                     ,result nil))))
4044                ((zerop i)
4045                 `((lambda ,vars (declare (type ,type ,@vars)) ,result)
4046                   ,@args)))))))
4047
4048 (define-source-transform = (&rest args) (multi-compare '= args nil 'number))
4049 (define-source-transform < (&rest args) (multi-compare '< args nil 'real))
4050 (define-source-transform > (&rest args) (multi-compare '> args nil 'real))
4051 ;;; We cannot do the inversion for >= and <= here, since both
4052 ;;;   (< NaN X) and (> NaN X)
4053 ;;; are false, and we don't have type-information available yet. The
4054 ;;; deftransforms for two-argument versions of >= and <= takes care of
4055 ;;; the inversion to > and < when possible.
4056 (define-source-transform <= (&rest args) (multi-compare '<= args nil 'real))
4057 (define-source-transform >= (&rest args) (multi-compare '>= args nil 'real))
4058
4059 (define-source-transform char= (&rest args) (multi-compare 'char= args nil
4060                                                            'character))
4061 (define-source-transform char< (&rest args) (multi-compare 'char< args nil
4062                                                            'character))
4063 (define-source-transform char> (&rest args) (multi-compare 'char> args nil
4064                                                            'character))
4065 (define-source-transform char<= (&rest args) (multi-compare 'char> args t
4066                                                             'character))
4067 (define-source-transform char>= (&rest args) (multi-compare 'char< args t
4068                                                             'character))
4069
4070 (define-source-transform char-equal (&rest args)
4071   (multi-compare 'two-arg-char-equal args nil 'character t))
4072 (define-source-transform char-lessp (&rest args)
4073   (multi-compare 'two-arg-char-lessp args nil 'character t))
4074 (define-source-transform char-greaterp (&rest args)
4075   (multi-compare 'two-arg-char-greaterp args nil 'character t))
4076 (define-source-transform char-not-greaterp (&rest args)
4077   (multi-compare 'two-arg-char-greaterp args t 'character t))
4078 (define-source-transform char-not-lessp (&rest args)
4079   (multi-compare 'two-arg-char-lessp args t 'character t))
4080
4081 ;;; This function does source transformation of N-arg inequality
4082 ;;; functions such as /=. This is similar to MULTI-COMPARE in the <3
4083 ;;; arg cases. If there are more than two args, then we expand into
4084 ;;; the appropriate n^2 comparisons only when speed is important.
4085 (declaim (ftype (function (symbol list t) *) multi-not-equal))
4086 (defun multi-not-equal (predicate args type)
4087   (let ((nargs (length args)))
4088     (cond ((< nargs 1) (values nil t))
4089           ((= nargs 1) `(progn (the ,type ,@args) t))
4090           ((= nargs 2)
4091            `(if (,predicate ,(first args) ,(second args)) nil t))
4092           ((not (policy *lexenv*
4093                         (and (>= speed space)
4094                              (>= speed compilation-speed))))
4095            (values nil t))
4096           (t
4097            (let ((vars (make-gensym-list nargs)))
4098              (do ((var vars next)
4099                   (next (cdr vars) (cdr next))
4100                   (result t))
4101                  ((null next)
4102                   `((lambda ,vars (declare (type ,type ,@vars)) ,result)
4103                     ,@args))
4104                (let ((v1 (first var)))
4105                  (dolist (v2 next)
4106                    (setq result `(if (,predicate ,v1 ,v2) nil ,result))))))))))
4107
4108 (define-source-transform /= (&rest args)
4109   (multi-not-equal '= args 'number))
4110 (define-source-transform char/= (&rest args)
4111   (multi-not-equal 'char= args 'character))
4112 (define-source-transform char-not-equal (&rest args)
4113   (multi-not-equal 'char-equal args 'character))
4114
4115 ;;; Expand MAX and MIN into the obvious comparisons.
4116 (define-source-transform max (arg0 &rest rest)
4117   (once-only ((arg0 arg0))
4118     (if (null rest)
4119         `(values (the real ,arg0))
4120         `(let ((maxrest (max ,@rest)))
4121           (if (>= ,arg0 maxrest) ,arg0 maxrest)))))
4122 (define-source-transform min (arg0 &rest rest)
4123   (once-only ((arg0 arg0))
4124     (if (null rest)
4125         `(values (the real ,arg0))
4126         `(let ((minrest (min ,@rest)))
4127           (if (<= ,arg0 minrest) ,arg0 minrest)))))
4128
4129 ;;; Simplify some cross-type comparisons
4130 (macrolet ((def (comparator round)
4131              `(progn
4132                 (deftransform ,comparator
4133                     ((x y) (rational (constant-arg float)))
4134                   "open-code RATIONAL to FLOAT comparison"
4135                   (let ((y (lvar-value y)))
4136                     #-sb-xc-host
4137                     (when (or (float-nan-p y)
4138                               (float-infinity-p y))
4139                       (give-up-ir1-transform))
4140                     (setf y (rational y))
4141                     `(,',comparator
4142                       x ,(if (csubtypep (lvar-type x)
4143                                         (specifier-type 'integer))
4144                              (,round y)
4145                              y))))
4146                 (deftransform ,comparator
4147                     ((x y) (integer (constant-arg ratio)))
4148                   "open-code INTEGER to RATIO comparison"
4149                   `(,',comparator x ,(,round (lvar-value y)))))))
4150   (def < ceiling)
4151   (def > floor))
4152
4153 (deftransform = ((x y) (rational (constant-arg float)))
4154   "open-code RATIONAL to FLOAT comparison"
4155   (let ((y (lvar-value y)))
4156     #-sb-xc-host
4157     (when (or (float-nan-p y)
4158               (float-infinity-p y))
4159       (give-up-ir1-transform))
4160     (setf y (rational y))
4161     (if (and (csubtypep (lvar-type x)
4162                         (specifier-type 'integer))
4163              (ratiop y))
4164         nil
4165         `(= x ,y))))
4166
4167 (deftransform = ((x y) (integer (constant-arg ratio)))
4168   "constant-fold INTEGER to RATIO comparison"
4169   nil)
4170 \f
4171 ;;;; converting N-arg arithmetic functions
4172 ;;;;
4173 ;;;; N-arg arithmetic and logic functions are associated into two-arg
4174 ;;;; versions, and degenerate cases are flushed.
4175
4176 ;;; Left-associate FIRST-ARG and MORE-ARGS using FUNCTION.
4177 (declaim (ftype (sfunction (symbol t list t) list) associate-args))
4178 (defun associate-args (fun first-arg more-args identity)
4179   (let ((next (rest more-args))
4180         (arg (first more-args)))
4181     (if (null next)
4182         `(,fun ,first-arg ,(if arg arg identity))
4183         (associate-args fun `(,fun ,first-arg ,arg) next identity))))
4184
4185 ;;; Reduce constants in ARGS list.
4186 (declaim (ftype (sfunction (symbol list t symbol) list) reduce-constants))
4187 (defun reduce-constants (fun args identity one-arg-result-type)
4188   (let ((one-arg-constant-p (ecase one-arg-result-type
4189                               (number #'numberp)
4190                               (integer #'integerp)))
4191         (reduced-value identity)
4192         (reduced-p nil))
4193     (collect ((not-constants))
4194       (dolist (arg args)
4195         (if (funcall one-arg-constant-p arg)
4196             (setf reduced-value (funcall fun reduced-value arg)
4197                   reduced-p t)
4198             (not-constants arg)))
4199       ;; It is tempting to drop constants reduced to identity here,
4200       ;; but if X is SNaN in (* X 1), we cannot drop the 1.
4201       (if (not-constants)
4202           (if reduced-p
4203               `(,reduced-value ,@(not-constants))
4204               (not-constants))
4205           `(,reduced-value)))))
4206
4207 ;;; Do source transformations for transitive functions such as +.
4208 ;;; One-arg cases are replaced with the arg and zero arg cases with
4209 ;;; the identity. ONE-ARG-RESULT-TYPE is the type to ensure (with THE)
4210 ;;; that the argument in one-argument calls is.
4211 (declaim (ftype (function (symbol list t &optional symbol list)
4212                           (values t &optional (member nil t)))
4213                 source-transform-transitive))
4214 (defun source-transform-transitive (fun args identity
4215                                     &optional (one-arg-result-type 'number)
4216                                               (one-arg-prefixes '(values)))
4217   (case (length args)
4218     (0 identity)
4219     (1 `(,@one-arg-prefixes (the ,one-arg-result-type ,(first args))))
4220     (2 (values nil t))
4221     (t (let ((reduced-args (reduce-constants fun args identity one-arg-result-type)))
4222          (associate-args fun (first reduced-args) (rest reduced-args) identity)))))
4223
4224 (define-source-transform + (&rest args)
4225   (source-transform-transitive '+ args 0))
4226 (define-source-transform * (&rest args)
4227   (source-transform-transitive '* args 1))
4228 (define-source-transform logior (&rest args)
4229   (source-transform-transitive 'logior args 0 'integer))
4230 (define-source-transform logxor (&rest args)
4231   (source-transform-transitive 'logxor args 0 'integer))
4232 (define-source-transform logand (&rest args)
4233   (source-transform-transitive 'logand args -1 'integer))
4234 (define-source-transform logeqv (&rest args)
4235   (source-transform-transitive 'logeqv args -1 'integer))
4236 (define-source-transform gcd (&rest args)
4237   (source-transform-transitive 'gcd args 0 'integer '(abs)))
4238 (define-source-transform lcm (&rest args)
4239   (source-transform-transitive 'lcm args 1 'integer '(abs)))
4240
4241 ;;; Do source transformations for intransitive n-arg functions such as
4242 ;;; /. With one arg, we form the inverse. With two args we pass.
4243 ;;; Otherwise we associate into two-arg calls.
4244 (declaim (ftype (function (symbol symbol list t list &optional symbol)
4245                           (values list &optional (member nil t)))
4246                 source-transform-intransitive))
4247 (defun source-transform-intransitive (fun fun* args identity one-arg-prefixes
4248                                       &optional (one-arg-result-type 'number))
4249   (case (length args)
4250     ((0 2) (values nil t))
4251     (1 `(,@one-arg-prefixes (the ,one-arg-result-type ,(first args))))
4252     (t (let ((reduced-args
4253               (reduce-constants fun* (rest args) identity one-arg-result-type)))
4254          (associate-args fun (first args) reduced-args identity)))))
4255
4256 (define-source-transform - (&rest args)
4257   (source-transform-intransitive '- '+ args 0 '(%negate)))
4258 (define-source-transform / (&rest args)
4259   (source-transform-intransitive '/ '* args 1 '(/ 1)))
4260 \f
4261 ;;;; transforming APPLY
4262
4263 ;;; We convert APPLY into MULTIPLE-VALUE-CALL so that the compiler
4264 ;;; only needs to understand one kind of variable-argument call. It is
4265 ;;; more efficient to convert APPLY to MV-CALL than MV-CALL to APPLY.
4266 (define-source-transform apply (fun arg &rest more-args)
4267   (let ((args (cons arg more-args)))
4268     `(multiple-value-call ,fun
4269        ,@(mapcar (lambda (x) `(values ,x)) (butlast args))
4270        (values-list ,(car (last args))))))
4271
4272 ;;;; transforming references to &REST argument
4273
4274 ;;; We add magical &MORE arguments to all functions with &REST. If ARG names
4275 ;;; the &REST argument, this returns the lambda-vars for the context and
4276 ;;; count.
4277 (defun possible-rest-arg-context (arg)
4278   (when (symbolp arg)
4279     (let* ((var (lexenv-find arg vars))
4280            (info (when (lambda-var-p var)
4281                    (lambda-var-arg-info var))))
4282       (when (and info
4283                  (eq :rest (arg-info-kind info))
4284                  (consp (arg-info-default info)))
4285         (values-list (arg-info-default info))))))
4286
4287 (defun mark-more-context-used (rest-var)
4288   (let ((info (lambda-var-arg-info rest-var)))
4289     (aver (eq :rest (arg-info-kind info)))
4290     (destructuring-bind (context count &optional used) (arg-info-default info)
4291       (unless used
4292         (setf (arg-info-default info) (list context count t))))))
4293
4294 (defun mark-more-context-invalid (rest-var)
4295   (let ((info (lambda-var-arg-info rest-var)))
4296     (aver (eq :rest (arg-info-kind info)))
4297     (setf (arg-info-default info) t)))
4298
4299 ;;; This determines of we the REF to a &REST variable is headed towards
4300 ;;; parts unknown, or if we can really use the context.
4301 (defun rest-var-more-context-ok (lvar)
4302   (let* ((use (lvar-use lvar))
4303          (var (when (ref-p use) (ref-leaf use)))
4304          (home (when (lambda-var-p var) (lambda-var-home var)))
4305          (info (when (lambda-var-p var) (lambda-var-arg-info var)))
4306          (restp (when info (eq :rest (arg-info-kind info)))))
4307     (flet ((ref-good-for-more-context-p (ref)
4308              (let ((dest (principal-lvar-end (node-lvar ref))))
4309                (and (combination-p dest)
4310                     ;; If the destination is to anything but these, we're going to
4311                     ;; actually need the rest list -- and since other operations
4312                     ;; might modify the list destructively, the using the context
4313                     ;; isn't good anywhere else either.
4314                     (lvar-fun-is (combination-fun dest)
4315                                  '(%rest-values %rest-ref %rest-length
4316                                    %rest-null %rest-true))
4317                     ;; If the home lambda is different and isn't DX, it might
4318                     ;; escape -- in which case using the more context isn't safe.
4319                     (let ((clambda (node-home-lambda dest)))
4320                       (or (eq home clambda)
4321                           (leaf-dynamic-extent clambda)))))))
4322       (let ((ok (and restp
4323                      (consp (arg-info-default info))
4324                      (not (lambda-var-specvar var))
4325                      (not (lambda-var-sets var))
4326                      (every #'ref-good-for-more-context-p (lambda-var-refs var)))))
4327         (if ok
4328             (mark-more-context-used var)
4329             (when restp
4330               (mark-more-context-invalid var)))
4331         ok))))
4332
4333 ;;; VALUES-LIST -> %REST-VALUES
4334 (define-source-transform values-list (list)
4335   (multiple-value-bind (context count) (possible-rest-arg-context list)
4336     (if context
4337         `(%rest-values ,list ,context ,count)
4338         (values nil t))))
4339
4340 ;;; NTH -> %REST-REF
4341 (define-source-transform nth (n list)
4342   (multiple-value-bind (context count) (possible-rest-arg-context list)
4343     (if context
4344         `(%rest-ref ,n ,list ,context ,count)
4345         `(car (nthcdr ,n ,list)))))
4346
4347 (define-source-transform elt (seq n)
4348   (if (policy *lexenv* (= safety 3))
4349       (values nil t)
4350       (multiple-value-bind (context count) (possible-rest-arg-context seq)
4351         (if context
4352             `(%rest-ref ,n ,seq ,context ,count)
4353             (values nil t)))))
4354
4355 ;;; CAxR -> %REST-REF
4356 (defun source-transform-car (list nth)
4357   (multiple-value-bind (context count) (possible-rest-arg-context list)
4358     (if context
4359         `(%rest-ref ,nth ,list ,context ,count)
4360         (values nil t))))
4361
4362 (define-source-transform car (list)
4363   (source-transform-car list 0))
4364
4365 (define-source-transform cadr (list)
4366   (or (source-transform-car list 1)
4367       `(car (cdr ,list))))
4368
4369 (define-source-transform caddr (list)
4370   (or (source-transform-car list 2)
4371       `(car (cdr (cdr ,list)))))
4372
4373 (define-source-transform cadddr (list)
4374   (or (source-transform-car list 3)
4375       `(car (cdr (cdr (cdr ,list))))))
4376
4377 ;;; LENGTH -> %REST-LENGTH
4378 (defun source-transform-length (list)
4379   (multiple-value-bind (context count) (possible-rest-arg-context list)
4380     (if context
4381         `(%rest-length ,list ,context ,count)
4382         (values nil t))))
4383 (define-source-transform length (list) (source-transform-length list))
4384 (define-source-transform list-length (list) (source-transform-length list))
4385
4386 ;;; ENDP, NULL and NOT -> %REST-NULL
4387 ;;;
4388 ;;; Outside &REST convert into an IF so that IF optimizations will eliminate
4389 ;;; redundant negations.
4390 (defun source-transform-null (x op)
4391   (multiple-value-bind (context count) (possible-rest-arg-context x)
4392     (cond (context
4393            `(%rest-null ',op ,x ,context ,count))
4394           ((eq 'endp op)
4395            `(if (the list ,x) nil t))
4396           (t
4397            `(if ,x nil t)))))
4398 (define-source-transform not (x) (source-transform-null x 'not))
4399 (define-source-transform null (x) (source-transform-null x 'null))
4400 (define-source-transform endp (x) (source-transform-null x 'endp))
4401
4402 (deftransform %rest-values ((list context count))
4403   (if (rest-var-more-context-ok list)
4404       `(%more-arg-values context 0 count)
4405       `(values-list list)))
4406
4407 (deftransform %rest-ref ((n list context count))
4408   (cond ((rest-var-more-context-ok list)
4409          `(and (< (the index n) count)
4410                (%more-arg context n)))
4411         ((and (constant-lvar-p n) (zerop (lvar-value n)))
4412          `(car list))
4413         (t
4414          `(nth n list))))
4415
4416 (deftransform %rest-length ((list context count))
4417   (if (rest-var-more-context-ok list)
4418       'count
4419       `(length list)))
4420
4421 (deftransform %rest-null ((op list context count))
4422   (aver (constant-lvar-p op))
4423   (if (rest-var-more-context-ok list)
4424       `(eql 0 count)
4425       `(,(lvar-value op) list)))
4426
4427 (deftransform %rest-true ((list context count))
4428   (if (rest-var-more-context-ok list)
4429       `(not (eql 0 count))
4430       `list))
4431 \f
4432 ;;;; transforming FORMAT
4433 ;;;;
4434 ;;;; If the control string is a compile-time constant, then replace it
4435 ;;;; with a use of the FORMATTER macro so that the control string is
4436 ;;;; ``compiled.'' Furthermore, if the destination is either a stream
4437 ;;;; or T and the control string is a function (i.e. FORMATTER), then
4438 ;;;; convert the call to FORMAT to just a FUNCALL of that function.
4439
4440 ;;; for compile-time argument count checking.
4441 ;;;
4442 ;;; FIXME II: In some cases, type information could be correlated; for
4443 ;;; instance, ~{ ... ~} requires a list argument, so if the lvar-type
4444 ;;; of a corresponding argument is known and does not intersect the
4445 ;;; list type, a warning could be signalled.
4446 (defun check-format-args (string args fun)
4447   (declare (type string string))
4448   (unless (typep string 'simple-string)
4449     (setq string (coerce string 'simple-string)))
4450   (multiple-value-bind (min max)
4451       (handler-case (sb!format:%compiler-walk-format-string string args)
4452         (sb!format:format-error (c)
4453           (compiler-warn "~A" c)))
4454     (when min
4455       (let ((nargs (length args)))
4456         (cond
4457           ((< nargs min)
4458            (warn 'format-too-few-args-warning
4459                  :format-control
4460                  "Too few arguments (~D) to ~S ~S: requires at least ~D."
4461                  :format-arguments (list nargs fun string min)))
4462           ((> nargs max)
4463            (warn 'format-too-many-args-warning
4464                  :format-control
4465                  "Too many arguments (~D) to ~S ~S: uses at most ~D."
4466                  :format-arguments (list nargs fun string max))))))))
4467
4468 (defoptimizer (format optimizer) ((dest control &rest args))
4469   (when (constant-lvar-p control)
4470     (let ((x (lvar-value control)))
4471       (when (stringp x)
4472         (check-format-args x args 'format)))))
4473
4474 ;;; We disable this transform in the cross-compiler to save memory in
4475 ;;; the target image; most of the uses of FORMAT in the compiler are for
4476 ;;; error messages, and those don't need to be particularly fast.
4477 #+sb-xc
4478 (deftransform format ((dest control &rest args) (t simple-string &rest t) *
4479                       :policy (>= speed space))
4480   (unless (constant-lvar-p control)
4481     (give-up-ir1-transform "The control string is not a constant."))
4482   (let ((arg-names (make-gensym-list (length args))))
4483     `(lambda (dest control ,@arg-names)
4484        (declare (ignore control))
4485        (format dest (formatter ,(lvar-value control)) ,@arg-names))))
4486
4487 (deftransform format ((stream control &rest args) (stream function &rest t))
4488   (let ((arg-names (make-gensym-list (length args))))
4489     `(lambda (stream control ,@arg-names)
4490        (funcall control stream ,@arg-names)
4491        nil)))
4492
4493 (deftransform format ((tee control &rest args) ((member t) function &rest t))
4494   (let ((arg-names (make-gensym-list (length args))))
4495     `(lambda (tee control ,@arg-names)
4496        (declare (ignore tee))
4497        (funcall control *standard-output* ,@arg-names)
4498        nil)))
4499
4500 (deftransform pathname ((pathspec) (pathname) *)
4501   'pathspec)
4502
4503 (deftransform pathname ((pathspec) (string) *)
4504   '(values (parse-namestring pathspec)))
4505
4506 (macrolet
4507     ((def (name)
4508          `(defoptimizer (,name optimizer) ((control &rest args))
4509             (when (constant-lvar-p control)
4510               (let ((x (lvar-value control)))
4511                 (when (stringp x)
4512                   (check-format-args x args ',name)))))))
4513   (def error)
4514   (def warn)
4515   #+sb-xc-host ; Only we should be using these
4516   (progn
4517     (def style-warn)
4518     (def compiler-error)
4519     (def compiler-warn)
4520     (def compiler-style-warn)
4521     (def compiler-notify)
4522     (def maybe-compiler-notify)
4523     (def bug)))
4524
4525 (defoptimizer (cerror optimizer) ((report control &rest args))
4526   (when (and (constant-lvar-p control)
4527              (constant-lvar-p report))
4528     (let ((x (lvar-value control))
4529           (y (lvar-value report)))
4530       (when (and (stringp x) (stringp y))
4531         (multiple-value-bind (min1 max1)
4532             (handler-case
4533                 (sb!format:%compiler-walk-format-string x args)
4534               (sb!format:format-error (c)
4535                 (compiler-warn "~A" c)))
4536           (when min1
4537             (multiple-value-bind (min2 max2)
4538                 (handler-case
4539                     (sb!format:%compiler-walk-format-string y args)
4540                   (sb!format:format-error (c)
4541                     (compiler-warn "~A" c)))
4542               (when min2
4543                 (let ((nargs (length args)))
4544                   (cond
4545                     ((< nargs (min min1 min2))
4546                      (warn 'format-too-few-args-warning
4547                            :format-control
4548                            "Too few arguments (~D) to ~S ~S ~S: ~
4549                             requires at least ~D."
4550                            :format-arguments
4551                            (list nargs 'cerror y x (min min1 min2))))
4552                     ((> nargs (max max1 max2))
4553                      (warn 'format-too-many-args-warning
4554                            :format-control
4555                            "Too many arguments (~D) to ~S ~S ~S: ~
4556                             uses at most ~D."
4557                            :format-arguments
4558                            (list nargs 'cerror y x (max max1 max2))))))))))))))
4559
4560 (defoptimizer (coerce derive-type) ((value type) node)
4561   (cond
4562     ((constant-lvar-p type)
4563      ;; This branch is essentially (RESULT-TYPE-SPECIFIER-NTH-ARG 2),
4564      ;; but dealing with the niggle that complex canonicalization gets
4565      ;; in the way: (COERCE 1 'COMPLEX) returns 1, which is not of
4566      ;; type COMPLEX.
4567      (let* ((specifier (lvar-value type))
4568             (result-typeoid (careful-specifier-type specifier)))
4569        (cond
4570          ((null result-typeoid) nil)
4571          ((csubtypep result-typeoid (specifier-type 'number))
4572           ;; the difficult case: we have to cope with ANSI 12.1.5.3
4573           ;; Rule of Canonical Representation for Complex Rationals,
4574           ;; which is a truly nasty delivery to field.
4575           (cond
4576             ((csubtypep result-typeoid (specifier-type 'real))
4577              ;; cleverness required here: it would be nice to deduce
4578              ;; that something of type (INTEGER 2 3) coerced to type
4579              ;; DOUBLE-FLOAT should return (DOUBLE-FLOAT 2.0d0 3.0d0).
4580              ;; FLOAT gets its own clause because it's implemented as
4581              ;; a UNION-TYPE, so we don't catch it in the NUMERIC-TYPE
4582              ;; logic below.
4583              result-typeoid)
4584             ((and (numeric-type-p result-typeoid)
4585                   (eq (numeric-type-complexp result-typeoid) :real))
4586              ;; FIXME: is this clause (a) necessary or (b) useful?
4587              result-typeoid)
4588             ((or (csubtypep result-typeoid
4589                             (specifier-type '(complex single-float)))
4590                  (csubtypep result-typeoid
4591                             (specifier-type '(complex double-float)))
4592                  #!+long-float
4593                  (csubtypep result-typeoid
4594                             (specifier-type '(complex long-float))))
4595              ;; float complex types are never canonicalized.
4596              result-typeoid)
4597             (t
4598              ;; if it's not a REAL, or a COMPLEX FLOAToid, it's
4599              ;; probably just a COMPLEX or equivalent.  So, in that
4600              ;; case, we will return a complex or an object of the
4601              ;; provided type if it's rational:
4602              (type-union result-typeoid
4603                          (type-intersection (lvar-type value)
4604                                             (specifier-type 'rational))))))
4605          ((and (policy node (zerop safety))
4606                (csubtypep result-typeoid (specifier-type '(array * (*)))))
4607           ;; At zero safety the deftransform for COERCE can elide dimension
4608           ;; checks for the things like (COERCE X '(SIMPLE-VECTOR 5)) -- so we
4609           ;; need to simplify the type to drop the dimension information.
4610           (let ((vtype (simplify-vector-type result-typeoid)))
4611             (if vtype
4612                 (specifier-type vtype)
4613                 result-typeoid)))
4614          (t
4615           result-typeoid))))
4616     (t
4617      ;; OK, the result-type argument isn't constant.  However, there
4618      ;; are common uses where we can still do better than just
4619      ;; *UNIVERSAL-TYPE*: e.g. (COERCE X (ARRAY-ELEMENT-TYPE Y)),
4620      ;; where Y is of a known type.  See messages on cmucl-imp
4621      ;; 2001-02-14 and sbcl-devel 2002-12-12.  We only worry here
4622      ;; about types that can be returned by (ARRAY-ELEMENT-TYPE Y), on
4623      ;; the basis that it's unlikely that other uses are both
4624      ;; time-critical and get to this branch of the COND (non-constant
4625      ;; second argument to COERCE).  -- CSR, 2002-12-16
4626      (let ((value-type (lvar-type value))
4627            (type-type (lvar-type type)))
4628        (labels
4629            ((good-cons-type-p (cons-type)
4630               ;; Make sure the cons-type we're looking at is something
4631               ;; we're prepared to handle which is basically something
4632               ;; that array-element-type can return.
4633               (or (and (member-type-p cons-type)
4634                        (eql 1 (member-type-size cons-type))
4635                        (null (first (member-type-members cons-type))))
4636                   (let ((car-type (cons-type-car-type cons-type)))
4637                     (and (member-type-p car-type)
4638                          (eql 1 (member-type-members car-type))
4639                          (let ((elt (first (member-type-members car-type))))
4640                            (or (symbolp elt)
4641                                (numberp elt)
4642                                (and (listp elt)
4643                                     (numberp (first elt)))))
4644                          (good-cons-type-p (cons-type-cdr-type cons-type))))))
4645             (unconsify-type (good-cons-type)
4646               ;; Convert the "printed" respresentation of a cons
4647               ;; specifier into a type specifier.  That is, the
4648               ;; specifier (CONS (EQL SIGNED-BYTE) (CONS (EQL 16)
4649               ;; NULL)) is converted to (SIGNED-BYTE 16).
4650               (cond ((or (null good-cons-type)
4651                          (eq good-cons-type 'null))
4652                      nil)
4653                     ((and (eq (first good-cons-type) 'cons)
4654                           (eq (first (second good-cons-type)) 'member))
4655                      `(,(second (second good-cons-type))
4656                        ,@(unconsify-type (caddr good-cons-type))))))
4657             (coerceable-p (part)
4658               ;; Can the value be coerced to the given type?  Coerce is
4659               ;; complicated, so we don't handle every possible case
4660               ;; here---just the most common and easiest cases:
4661               ;;
4662               ;; * Any REAL can be coerced to a FLOAT type.
4663               ;; * Any NUMBER can be coerced to a (COMPLEX
4664               ;;   SINGLE/DOUBLE-FLOAT).
4665               ;;
4666               ;; FIXME I: we should also be able to deal with characters
4667               ;; here.
4668               ;;
4669               ;; FIXME II: I'm not sure that anything is necessary
4670               ;; here, at least while COMPLEX is not a specialized
4671               ;; array element type in the system.  Reasoning: if
4672               ;; something cannot be coerced to the requested type, an
4673               ;; error will be raised (and so any downstream compiled
4674               ;; code on the assumption of the returned type is
4675               ;; unreachable).  If something can, then it will be of
4676               ;; the requested type, because (by assumption) COMPLEX
4677               ;; (and other difficult types like (COMPLEX INTEGER)
4678               ;; aren't specialized types.
4679               (let ((coerced-type (careful-specifier-type part)))
4680                 (when coerced-type
4681                   (or (and (csubtypep coerced-type (specifier-type 'float))
4682                            (csubtypep value-type (specifier-type 'real)))
4683                       (and (csubtypep coerced-type
4684                                       (specifier-type `(or (complex single-float)
4685                                                            (complex double-float))))
4686                           (csubtypep value-type (specifier-type 'number)))))))
4687             (process-types (type)
4688               ;; FIXME: This needs some work because we should be able
4689               ;; to derive the resulting type better than just the
4690               ;; type arg of coerce.  That is, if X is (INTEGER 10
4691               ;; 20), then (COERCE X 'DOUBLE-FLOAT) should say
4692               ;; (DOUBLE-FLOAT 10d0 20d0) instead of just
4693               ;; double-float.
4694               (cond ((member-type-p type)
4695                      (block punt
4696                        (let (members)
4697                          (mapc-member-type-members
4698                           (lambda (member)
4699                             (if (coerceable-p member)
4700                                 (push member members)
4701                                 (return-from punt *universal-type*)))
4702                           type)
4703                          (specifier-type `(or ,@members)))))
4704                     ((and (cons-type-p type)
4705                           (good-cons-type-p type))
4706                      (let ((c-type (unconsify-type (type-specifier type))))
4707                        (if (coerceable-p c-type)
4708                            (specifier-type c-type)
4709                            *universal-type*)))
4710                     (t
4711                      *universal-type*))))
4712          (cond ((union-type-p type-type)
4713                 (apply #'type-union (mapcar #'process-types
4714                                             (union-type-types type-type))))
4715                ((or (member-type-p type-type)
4716                     (cons-type-p type-type))
4717                 (process-types type-type))
4718                (t
4719                 *universal-type*)))))))
4720
4721 (defoptimizer (compile derive-type) ((nameoid function))
4722   (when (csubtypep (lvar-type nameoid)
4723                    (specifier-type 'null))
4724     (values-specifier-type '(values function boolean boolean))))
4725
4726 ;;; FIXME: Maybe also STREAM-ELEMENT-TYPE should be given some loving
4727 ;;; treatment along these lines? (See discussion in COERCE DERIVE-TYPE
4728 ;;; optimizer, above).
4729 (defoptimizer (array-element-type derive-type) ((array))
4730   (let ((array-type (lvar-type array)))
4731     (labels ((consify (list)
4732               (if (endp list)
4733                   '(eql nil)
4734                   `(cons (eql ,(car list)) ,(consify (rest list)))))
4735             (get-element-type (a)
4736               (let ((element-type
4737                      (type-specifier (array-type-specialized-element-type a))))
4738                 (cond ((eq element-type '*)
4739                        (specifier-type 'type-specifier))
4740                       ((symbolp element-type)
4741                        (make-member-type :members (list element-type)))
4742                       ((consp element-type)
4743                        (specifier-type (consify element-type)))
4744                       (t
4745                        (error "can't understand type ~S~%" element-type))))))
4746       (labels ((recurse (type)
4747                   (cond ((array-type-p type)
4748                          (get-element-type type))
4749                         ((union-type-p type)
4750                          (apply #'type-union
4751                                 (mapcar #'recurse (union-type-types type))))
4752                         (t
4753                          *universal-type*))))
4754         (recurse array-type)))))
4755
4756 (define-source-transform sb!impl::sort-vector (vector start end predicate key)
4757   ;; Like CMU CL, we use HEAPSORT. However, other than that, this code
4758   ;; isn't really related to the CMU CL code, since instead of trying
4759   ;; to generalize the CMU CL code to allow START and END values, this
4760   ;; code has been written from scratch following Chapter 7 of
4761   ;; _Introduction to Algorithms_ by Corman, Rivest, and Shamir.
4762   `(macrolet ((%index (x) `(truly-the index ,x))
4763               (%parent (i) `(ash ,i -1))
4764               (%left (i) `(%index (ash ,i 1)))
4765               (%right (i) `(%index (1+ (ash ,i 1))))
4766               (%heapify (i)
4767                `(do* ((i ,i)
4768                       (left (%left i) (%left i)))
4769                  ((> left current-heap-size))
4770                  (declare (type index i left))
4771                  (let* ((i-elt (%elt i))
4772                         (i-key (funcall keyfun i-elt))
4773                         (left-elt (%elt left))
4774                         (left-key (funcall keyfun left-elt)))
4775                    (multiple-value-bind (large large-elt large-key)
4776                        (if (funcall ,',predicate i-key left-key)
4777                            (values left left-elt left-key)
4778                            (values i i-elt i-key))
4779                      (let ((right (%right i)))
4780                        (multiple-value-bind (largest largest-elt)
4781                            (if (> right current-heap-size)
4782                                (values large large-elt)
4783                                (let* ((right-elt (%elt right))
4784                                       (right-key (funcall keyfun right-elt)))
4785                                  (if (funcall ,',predicate large-key right-key)
4786                                      (values right right-elt)
4787                                      (values large large-elt))))
4788                          (cond ((= largest i)
4789                                 (return))
4790                                (t
4791                                 (setf (%elt i) largest-elt
4792                                       (%elt largest) i-elt
4793                                       i largest)))))))))
4794               (%sort-vector (keyfun &optional (vtype 'vector))
4795                `(macrolet (;; KLUDGE: In SBCL ca. 0.6.10, I had
4796                            ;; trouble getting type inference to
4797                            ;; propagate all the way through this
4798                            ;; tangled mess of inlining. The TRULY-THE
4799                            ;; here works around that. -- WHN
4800                            (%elt (i)
4801                             `(aref (truly-the ,',vtype ,',',vector)
4802                               (%index (+ (%index ,i) start-1)))))
4803                  (let (;; Heaps prefer 1-based addressing.
4804                        (start-1 (1- ,',start))
4805                        (current-heap-size (- ,',end ,',start))
4806                        (keyfun ,keyfun))
4807                    (declare (type (integer -1 #.(1- sb!xc:most-positive-fixnum))
4808                                   start-1))
4809                    (declare (type index current-heap-size))
4810                    (declare (type function keyfun))
4811                    (loop for i of-type index
4812                          from (ash current-heap-size -1) downto 1 do
4813                          (%heapify i))
4814                    (loop
4815                     (when (< current-heap-size 2)
4816                       (return))
4817                     (rotatef (%elt 1) (%elt current-heap-size))
4818                     (decf current-heap-size)
4819                     (%heapify 1))))))
4820     (if (typep ,vector 'simple-vector)
4821         ;; (VECTOR T) is worth optimizing for, and SIMPLE-VECTOR is
4822         ;; what we get from (VECTOR T) inside WITH-ARRAY-DATA.
4823         (if (null ,key)
4824             ;; Special-casing the KEY=NIL case lets us avoid some
4825             ;; function calls.
4826             (%sort-vector #'identity simple-vector)
4827             (%sort-vector ,key simple-vector))
4828         ;; It's hard to anticipate many speed-critical applications for
4829         ;; sorting vector types other than (VECTOR T), so we just lump
4830         ;; them all together in one slow dynamically typed mess.
4831         (locally
4832           (declare (optimize (speed 2) (space 2) (inhibit-warnings 3)))
4833           (%sort-vector (or ,key #'identity))))))
4834 \f
4835 ;;;; debuggers' little helpers
4836
4837 ;;; for debugging when transforms are behaving mysteriously,
4838 ;;; e.g. when debugging a problem with an ASH transform
4839 ;;;   (defun foo (&optional s)
4840 ;;;     (sb-c::/report-lvar s "S outside WHEN")
4841 ;;;     (when (and (integerp s) (> s 3))
4842 ;;;       (sb-c::/report-lvar s "S inside WHEN")
4843 ;;;       (let ((bound (ash 1 (1- s))))
4844 ;;;         (sb-c::/report-lvar bound "BOUND")
4845 ;;;         (let ((x (- bound))
4846 ;;;               (y (1- bound)))
4847 ;;;           (sb-c::/report-lvar x "X")
4848 ;;;           (sb-c::/report-lvar x "Y"))
4849 ;;;         `(integer ,(- bound) ,(1- bound)))))
4850 ;;; (The DEFTRANSFORM doesn't do anything but report at compile time,
4851 ;;; and the function doesn't do anything at all.)
4852 #!+sb-show
4853 (progn
4854   (defknown /report-lvar (t t) null)
4855   (deftransform /report-lvar ((x message) (t t))
4856     (format t "~%/in /REPORT-LVAR~%")
4857     (format t "/(LVAR-TYPE X)=~S~%" (lvar-type x))
4858     (when (constant-lvar-p x)
4859       (format t "/(LVAR-VALUE X)=~S~%" (lvar-value x)))
4860     (format t "/MESSAGE=~S~%" (lvar-value message))
4861     (give-up-ir1-transform "not a real transform"))
4862   (defun /report-lvar (x message)
4863     (declare (ignore x message))))
4864
4865 \f
4866 ;;;; Transforms for internal compiler utilities
4867
4868 ;;; If QUALITY-NAME is constant and a valid name, don't bother
4869 ;;; checking that it's still valid at run-time.
4870 (deftransform policy-quality ((policy quality-name)
4871                               (t symbol))
4872   (unless (and (constant-lvar-p quality-name)
4873                (policy-quality-name-p (lvar-value quality-name)))
4874     (give-up-ir1-transform))
4875   '(%policy-quality policy quality-name))
4876 \f
4877 (deftransform encode-universal-time
4878     ((second minute hour date month year &optional time-zone)
4879      ((constant-arg (mod 60)) (constant-arg (mod 60))
4880       (constant-arg (mod 24))
4881       (constant-arg (integer 1 31))
4882       (constant-arg (integer 1 12))
4883       (constant-arg (integer 1899))
4884       (constant-arg (rational -24 24))))
4885   (let ((second (lvar-value second))
4886         (minute (lvar-value minute))
4887         (hour (lvar-value hour))
4888         (date (lvar-value date))
4889         (month (lvar-value month))
4890         (year (lvar-value year))
4891         (time-zone (lvar-value time-zone)))
4892     (if (zerop (rem time-zone 1/3600))
4893         (encode-universal-time second minute hour date month year time-zone)
4894         (give-up-ir1-transform))))
4895
4896 #!-(and win32 (not sb-thread))
4897 (deftransform sleep ((seconds) ((integer 0 #.(expt 10 8))))
4898   `(sb!unix:nanosleep seconds 0))
4899
4900 #!-(and win32 (not sb-thread))
4901 (deftransform sleep ((seconds) ((constant-arg (real 0))))
4902   (let ((seconds-value (lvar-value seconds)))
4903     (multiple-value-bind (seconds nano)
4904         (sb!impl::split-seconds-for-sleep seconds-value)
4905       (if (> seconds (expt 10 8))
4906           (give-up-ir1-transform)
4907           `(sb!unix:nanosleep ,seconds ,nano)))))