From 20b2378572cf7378f3f267e2234c4234dacfbdc9 Mon Sep 17 00:00:00 2001 From: Alexey Dejneka Date: Sat, 31 Jan 2004 17:04:13 +0000 Subject: [PATCH] 0.8.7.34: * Make transforms and optimizers for MAX and MIN consistent with their definitions. --- NEWS | 2 ++ src/code/numbers.lisp | 6 ++++-- src/compiler/sparc/float.lisp | 16 ++++++++-------- src/compiler/srctran.lisp | 4 ++-- tests/compiler.pure.lisp | 17 +++++++++++++++++ version.lisp-expr | 2 +- 6 files changed, 34 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index 5402e4b..77290ed 100644 --- a/NEWS +++ b/NEWS @@ -2262,6 +2262,8 @@ changes in sbcl-0.8.8 relative to sbcl-0.8.7: * 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. diff --git a/src/code/numbers.lisp b/src/code/numbers.lisp index a18b5b9..72e8761 100644 --- a/src/code/numbers.lisp +++ b/src/code/numbers.lisp @@ -765,7 +765,8 @@ (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)) @@ -775,7 +776,8 @@ (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)) diff --git a/src/compiler/sparc/float.lisp b/src/compiler/sparc/float.lisp index 5ae9ef2..b96cecc 100644 --- a/src/compiler/sparc/float.lisp +++ b/src/compiler/sparc/float.lisp @@ -2396,14 +2396,14 @@ (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 @@ -2538,11 +2538,11 @@ (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) @@ -2575,7 +2575,7 @@ (arg2 (gensym))) `(let ((,arg1 x) (,arg2 y)) - (if (> ,arg1 ,arg2) + (if (>= ,arg1 ,arg2) ,arg1 ,arg2))))))) (deftransform min ((x y) (real real) *) @@ -2602,7 +2602,7 @@ (arg2 (gensym))) `(let ((,arg1 x) (,arg2 y)) - (if (< ,arg1 ,arg2) + (if (<= ,arg1 ,arg2) ,arg1 ,arg2))))))) ) ; PROGN diff --git a/src/compiler/srctran.lisp b/src/compiler/srctran.lisp index 67c8956..6ba54f8 100644 --- a/src/compiler/srctran.lisp +++ b/src/compiler/srctran.lisp @@ -3176,13 +3176,13 @@ (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))))) ;;;; converting N-arg arithmetic functions ;;;; diff --git a/tests/compiler.pure.lisp b/tests/compiler.pure.lisp index eefc810..7240363 100644 --- a/tests/compiler.pure.lisp +++ b/tests/compiler.pure.lisp @@ -1117,3 +1117,20 @@ '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))))))) diff --git a/version.lisp-expr b/version.lisp-expr index c04b9b0..b2f2a79 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; 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" -- 1.7.10.4