1.0.28.57: cross compiler is able to reason about host complexes
[sbcl.git] / tests / compiler.pure.lisp
index e68cfe0..db2bfc4 100644 (file)
 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
 ;;;; more information.
 
 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
 ;;;; more information.
 
+(cl:in-package :sb-c)
+
+(defknown compiler-derived-type (t) (values t t) (movable flushable unsafe))
+
+(deftransform compiler-derived-type ((x))
+ `(values ',(type-specifier (lvar-type x)) t))
+
+(defun compiler-derived-type (x)
+  (values t nil))
+
 (cl:in-package :cl-user)
 
 (cl:in-package :cl-user)
 
+;; The tests in this file assume that EVAL will use the compiler
+(when (eq sb-ext:*evaluator-mode* :interpret)
+  (invoke-restart 'run-tests::skip-file))
+
 ;;; Exercise a compiler bug (by crashing the compiler).
 ;;;
 ;;; This test code is from Douglas Crosher's simplified TICKLE-BUG
 ;;; Exercise a compiler bug (by crashing the compiler).
 ;;;
 ;;; This test code is from Douglas Crosher's simplified TICKLE-BUG
 ;;; Moellmann: CONVERT-MORE-CALL failed on the following call
 (assert (eq (eval '((lambda (&key) 'u) :allow-other-keys nil)) 'u))
 
 ;;; Moellmann: CONVERT-MORE-CALL failed on the following call
 (assert (eq (eval '((lambda (&key) 'u) :allow-other-keys nil)) 'u))
 
-(raises-error? (multiple-value-bind (a b c)
-                   (eval '(truncate 3 4))
-                 (declare (integer c))
-                 (list a b c))
-               type-error)
+(assert
+ (raises-error? (multiple-value-bind (a b c)
+                    (eval '(truncate 3 4))
+                  (declare (integer c))
+                  (list a b c))
+                type-error))
 
 (assert (equal (multiple-value-list (the (values &rest integer)
                                       (eval '(values 3))))
 
 (assert (equal (multiple-value-list (the (values &rest integer)
                                       (eval '(values 3))))
     (funcall f y 1)
     (assert (equal y #*10))))
 
     (funcall f y 1)
     (assert (equal y #*10))))
 
+;;; use of declared array types
 (handler-bind ((sb-ext:compiler-note #'error))
   (compile nil '(lambda (x)
 (handler-bind ((sb-ext:compiler-note #'error))
   (compile nil '(lambda (x)
-                 (declare (type (simple-array (simple-string 3) (5)) x))
+                 (declare (type (simple-array (simple-string 3) (5)) x)
+                          (optimize speed))
                  (aref (aref x 0) 0))))
 
                  (aref (aref x 0) 0))))
 
+(handler-bind ((sb-ext:compiler-note #'error))
+  (compile nil '(lambda (x)
+                 (declare (type (simple-array (simple-array bit (10)) (10)) x)
+                          (optimize speed))
+                 (1+ (aref (aref x 0) 0)))))
+
 ;;; compiler failure
 (let ((f (compile nil '(lambda (x) (typep x '(not (member 0d0)))))))
   (assert (funcall f 1d0)))
 ;;; compiler failure
 (let ((f (compile nil '(lambda (x) (typep x '(not (member 0d0)))))))
   (assert (funcall f 1d0)))
                          (declare (type (integer 4303063 101130078) a))
                          (mask-field (byte 18 2) (ash a 77))))
               57132532)))
                          (declare (type (integer 4303063 101130078) a))
                          (mask-field (byte 18 2) (ash a 77))))
               57132532)))
+;;; rewrite the test case to get the unsigned-byte 32/64
+;;; implementation even after implementing some modular arithmetic
+;;; with signed-byte 30:
+(assert (= 0 (funcall
+              (compile nil
+                       '(lambda (a)
+                         (declare (type (integer 4303063 101130078) a))
+                         (mask-field (byte 30 2) (ash a 77))))
+              57132532)))
+(assert (= 0 (funcall
+              (compile nil
+                       '(lambda (a)
+                         (declare (type (integer 4303063 101130078) a))
+                         (mask-field (byte 64 2) (ash a 77))))
+              57132532)))
+;;; and a similar test case for the signed masking extension (not the
+;;; final interface, so change the call when necessary):
+(assert (= 0 (funcall
+              (compile nil
+                       '(lambda (a)
+                         (declare (type (integer 4303063 101130078) a))
+                         (sb-c::mask-signed-field 30 (ash a 77))))
+              57132532)))
+(assert (= 0 (funcall
+              (compile nil
+                       '(lambda (a)
+                         (declare (type (integer 4303063 101130078) a))
+                         (sb-c::mask-signed-field 61 (ash a 77))))
+              57132532)))
 
 ;;; MISC.101 and MISC.103: FLUSH-DEST did not mark the USE's block for
 ;;; type check regeneration
 
 ;;; MISC.101 and MISC.103: FLUSH-DEST did not mark the USE's block for
 ;;; type check regeneration
 (handler-case (compile nil '(lambda (x)
                              (declare (optimize (speed 3) (safety 0)))
                              (the double-float (sqrt (the double-float x)))))
 (handler-case (compile nil '(lambda (x)
                              (declare (optimize (speed 3) (safety 0)))
                              (the double-float (sqrt (the double-float x)))))
-  (sb-ext:compiler-note ()
-    (error "Compiler does not trust result type assertion.")))
+  (sb-ext:compiler-note (c)
+    ;; Ignore the note for the float -> pointer conversion of the
+    ;; return value.
+    (unless (string= (car (last (sb-c::simple-condition-format-arguments c)))
+                     "<return value>")
+      (error "Compiler does not trust result type assertion."))))
 
 (let ((f (compile nil '(lambda (x)
                         (declare (optimize speed (safety 0)))
 
 (let ((f (compile nil '(lambda (x)
                         (declare (optimize speed (safety 0)))
     (compile nil '(lambda (x)
                    (declare (optimize (speed 3)))
                    (1+ x))))
     (compile nil '(lambda (x)
                    (declare (optimize (speed 3)))
                    (1+ x))))
-  ;; forced-to-do GENERIC-+, etc
-  (assert (> count0 0))
+  ;; forced-to-do GENERIC-+, etc, possible word -> bignum conversion note
+  (assert (> count0 1))
   (handler-bind ((sb-ext:compiler-note (lambda (c) (incf count1))))
     (compile nil '(lambda (x)
                    (declare (optimize (speed 3)))
                    (check-type x fixnum)
                    (1+ x))))
   (handler-bind ((sb-ext:compiler-note (lambda (c) (incf count1))))
     (compile nil '(lambda (x)
                    (declare (optimize (speed 3)))
                    (check-type x fixnum)
                    (1+ x))))
-  (assert (= count1 0)))
+  ;; Only the posssible word -> bignum conversion note
+  (assert (= count1 1)))
 
 ;;; Up to 0.9.8.22 x86-64 had broken return value handling in the
 ;;; %SET-SAP-REF-DOUBLE/SINGLE VOPs.
 
 ;;; Up to 0.9.8.22 x86-64 had broken return value handling in the
 ;;; %SET-SAP-REF-DOUBLE/SINGLE VOPs.
                                              (bit #*1001101001001
                                                   (min 12 (max 0 lv3))))))))))))
 
                                              (bit #*1001101001001
                                                   (min 12 (max 0 lv3))))))))))))
 
-;;; MISC.624: erronous AVER in x86's %LOGBITP VOPs
+;;; MISC.624: erroneous AVER in x86's %LOGBITP VOPs
 (assert (eql 0
              (funcall
               (compile
                nil
                '(lambda (a)
                  (declare (type (integer 21 28) a))
 (assert (eql 0
              (funcall
               (compile
                nil
                '(lambda (a)
                  (declare (type (integer 21 28) a))
-                 (declare      (optimize (compilation-speed 1) (safety 2)
+                 (declare       (optimize (compilation-speed 1) (safety 2)
                                  (speed 0) (debug 0) (space 1)))
                  (let* ((v7 (flet ((%f3 (f3-1 f3-2)
                                      (loop for lv2 below 1
                                  (speed 0) (debug 0) (space 1)))
                  (let* ((v7 (flet ((%f3 (f3-1 f3-2)
                                      (loop for lv2 below 1
 
 ;;; MISC.626: bandaged AVER was still wrong
 (assert (eql -829253
 
 ;;; MISC.626: bandaged AVER was still wrong
 (assert (eql -829253
-            (funcall
-             (compile
-              nil
-              '(lambda (a)
-                 (declare (type (integer -902970 2) a))
-                 (declare (optimize (space 2) (debug 0) (compilation-speed 1)
-                                    (speed 0) (safety 3)))
-                 (prog2 (if (logbitp 30 a) 0 (block b3 0)) a)))
-             -829253)))
+             (funcall
+              (compile
+               nil
+               '(lambda (a)
+                  (declare (type (integer -902970 2) a))
+                  (declare (optimize (space 2) (debug 0) (compilation-speed 1)
+                                     (speed 0) (safety 3)))
+                  (prog2 (if (logbitp 30 a) 0 (block b3 0)) a)))
+              -829253)))
 
 ;; MISC.628: constant-folding %LOGBITP was buggy
 (assert (eql t
 
 ;; MISC.628: constant-folding %LOGBITP was buggy
 (assert (eql t
-            (funcall
-             (compile
-              nil
-              '(lambda ()
-                 (declare (optimize (safety 3) (space 3) (compilation-speed 3)
-                                    (speed 0) (debug 1)))
-                 (not (not (logbitp 0 (floor 2147483651 (min -23 0))))))))))
+             (funcall
+              (compile
+               nil
+               '(lambda ()
+                  (declare (optimize (safety 3) (space 3) (compilation-speed 3)
+                                     (speed 0) (debug 1)))
+                  (not (not (logbitp 0 (floor 2147483651 (min -23 0))))))))))
+
+;; mistyping found by random-tester
+(assert (zerop
+  (funcall
+   (compile
+    nil
+    '(lambda ()
+      (declare (optimize (speed 1) (debug 0)
+                (space 2) (safety 0) (compilation-speed 0)))
+      (unwind-protect 0
+        (* (/ (multiple-value-prog1 -29457482 -5602513511) 1))))))))
+
+;; aggressive constant folding (bug #400)
+(assert
+ (eq t (funcall (compile nil '(lambda () (or t (the integer (/ 1 0))))))))
+
+(with-test (:name (:compiler :constraint-propagation :var-eql-to-non-var-1))
+  (assert
+   (handler-case
+       (compile nil '(lambda (x y)
+                       (when (eql x (length y))
+                         (locally
+                             (declare (optimize (speed 3)))
+                           (1+ x)))))
+     (compiler-note () (error "The code is not optimized.")))))
+
+(with-test (:name (:compiler :constraint-propagation :var-eql-to-non-var-2))
+  (assert
+   (handler-case
+       (compile nil '(lambda (x y)
+                       (when (eql (length y) x)
+                         (locally
+                             (declare (optimize (speed 3)))
+                           (1+ x)))))
+     (compiler-note () (error "The code is not optimized.")))))
+
+(with-test (:name (:compiler :constraint-propagation :float-bounds-1))
+  (handler-case
+      (compile nil '(lambda (x)
+                      (declare (type (single-float * (3.0)) x))
+                      (when (<= x 2.0)
+                        (when (<= 2.0 x)
+                          x))))
+    (compiler-note () (error "Deleted reachable code."))))
+
+(with-test (:name (:compiler :constraint-propagation :float-bounds-2))
+  (catch :note
+    (handler-case
+        (compile nil '(lambda (x)
+                        (declare (type single-float x))
+                        (when (< 1.0 x)
+                          (when (<= x 1.0)
+                            (error "This is unreachable.")))))
+      (compiler-note () (throw :note nil)))
+    (error "Unreachable code undetected.")))
+
+(with-test (:name (:compiler :constraint-propagation :var-eql-to-var-1))
+  (catch :note
+    (handler-case
+        (compile nil '(lambda (x y)
+                        (when (typep y 'fixnum)
+                          (when (eql x y)
+                            (unless (typep x 'fixnum)
+                              (error "This is unreachable"))
+                            (setq y nil)))))
+      (compiler-note () (throw :note nil)))
+    (error "Unreachable code undetected.")))
+
+(with-test (:name (:compiler :constraint-propagation :var-eql-to-var-2))
+  (catch :note
+    (handler-case
+        (compile nil '(lambda (x y)
+                        (when (typep y 'fixnum)
+                          (when (eql y x)
+                            (unless (typep x 'fixnum)
+                              (error "This is unreachable"))
+                            (setq y nil)))))
+      (compiler-note () (throw :note nil)))
+    (error "Unreachable code undetected.")))
+
+;; Reported by John Wiseman, sbcl-devel
+;; Subject: [Sbcl-devel] float type derivation bug?
+;; Date: Tue, 4 Apr 2006 15:28:15 -0700
+(with-test (:name (:type-derivation :float-bounds))
+  (compile nil '(lambda (bits)
+                 (let* ((s (if (= (ash bits -31) 0) 1 -1))
+                        (e (logand (ash bits -23) #xff))
+                        (m (if (= e 0)
+                               (ash (logand bits #x7fffff) 1)
+                               (logior (logand bits #x7fffff) #x800000))))
+                   (float (* s m (expt 2 (- e 150))))))))
+
+;; Reported by James Knight
+;; Subject: [Sbcl-devel] AVER: "(EQ (SB-NAME (SC-SB (TN-SC TN))) 'REGISTERS)"
+;; Date: Fri, 24 Mar 2006 19:30:00 -0500
+(with-test (:name :logbitp-vop)
+  (compile nil
+           '(lambda (days shift)
+             (declare (type fixnum shift days))
+             (let* ((result 0)
+                    (canonicalized-shift (+ shift 1))
+                    (first-wrapping-day (- 1 canonicalized-shift)))
+               (declare (type fixnum result))
+               (dotimes (source-day 7)
+                 (declare (type (integer 0 6) source-day))
+                 (when (logbitp source-day days)
+                   (setf result
+                         (logior result
+                                 (the fixnum
+                                   (if (< source-day first-wrapping-day)
+                                       (+ source-day canonicalized-shift)
+                                       (- (+ source-day
+                                             canonicalized-shift) 7)))))))
+               result))))
+
+;;; MISC.637: incorrect delaying of conversion of optional entries
+;;; with hairy constant defaults
+(let ((f '(lambda ()
+  (labels ((%f11 (f11-2 &key key1)
+             (labels ((%f8 (f8-2 &optional (f8-5 (if nil (return-from %f11 0) 0)))
+                        :bad1))
+               (%f8 (%f8 0)))
+             :bad2))
+    :good))))
+  (assert (eq (funcall (compile nil f)) :good)))
+
+;;; MISC.555: new reference to an already-optimized local function
+(let* ((l '(lambda (p1)
+    (declare (optimize (speed 1) (safety 2) (debug 2) (space 0)) (type keyword p1))
+    (keywordp p1)))
+       (f (compile nil l)))
+  (assert (funcall f :good))
+  (assert (nth-value 1 (ignore-errors (funcall f 42)))))
+
+;;; Check that the compiler doesn't munge *RANDOM-STATE*.
+(let* ((state (make-random-state))
+       (*random-state* (make-random-state state))
+       (a (random most-positive-fixnum)))
+  (setf *random-state* state)
+  (compile nil `(lambda (x a)
+                  (declare (single-float x)
+                           (type (simple-array double-float) a))
+                  (+ (loop for i across a
+                           summing i)
+                     x)))
+  (assert (= a (random most-positive-fixnum))))
+
+;;; MISC.641: LET-conversion after physical environment analysis lost NLX-INFOs
+(let ((form '(lambda ()
+              (declare (optimize (speed 1) (space 0) (debug 2)
+                           (compilation-speed 0) (safety 1)))
+              (flet ((%f3 (f3-1 &key (key1 (count (floor 0 (min -74 0)) #())))
+                          0))
+                   (apply #'%f3 0 nil)))))
+  (assert (zerop (funcall (compile nil form)))))
+
+;;;  size mismatch: #<SB-VM::EA :DWORD base=#<SB-C:TN t1[RDX]> disp=1> is a :DWORD and #<SB-C:TN t2[RAX]> is a :QWORD. on x86-64
+(compile nil '(lambda ()
+               (let ((x (make-array '(1) :element-type '(signed-byte 32))))
+                 (setf (aref x 0) 1))))
+
+;;; step instrumentation confusing the compiler, reported by Faré
+(handler-bind ((warning #'error))
+  (compile nil '(lambda ()
+                 (declare (optimize (debug 2))) ; not debug 3!
+                 (let ((val "foobar"))
+                   (map-into (make-array (list (length val))
+                                         :element-type '(unsigned-byte 8))
+                             #'char-code val)))))
+
+;;; overconfident primitive type computation leading to bogus type
+;;; checking.
+(let* ((form1 '(lambda (x)
+                (declare (type (and condition function) x))
+                x))
+       (fun1 (compile nil form1))
+       (form2 '(lambda (x)
+                (declare (type (and standard-object function) x))
+                x))
+       (fun2 (compile nil form2)))
+  (assert (raises-error? (funcall fun1 (make-condition 'error))))
+  (assert (raises-error? (funcall fun1 fun1)))
+  (assert (raises-error? (funcall fun2 fun2)))
+  (assert (eq (funcall fun2 #'print-object) #'print-object)))
+
+;;; LET* + VALUES declaration: while the declaration is a non-standard
+;;; and possibly a non-conforming extension, as long as we do support
+;;; it, we might as well get it right.
+;;;
+;;; Bug reported by Kaersten Poeck on sbcl-devel 20061023.
+(compile nil '(lambda () (let* () (declare (values list)))))
+
+
+;;; test for some problems with too large immediates in x86-64 modular
+;;; arithmetic vops
+(compile nil '(lambda (x) (declare (fixnum x))
+               (logand most-positive-fixnum (logxor x most-positive-fixnum))))
+
+(compile nil '(lambda (x) (declare (fixnum x))
+               (logand most-positive-fixnum (+ x most-positive-fixnum))))
+
+(compile nil '(lambda (x) (declare (fixnum x))
+               (logand most-positive-fixnum (* x most-positive-fixnum))))
+
+;;; bug 256.b
+(assert (let (warned-p)
+            (handler-bind ((warning (lambda (w) (setf warned-p t))))
+              (compile nil
+                         '(lambda (x)
+                           (list (let ((y (the real x)))
+                                   (unless (floatp y) (error ""))
+                                   y)
+                                 (integer-length x)))))
+            warned-p))
+
+;; Dead / in safe code
+(with-test (:name :safe-dead-/)
+  (assert (eq :error
+              (handler-case
+                  (funcall (compile nil
+                                    '(lambda (x y)
+                                      (declare (optimize (safety 3)))
+                                      (/ x y)
+                                      (+ x y)))
+                           1
+                           0)
+                (division-by-zero ()
+                  :error)))))
+
+;;; Dead unbound variable (bug 412)
+(with-test (:name :dead-unbound)
+  (assert (eq :error
+              (handler-case
+                  (funcall (compile nil
+                                    '(lambda ()
+                                      #:unbound
+                                      42)))
+                (unbound-variable ()
+                  :error)))))
+
+;;; No compiler notes from compiling SUBSEQ SIMPLE-VECTOR.
+(handler-bind ((sb-ext:compiler-note 'error))
+  (assert
+   (equalp #(2 3)
+           (funcall (compile nil `(lambda (s p e)
+                                    (declare (optimize speed)
+                                             (simple-vector s))
+                                    (subseq s p e)))
+                    (vector 1 2 3 4)
+                    1
+                    3))))
+
+;;; No compiler notes from compiling COPY-SEQ SIMPLE-VECTOR.
+(handler-bind ((sb-ext:compiler-note 'error))
+  (assert
+   (equalp #(1 2 3 4)
+           (funcall (compile nil `(lambda (s)
+                                    (declare (optimize speed)
+                                             (simple-vector s))
+                                    (copy-seq s)))
+                    (vector 1 2 3 4)))))
+
+;;; bug in adding DATA-VECTOR-REF-WITH-OFFSET to x86-64
+(assert (not (mismatch #(1.0f0 2.0f0) (make-array 2 :element-type 'single-float :initial-contents (list 1.0f0 2.0f0)))))
+
+;;; bug in interval-arithmetic used by the compiler: needless attempt to coerce too
+;;; large bignums to floats
+(dolist (op '(* / + -))
+  (let ((fun (compile
+              nil
+              `(lambda (x)
+                 (declare (type (integer 0 #.(* 2 (truncate most-positive-double-float))) x))
+                 (,op 0.0d0 x)))))
+    (loop repeat 10
+          do (let ((arg (random (truncate most-positive-double-float))))
+               (assert (eql (funcall fun arg)
+                            (funcall op 0.0d0 arg)))))))
+
+(with-test (:name :high-debug-known-function-inlining)
+  (let ((fun (compile nil
+                      '(lambda ()
+                        (declare (optimize (debug 3)) (inline append))
+                        (let ((fun (lambda (body)
+                                     (append
+                                      (first body)
+                                      nil))))
+                          (funcall fun
+                                   '((foo (bar)))))))))
+    (funcall fun)))
+
+(with-test (:name :high-debug-known-function-transform-with-optional-arguments)
+  (compile nil '(lambda (x y)
+               (declare (optimize sb-c::preserve-single-use-debug-variables))
+               (if (block nil
+                     (some-unknown-function
+                      (lambda ()
+                        (return (member x y))))
+                     t)
+                   t
+                   (error "~a" y)))))
+
+;;; Compiling W-P-O when the pinned objects are known to be fixnums
+;;; or characters.
+(compile nil '(lambda (x y)
+               (declare (fixnum y) (character x))
+               (sb-sys:with-pinned-objects (x y)
+                 (some-random-function))))
+
+;;; *CHECK-CONSISTENCY* and TRULY-THE
+
+(with-test (:name :bug-423)
+  (let ((sb-c::*check-consistency* t))
+    (handler-bind ((warning #'error))
+      (flet ((make-lambda (type)
+               `(lambda (x)
+                  ((lambda (z)
+                     (if (listp z)
+                         (let ((q (truly-the list z)))
+                           (length q))
+                         (if (arrayp z)
+                             (let ((q (truly-the vector z)))
+                               (length q))
+                             (error "oops"))))
+                   (the ,type x)))))
+        (compile nil (make-lambda 'list))
+        (compile nil (make-lambda 'vector))))))
+
+;;; this caused a momentary regression when an ill-adviced fix to
+;;; bug 427 made ANY-REG suitable for primitive-type T:
+;;;
+;;; no :MOVE-ARG VOP defined to move #<SB-C:TN t1> (SC SB-VM::SINGLE-REG) to #<SB-C:TN t2> (SC SB-VM::ANY-REG)
+;;;    [Condition of type SIMPLE-ERROR]
+(compile nil
+         '(lambda (frob)
+           (labels
+               ((%zig (frob)
+                  (typecase frob
+                    (double-float
+                     (setf (sb-alien:deref (sb-alien:cast (sb-alien:sap-alien (unknown1) (* unsigned-char))
+                                                          (* double-float))) frob))
+                    (hash-table
+                     (%zig (the (values (single-float (0.0) 1.0) &optional) (unknown2)))
+                     nil))))
+             (%zig))))
+
+;;; non-required arguments in HANDLER-BIND
+(assert (eq :oops (car (funcall (compile nil
+                                         '(lambda (x)
+                                           (block nil
+                                             (handler-bind ((error (lambda (&rest args) (return (cons :oops args)))))
+                                               (/ 2 x)))))
+                                0))))
+
+;;; NIL is a legal function name
+(assert (eq 'a (flet ((nil () 'a)) (nil))))
+
+;;; misc.528
+(assert (null (let* ((x 296.3066f0)
+                     (y 22717067)
+                     (form `(lambda (r p2)
+                              (declare (optimize speed (safety 1))
+                                       (type (simple-array single-float nil) r)
+                                       (type (integer -9369756340 22717335) p2))
+                              (setf (aref r) (* ,x (the (eql 22717067) p2)))
+                           (values)))
+                     (r (make-array nil :element-type 'single-float))
+                     (expected (* x y)))
+                (funcall (compile nil form) r y)
+                (let ((actual (aref r)))
+                  (unless (eql expected actual)
+                    (list expected actual))))))
+;;; misc.529
+(assert (null (let* ((x -2367.3296f0)
+                     (y 46790178)
+                     (form `(lambda (r p2)
+                              (declare (optimize speed (safety 1))
+                                       (type (simple-array single-float nil) r)
+                                       (type (eql 46790178) p2))
+                              (setf (aref r) (+ ,x (the (integer 45893897) p2)))
+                              (values)))
+                     (r (make-array nil :element-type 'single-float))
+                     (expected (+ x y)))
+                (funcall (compile nil form) r y)
+                (let ((actual (aref r)))
+                  (unless (eql expected actual)
+                    (list expected actual))))))
+
+;;; misc.556
+(assert (eql -1
+             (funcall
+              (compile nil '(lambda (p1 p2)
+                             (declare
+                              (optimize (speed 1) (safety 0)
+                               (debug 0) (space 0))
+                              (type (member 8174.8604) p1)
+                              (type (member -95195347) p2))
+                             (floor p1 p2)))
+              8174.8604 -95195347)))
+
+;;; misc.557
+(assert (eql -1
+             (funcall
+              (compile
+               nil
+               '(lambda (p1)
+                 (declare (optimize (speed 3) (safety 0) (debug 3) (space 1))
+                  (type (member -94430.086f0) p1))
+                 (floor (the single-float p1) 19311235)))
+              -94430.086f0)))
+
+;;; misc.558
+(assert (eql -1.0f0
+             (funcall
+              (compile
+               nil
+               '(lambda (p1)
+                 (declare (optimize (speed 1) (safety 2)
+                           (debug 2) (space 3))
+                  (type (eql -39466.56f0) p1))
+                 (ffloor p1 305598613)))
+              -39466.56f0)))
+
+;;; misc.559
+(assert (eql 1
+             (funcall
+              (compile
+               nil
+               '(lambda (p1)
+                 (declare (optimize (speed 1) (safety 1) (debug 1) (space 2))
+                  (type (eql -83232.09f0) p1))
+                 (ceiling p1 -83381228)))
+              -83232.09f0)))
+
+;;; misc.560
+(assert (eql 1
+             (funcall
+              (compile
+               nil
+               '(lambda (p1)
+                 (declare (optimize (speed 1) (safety 1)
+                           (debug 1) (space 0))
+                  (type (member -66414.414f0) p1))
+                 (ceiling p1 -63019173f0)))
+              -66414.414f0)))
+
+;;; misc.561
+(assert (eql 1.0f0
+             (funcall
+              (compile
+               nil
+               '(lambda (p1)
+                 (declare (optimize (speed 0) (safety 1)
+                           (debug 0) (space 1))
+                  (type (eql 20851.398f0) p1))
+                 (fceiling p1 80839863)))
+              20851.398f0)))
+
+;;; misc.581
+(assert (floatp
+         (funcall
+          (compile nil '(lambda (x)
+                         (declare (type (eql -5067.2056) x))
+                         (+ 213734822 x)))
+          -5067.2056)))
+
+;;; misc.581a
+(assert (typep
+         (funcall
+          (compile nil '(lambda (x) (declare (type (eql -1.0) x))
+                         (+ #x1000001 x)))
+          -1.0f0)
+         'single-float))
+
+;;; misc.582
+(assert (plusp (funcall
+                (compile
+                 nil
+                 ' (lambda (p1)
+                     (declare (optimize (speed 0) (safety 1) (debug 1) (space 1))
+                              (type (eql -39887.645) p1))
+                     (mod p1 382352925)))
+              -39887.645)))
+
+;;; misc.587
+(assert (let ((result (funcall
+                       (compile
+                        nil
+                        '(lambda (p2)
+                          (declare (optimize (speed 0) (safety 3) (debug 1) (space 0))
+                           (type (eql 33558541) p2))
+                          (- 92215.266 p2)))
+                       33558541)))
+          (typep result 'single-float)))
+
+;;; misc.635
+(assert (eql 1
+             (let* ((form '(lambda (p2)
+                            (declare (optimize (speed 0) (safety 1)
+                                      (debug 2) (space 2))
+                             (type (member -19261719) p2))
+                            (ceiling -46022.094 p2))))
+               (values (funcall (compile nil form) -19261719)))))
+
+;;; misc.636
+(assert (let* ((x 26899.875)
+               (form `(lambda (p2)
+                        (declare (optimize (speed 3) (safety 1) (debug 3) (space 1))
+                                 (type (member ,x #:g5437 char-code #:g5438) p2))
+                        (* 104102267 p2))))
+          (floatp (funcall (compile nil form) x))))
+
+;;; misc.622
+(assert (eql
+         (funcall
+           (compile
+            nil
+            '(lambda (p2)
+              (declare (optimize (speed 3) (safety 2) (debug 3) (space 0))
+               (type real p2))
+              (+ 81535869 (the (member 17549.955 #:g35917) p2))))
+           17549.955)
+          (+ 81535869 17549.955)))
+
+;;; misc.654
+(assert (eql 2
+             (let ((form '(lambda (p2)
+                           (declare (optimize (speed 0) (safety 2) (debug 0) (space 2))
+                            (type (member integer eql) p2))
+                           (coerce 2 p2))))
+               (funcall (compile nil form) 'integer))))
+
+;;; misc.656
+(assert (eql 2
+             (let ((form '(lambda (p2)
+                           (declare (optimize (speed 0) (safety 2) (debug 0) (space 2))
+                            (type (member integer mod) p2))
+                           (coerce 2 p2))))
+               (funcall (compile nil form) 'integer))))
+
+;;; misc.657
+(assert (eql 2
+         (let ((form '(lambda (p2)
+                       (declare (optimize (speed 0) (safety 2) (debug 0) (space 2))
+                        (type (member integer values) p2))
+                       (coerce 2 p2))))
+           (funcall (compile nil form) 'integer))))
+
+(with-test (:name :string-aref-type)
+ (assert (eq 'character
+             (funcall (compile nil
+                               '(lambda (s)
+                                 (sb-c::compiler-derived-type (aref (the string s) 0))))
+                      "foo"))))
+
+(with-test (:name :base-string-aref-type)
+ (assert (eq #+sb-unicode 'base-char
+             #-sb-unicode 'character
+             (funcall (compile nil
+                               '(lambda (s)
+                                 (sb-c::compiler-derived-type (aref (the base-string s) 0))))
+                      (coerce "foo" 'base-string)))))
+
+(with-test (:name :dolist-constant-type-derivation)
+  (assert (equal '(integer 1 3)
+                 (funcall (compile nil
+                                   '(lambda (x)
+                                     (dolist (y '(1 2 3))
+                                       (when x
+                                         (return (sb-c::compiler-derived-type y))))))
+                          t))))
+
+(with-test (:name :dolist-simple-list-type-derivation)
+  (assert (equal '(integer 1 3)
+                 (funcall (compile nil
+                                   '(lambda (x)
+                                     (dolist (y (list 1 2 3))
+                                       (when x
+                                         (return (sb-c::compiler-derived-type y))))))
+                          t))))
+
+(with-test (:name :dolist-dotted-constant-list-type-derivation)
+  (let* ((warned nil)
+         (fun (handler-bind ((style-warning (lambda (c) (push c warned))))
+                (compile nil
+                         '(lambda (x)
+                           (dolist (y '(1 2 3 . 4) :foo)
+                             (when x
+                               (return (sb-c::compiler-derived-type y)))))))))
+    (assert (equal '(integer 1 3) (funcall fun t)))
+    (assert (= 1 (length warned)))
+    (multiple-value-bind (res err) (ignore-errors (funcall fun nil))
+      (assert (not res))
+      (assert (typep err 'type-error)))))
+
+(with-test (:name :constant-list-destructuring)
+  (handler-bind ((sb-ext:compiler-note #'error))
+    (progn
+      (assert (= 10
+                 (funcall
+                  (compile nil
+                           '(lambda ()
+                             (destructuring-bind (a (b c) d) '(1 (2 3) 4)
+                               (+ a b c d)))))))
+      (assert (eq :feh
+                  (funcall
+                   (compile nil
+                            '(lambda (x)
+                              (or x
+                               (destructuring-bind (a (b c) d) '(1 "foo" 4)
+                                 (+ a b c d)))))
+                   :feh))))))
+
+;;; Functions with non-required arguments used to end up with
+;;; (&OPTIONAL-DISPATCH ...) as their names.
+(with-test (:name :hairy-function-name)
+  (assert (eq 'read-line (nth-value 2 (function-lambda-expression #'read-line))))
+  (assert (equal "#<FUNCTION READ-LINE>" (princ-to-string #'read-line))))
+
+;;; PROGV + RESTRICT-COMPILER-POLICY
+(with-test (:name :progv-and-restrict-compiler-policy)
+  (let ((sb-c::*policy-restrictions* sb-c::*policy-restrictions*))
+    (restrict-compiler-policy 'debug 3)
+    (let ((fun (compile nil '(lambda (x)
+                              (let ((i x))
+                                (declare (special i))
+                                (list i
+                                      (progv '(i) (list (+ i 1))
+                                        i)
+                                      i))))))
+      (assert (equal '(1 2 1) (funcall fun 1))))))
+
+;;; It used to be possible to confuse the compiler into
+;;; IR2-converting such a call to CONS
+(with-test (:name :late-bound-primitive)
+  (compile nil `(lambda ()
+                  (funcall 'cons 1))))
+
+(with-test (:name :hairy-array-element-type-derivation)
+  (compile nil '(lambda (x)
+                 (declare (type (and simple-string (satisfies array-has-fill-pointer-p)) x))
+                 (array-element-type x))))
+
+(with-test (:name :rest-list-type-derivation)
+  (multiple-value-bind (type derivedp)
+      (funcall (compile nil `(lambda (&rest args)
+                               (sb-c::compiler-derived-type args)))
+               nil)
+    (assert (eq 'list type))
+    (assert derivedp)))
+
+(with-test (:name :base-char-typep-elimination)
+  (assert (eq (funcall (lambda (ch)
+                         (declare (type base-char ch) (optimize (speed 3) (safety 0)))
+                         (typep ch 'base-char))
+                       t)
+              t)))
+
+(with-test (:name :regression-1.0.24.37)
+  (compile nil '(lambda (&key (test (constantly t)))
+                 (when (funcall test)
+                   :quux))))
+
+;;; Attempt to test a decent cross section of conditions
+;;; and values types to move conditionally.
+(macrolet
+    ((test-comparison (comparator type x y)
+       `(progn
+          ,@(loop for (result-type a b)
+                    in '((nil t   nil)
+                         (nil 0   1)
+                         (nil 0.0 1.0)
+                         (nil 0d0 0d0)
+                         (nil 0.0 0d0)
+                         (nil #c(1.0 1.0) #c(2.0 2.0))
+
+                         (t      t  nil)
+                         (fixnum 0 1)
+                         ((unsigned-byte #.sb-vm:n-word-bits)
+                          (1+ most-positive-fixnum)
+                          (+ 2 most-positive-fixnum))
+                         ((signed-byte #.sb-vm:n-word-bits)
+                          -1 (* 2 most-negative-fixnum))
+                         (single-float 0.0 1.0)
+                         (double-float 0d0 1d0))
+                  for lambda = (if result-type
+                                   `(lambda (x y a b)
+                                      (declare (,type x y)
+                                               (,result-type a b))
+                                      (if (,comparator x y)
+                                          a b))
+                                   `(lambda (x y)
+                                      (declare (,type x y))
+                                      (if (,comparator x y)
+                                          ,a ,b)))
+                  for args = `(,x ,y ,@(and result-type
+                                            `(,a ,b)))
+                  collect
+                  `(progn
+                     (eql (funcall (compile nil ',lambda)
+                                   ,@args)
+                          (eval '(,lambda ,@args))))))))
+  (sb-vm::with-float-traps-masked
+      (:divide-by-zero :overflow :inexact :invalid)
+    (let ((sb-ext:*evaluator-mode* :interpret))
+      (declare (sb-ext:muffle-conditions style-warning))
+      (test-comparison eql t t nil)
+      (test-comparison eql t t t)
+
+      (test-comparison =   t 1 0)
+      (test-comparison =   t 1 1)
+      (test-comparison =   t (1+ most-positive-fixnum) (+ 2 most-positive-fixnum))
+      (test-comparison =   fixnum 1 0)
+      (test-comparison =   fixnum 0 0)
+      (test-comparison =   (unsigned-byte #.sb-vm:n-word-bits) 1 0)
+      (test-comparison =   (unsigned-byte #.sb-vm:n-word-bits) 0 0)
+      (test-comparison =   (signed-byte #.sb-vm:n-word-bits)   1 0)
+      (test-comparison =   (signed-byte #.sb-vm:n-word-bits)   1 1)
+
+      (test-comparison =   single-float 0.0 1.0)
+      (test-comparison =   single-float 1.0 1.0)
+      (test-comparison =   single-float (/ 1.0 0.0) (/ 1.0 0.0))
+      (test-comparison =   single-float (/ 1.0 0.0) 1.0)
+      (test-comparison =   single-float (/ 0.0 0.0) (/ 0.0 0.0))
+      (test-comparison =   single-float (/ 0.0 0.0) 0.0)
+
+      (test-comparison =   double-float 0d0 1d0)
+      (test-comparison =   double-float 1d0 1d0)
+      (test-comparison =   double-float (/ 1d0 0d0) (/ 1d0 0d0))
+      (test-comparison =   double-float (/ 1d0 0d0) 1d0)
+      (test-comparison =   double-float (/ 0d0 0d0) (/ 0d0 0d0))
+      (test-comparison =   double-float (/ 0d0 0d0) 0d0)
+
+      (test-comparison <   t 1 0)
+      (test-comparison <   t 0 1)
+      (test-comparison <   t 1 1)
+      (test-comparison <   t (1+ most-positive-fixnum)  (+ 2 most-positive-fixnum))
+      (test-comparison <   t (+ 2 most-positive-fixnum) (1+ most-positive-fixnum))
+      (test-comparison <   fixnum 1 0)
+      (test-comparison <   fixnum 0 1)
+      (test-comparison <   fixnum 0 0)
+      (test-comparison <   (unsigned-byte #.sb-vm:n-word-bits) 1 0)
+      (test-comparison <   (unsigned-byte #.sb-vm:n-word-bits) 0 1)
+      (test-comparison <   (unsigned-byte #.sb-vm:n-word-bits) 0 0)
+      (test-comparison <   (signed-byte #.sb-vm:n-word-bits)   1 0)
+      (test-comparison <   (signed-byte #.sb-vm:n-word-bits)   0 1)
+      (test-comparison <   (signed-byte #.sb-vm:n-word-bits)   1 1)
+
+      (test-comparison <   single-float 0.0 1.0)
+      (test-comparison <   single-float 1.0 0.0)
+      (test-comparison <   single-float 1.0 1.0)
+      (test-comparison <   single-float (/ 1.0 0.0) (/ 1.0 0.0))
+      (test-comparison <   single-float (/ 1.0 0.0) 1.0)
+      (test-comparison <   single-float 1.0 (/ 1.0 0.0))
+      (test-comparison <   single-float (/ 0.0 0.0) (/ 0.0 0.0))
+      (test-comparison <   single-float (/ 0.0 0.0) 0.0)
+
+      (test-comparison <   double-float 0d0 1d0)
+      (test-comparison <   double-float 1d0 0d0)
+      (test-comparison <   double-float 1d0 1d0)
+      (test-comparison <   double-float (/ 1d0 0d0) (/ 1d0 0d0))
+      (test-comparison <   double-float (/ 1d0 0d0) 1d0)
+      (test-comparison <   double-float 1d0 (/ 1d0 0d0))
+      (test-comparison <   double-float (/ 0d0 0d0) (/ 0d0 0d0))
+      (test-comparison <   double-float (/ 0d0 0d0) 0d0)
+      (test-comparison <   double-float 0d0 (/ 0d0 0d0))
+
+      (test-comparison >   t 1 0)
+      (test-comparison >   t 0 1)
+      (test-comparison >   t 1 1)
+      (test-comparison >   t (1+ most-positive-fixnum)  (+ 2 most-positive-fixnum))
+      (test-comparison >   t (+ 2 most-positive-fixnum) (1+ most-positive-fixnum))
+      (test-comparison >   fixnum 1 0)
+      (test-comparison >   fixnum 0 1)
+      (test-comparison >   fixnum 0 0)
+      (test-comparison >   (unsigned-byte #.sb-vm:n-word-bits) 1 0)
+      (test-comparison >   (unsigned-byte #.sb-vm:n-word-bits) 0 1)
+      (test-comparison >   (unsigned-byte #.sb-vm:n-word-bits) 0 0)
+      (test-comparison >   (signed-byte #.sb-vm:n-word-bits)   1 0)
+      (test-comparison >   (signed-byte #.sb-vm:n-word-bits)   0 1)
+      (test-comparison >   (signed-byte #.sb-vm:n-word-bits)   1 1)
+
+      (test-comparison >   single-float 0.0 1.0)
+      (test-comparison >   single-float 1.0 0.0)
+      (test-comparison >   single-float 1.0 1.0)
+      (test-comparison >   single-float (/ 1.0 0.0) (/ 1.0 0.0))
+      (test-comparison >   single-float (/ 1.0 0.0) 1.0)
+      (test-comparison >   single-float 1.0 (/ 1.0 0.0))
+      (test-comparison >   single-float (/ 0.0 0.0) (/ 0.0 0.0))
+      (test-comparison >   single-float (/ 0.0 0.0) 0.0)
+
+      (test-comparison >   double-float 0d0 1d0)
+      (test-comparison >   double-float 1d0 0d0)
+      (test-comparison >   double-float 1d0 1d0)
+      (test-comparison >   double-float (/ 1d0 0d0) (/ 1d0 0d0))
+      (test-comparison >   double-float (/ 1d0 0d0) 1d0)
+      (test-comparison >   double-float 1d0 (/ 1d0 0d0))
+      (test-comparison >   double-float (/ 0d0 0d0) (/ 0d0 0d0))
+      (test-comparison >   double-float (/ 0d0 0d0) 0d0)
+      (test-comparison >   double-float 0d0 (/ 0d0 0d0)))))
+
+(with-test (:name :car-and-cdr-type-derivation-conservative)
+  (let ((f1 (compile nil
+                     `(lambda (y)
+                        (declare (optimize speed))
+                        (let ((x (the (cons fixnum fixnum) (cons 1 2))))
+                          (declare (type (cons t fixnum) x))
+                          (rplaca x y)
+                          (+ (car x) (cdr x))))))
+        (f2 (compile nil
+                     `(lambda (y)
+                        (declare (optimize speed))
+                        (let ((x (the (cons fixnum fixnum) (cons 1 2))))
+                          (setf (cdr x) y)
+                          (+ (car x) (cdr x)))))))
+    (flet ((test-error (e value)
+             (assert (typep e 'type-error))
+             (assert (eq 'number (type-error-expected-type e)))
+             (assert (eq value (type-error-datum e)))))
+      (let ((v1 "foo")
+            (v2 "bar"))
+        (multiple-value-bind (res err) (ignore-errors (funcall f1 v1))
+          (assert (not res))
+          (test-error err v1))
+        (multiple-value-bind (res err) (ignore-errors (funcall f2 v2))
+          (assert (not res))
+          (test-error err v2))))))
+
+(with-test (:name :array-dimension-derivation-conservative)
+  (let ((f (compile nil
+                    `(lambda (x)
+                       (declare (optimize speed))
+                       (declare (type (array * (4 4)) x))
+                       (let ((y x))
+                         (setq x (make-array '(4 4)))
+                         (adjust-array y '(3 5))
+                         (array-dimension y 0))))))
+    (assert (= 3 (funcall f (make-array '(4 4) :adjustable t))))))
+
+(with-test (:name :with-timeout-code-deletion-note)
+  (handler-bind ((sb-ext:code-deletion-note #'error))
+    (compile nil `(lambda ()
+                    (sb-ext:with-timeout 0
+                      (sleep 1))))))
+
+(with-test (:name :full-warning-for-undefined-type-in-cl)
+  (assert (eq :full
+              (handler-case
+                  (compile nil `(lambda (x) (the replace x)))
+                (style-warning ()
+                  :style)
+                (warning ()
+                  :full)))))
+
+(with-test (:name :single-warning-for-single-undefined-type)
+  (let ((n 0))
+    (handler-bind ((warning (lambda (c)
+                              (declare (ignore c))
+                              (incf n))))
+      (compile nil `(lambda (x) (the #:no-type x)))
+      (assert (= 1 n))
+      (compile nil `(lambda (x) (the 'fixnum x)))
+      (assert (= 2 n)))))
+
+(with-test (:name :complex-subtype-dumping-in-xc)
+  (assert
+   (= sb-vm:complex-single-float-widetag
+      (sb-kernel:widetag-of
+       (sb-vm:saetp-initial-element-default (sb-c::find-saetp '(complex single-float))))))
+  (assert
+   (= sb-vm:complex-double-float-widetag
+      (sb-kernel:widetag-of
+       (sb-vm:saetp-initial-element-default (sb-c::find-saetp '(complex double-float)))))))
+
+(with-test (:name :complex-single-float-fill)
+  (assert (every (lambda (x) (= #c(1.0 2.0) x))
+                 (funcall
+                  (compile nil
+                           `(lambda (n x)
+                              (make-array (list n)
+                                          :element-type '(complex single-float)
+                                          :initial-element x)))
+                  10
+                  #c(1.0 2.0)))))