* optimization: SEARCH on simple-base-strings can now be open-coded.
(see also contrib/compiler-extras.lisp for inspiration for
teaching the compiler about the Boyer-Moore algorithm).
+ * value, returned by MAX (and MIN) called with several EQUALP, but
+ not EQL, arguments now does not depend on compiler settings.
* fixed some bugs revealed by Paul Dietz' test suite:
** in stack analysis liveness information is propagated from
non-local entry points.
(defun max (number &rest more-numbers)
#!+sb-doc
- "Return the greatest of its arguments."
+ "Return the greatest of its arguments; among EQUALP greatest, return
+the first."
(do ((nlist more-numbers (cdr nlist))
(result number))
((null nlist) (return result))
(defun min (number &rest more-numbers)
#!+sb-doc
- "Return the least of its arguments."
+ "Return the least of its arguments; among EQUALP least, return
+the first."
(do ((nlist more-numbers (cdr nlist))
(result number))
((null nlist) (return result))
(defun %%min (x y)
(declare (type (or (unsigned-byte 32) (signed-byte 32)
single-float double-float) x y))
- (if (< x y)
+ (if (<= x y)
x y))
#+nil
(defun %%max (x y)
(declare (type (or (unsigned-byte 32) (signed-byte 32)
single-float double-float) x y))
- (if (> x y)
+ (if (>= x y)
x y))
#+nil
(macrolet
(lvar-type y)))))))
(defoptimizer (min derive-type) ((x y))
- (multiple-value-bind (definitely-< definitely->=)
- (ir1-transform-<-helper x y)
- (cond (definitely-<
+ (multiple-value-bind (definitely-> definitely-<=)
+ (ir1-transform-<-helper y x)
+ (cond (definitely-<=
(lvar-type x))
- (definitely->=
+ (definitely->
(lvar-type y))
(t
(make-canonical-union-type (list (lvar-type x)
(arg2 (gensym)))
`(let ((,arg1 x)
(,arg2 y))
- (if (> ,arg1 ,arg2)
+ (if (>= ,arg1 ,arg2)
,arg1 ,arg2)))))))
(deftransform min ((x y) (real real) *)
(arg2 (gensym)))
`(let ((,arg1 x)
(,arg2 y))
- (if (< ,arg1 ,arg2)
+ (if (<= ,arg1 ,arg2)
,arg1 ,arg2)))))))
) ; PROGN
(if (null rest)
`(values (the real ,arg0))
`(let ((maxrest (max ,@rest)))
- (if (> ,arg0 maxrest) ,arg0 maxrest)))))
+ (if (>= ,arg0 maxrest) ,arg0 maxrest)))))
(define-source-transform min (arg0 &rest rest)
(once-only ((arg0 arg0))
(if (null rest)
`(values (the real ,arg0))
`(let ((minrest (min ,@rest)))
- (if (< ,arg0 minrest) ,arg0 minrest)))))
+ (if (<= ,arg0 minrest) ,arg0 minrest)))))
\f
;;;; converting N-arg arithmetic functions
;;;;
'integer)))
(funcall #'%f12 0))))
-33)))
+
+;;; Discussion of a CMUCL PCL bug on Sparc with Raymond Toy revealed a
+;;; potential problem: optimizers and type derivers for MAX and MIN
+;;; were not consistent in treating EQUALP, but not EQL, arguments.
+(dolist (f '(min max))
+ (loop for complex-arg-args in '((1d0 2d0) (0d0 1d0))
+ for complex-arg = `(if x ,@complex-arg-args)
+ do
+ (loop for args in `((1 ,complex-arg)
+ (,complex-arg 1))
+ for form = `(,f ,@args)
+ for f1 = (compile nil `(lambda (x) ,form))
+ and f2 = (compile nil `(lambda (x) (declare (notinline min max))
+ ,form))
+ do
+ (dolist (x '(nil t))
+ (assert (eql (funcall f1 x) (funcall f2 x)))))))
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.8.7.33"
+"0.8.7.34"