fix misoptimization of TRUNCATE
authorNikodemus Siivola <nikodemus@random-state.net>
Thu, 1 Dec 2011 15:43:49 +0000 (17:43 +0200)
committerNikodemus Siivola <nikodemus@random-state.net>
Mon, 5 Dec 2011 09:28:02 +0000 (11:28 +0200)
  Reported by Eric Marsden on sbcl-devel 2011-12-01.

   "illegal instruction on PowerPC"

  We check for result type being a VALUES-TYPE-P when deciding if to compute
  the second value for TRUNCATE or not -- but *WILD-TYPE* isn't a values type.

  Make VALUES-TYPE-P return true for it from now on. What could possibly go
  wrong? Just two other places need to change, it seems.

NEWS
src/code/early-type.lisp
src/code/late-type.lisp
src/compiler/ir2tran.lisp
tests/compiler.pure.lisp

diff --git a/NEWS b/NEWS
index 77b045c..25969ee 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ changes relative to sbcl-1.0.54:
     account for signed zeros.
   * bug fix: compiler error when typechecking a call to a function with
     non-constant keyword arguments.
+  * bug fix: misoptimization of TRUNCATE causing erratic behaviour.
 
 changes in sbcl-1.0.54 relative to sbcl-1.0.53:
   * minor incompatible changes:
index 5b761c0..1b395f1 100644 (file)
             (:include args-type
                       (class-info (type-class-or-lose 'values)))
             (:constructor %make-values-type)
+            (:predicate %values-type-p)
             (:copier nil)))
 
+(declaim (inline value-type-p))
+(defun values-type-p (x)
+  (or (eq x *wild-type*)
+      (%values-type-p x)))
+
 (defun-cached (make-values-type-cached
                :hash-bits 8
                :hash-function (lambda (req opt rest allowp)
index 13e3368..d1eaa9e 100644 (file)
       1
       (values-type-max-value-count type)))
 
+;;; VALUES type with a single value.
 (defun type-single-value-p (type)
-  (and (values-type-p type)
+  (and (%values-type-p type)
        (not (values-type-rest type))
        (null (values-type-optional type))
        (singleton-p (values-type-required type))))
index 1674834..4a35b47 100644 (file)
   (let* ((type (node-derived-type call))
          (types
           (mapcar #'primitive-type
-                  (if (values-type-p type)
+                  (if (args-type-p type)
                       (append (args-type-required type)
                               (args-type-optional type))
                       (list type))))
index eb60efd..2388091 100644 (file)
                          (declare (type keyword p3))
                          (tree-equal p1 (cons 1 2) (the (member :test) p3) p4)))))
     (assert (funcall fun (cons 1.0 2.0) :test '=))))
+
+(with-test (:name :truncate-wild-values)
+  (multiple-value-bind (q r)
+      (handler-bind ((warning #'error))
+        (let ((sb-c::*check-consistency* t))
+          (funcall (compile nil
+                            `(lambda (a)
+                               (declare (type (member 1d0 2d0) a))
+                               (block return-value-tag
+                                 (funcall
+                                  (the function
+                                       (catch 'debug-catch-tag
+                                         (return-from return-value-tag
+                                           (progn (truncate a)))))))))
+                   2d0)))
+    (assert (eql 2 q))
+    (assert (eql 0d0 r))))