X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=tests%2Fcompiler.pure.lisp;h=d36c958df49828ac906fa476d0c68b6c7b359927;hb=b3e7d6608689a639cb774e2ce15bb5bacaed5179;hp=4a0bf4173e655e33b8edf483116f44ba8bdecee5;hpb=787090e008e13b1c91ba04cf7776ca0af7336342;p=sbcl.git diff --git a/tests/compiler.pure.lisp b/tests/compiler.pure.lisp index 4a0bf41..d36c958 100644 --- a/tests/compiler.pure.lisp +++ b/tests/compiler.pure.lisp @@ -1031,4 +1031,620 @@ (compilation-speed 1))) (logand a (* a 438810)))) 215067723) - 13739018)) \ No newline at end of file + 13739018)) + + +;;;; Bugs in stack analysis +;;; bug 299 (reported by PFD) +(assert + (equal (funcall + (compile + nil + '(lambda () + (declare (optimize (debug 1))) + (multiple-value-call #'list + (if (eval t) (eval '(values :a :b :c)) nil) + (catch 'foo (throw 'foo (values :x :y))))))) + '(:a :b :c :x :y))) +;;; bug 298 (= MISC.183) +(assert (zerop (funcall + (compile + nil + '(lambda (a b c) + (declare (type (integer -368154 377964) a)) + (declare (type (integer 5044 14959) b)) + (declare (type (integer -184859815 -8066427) c)) + (declare (ignorable a b c)) + (declare (optimize (speed 3))) + (declare (optimize (safety 1))) + (declare (optimize (debug 1))) + (block b7 + (flet ((%f3 (f3-1 f3-2 f3-3) 0)) + (apply #'%f3 0 (catch 'foo (return-from b7 (%f3 0 b c))) c nil))))) + 0 6000 -9000000))) +(assert (equal (eval '(let () (apply #'list 1 (list (catch 'a (throw 'a (block b 2))))))) + '(1 2))) +(let ((f (compile + nil + '(lambda (x) + (block foo + (multiple-value-call #'list + :a + (block bar + (return-from foo + (multiple-value-call #'list + :b + (block quux + (return-from bar + (catch 'baz + (if x + (return-from quux 1) + (throw 'baz 2)))))))))))))) + (assert (equal (funcall f t) '(:b 1))) + (assert (equal (funcall f nil) '(:a 2)))) + +;;; MISC.185 +(assert (equal + (funcall + (compile + nil + '(lambda (a b c) + (declare (type (integer 5 155656586618) a)) + (declare (type (integer -15492 196529) b)) + (declare (type (integer 7 10) c)) + (declare (optimize (speed 3))) + (declare (optimize (safety 1))) + (declare (optimize (debug 1))) + (flet ((%f3 + (f3-1 f3-2 f3-3 + &optional (f3-4 a) (f3-5 0) + (f3-6 + (labels ((%f10 (f10-1 f10-2 f10-3) + 0)) + (apply #'%f10 + 0 + a + (- (if (equal a b) b (%f10 c a 0)) + (catch 'ct2 (throw 'ct2 c))) + nil)))) + 0)) + (%f3 (%f3 (%f3 b 0 0 0) a 0) a b b b c)))) 5 0 7) + 0)) +;;; MISC.186 +(assert (eq + (eval + '(let* ((form '(labels ((%f3 (f3-1 f3-2) f3-1)) + (apply #'%f3 b (catch 'ct8 (throw 'ct8 (logeqv (%f3 c 0)))) nil))) + (vars '(b c)) + (fn1 `(lambda ,vars + (declare (type (integer -2 19) b) + (type (integer -1520 218978) c) + (optimize (speed 3) (safety 1) (debug 1))) + ,form)) + (fn2 `(lambda ,vars + (declare (notinline logeqv apply) + (optimize (safety 3) (speed 0) (debug 0))) + ,form)) + (cf1 (compile nil fn1)) + (cf2 (compile nil fn2)) + (result1 (multiple-value-list (funcall cf1 2 18886))) + (result2 (multiple-value-list (funcall cf2 2 18886)))) + (if (equal result1 result2) + :good + (values result1 result2)))) + :good)) + +;;; MISC.290 +(assert (zerop + (funcall + (compile + nil + '(lambda () + (declare + (optimize (speed 3) (space 3) (safety 1) + (debug 2) (compilation-speed 0))) + (apply (constantly 0) (catch 'ct2 0) 0 (catch 'ct2 0) nil)))))) + +;;; MISC.292 +(assert (zerop (funcall + (compile + nil + '(lambda (a b) + (declare (optimize (speed 2) (space 0) (safety 3) (debug 1) + (compilation-speed 2))) + (apply (constantly 0) + a + 0 + (catch 'ct6 + (apply (constantly 0) + 0 + 0 + (let* ((v1 + (let ((*s7* 0)) + b))) + 0) + 0 + nil)) + 0 + nil))) + 1 2))) + +;;; misc.295 +(assert (eql + (funcall + (compile + nil + '(lambda () + (declare (optimize (speed 1) (space 0) (safety 0) (debug 0))) + (multiple-value-prog1 + (the integer (catch 'ct8 (catch 'ct7 15867134))) + (catch 'ct1 (throw 'ct1 0)))))) + 15867134)) + +;;; misc.361: replacing CAST with (m-v-call #'%compile-time-type-error) +;;; could transform known-values LVAR to UVL +(assert (zerop (funcall + (compile + nil + '(lambda (a b c) + (declare (notinline boole values denominator list)) + (declare + (optimize (speed 2) + (space 0) + (safety 1) + (debug 0) + (compilation-speed 2))) + (catch 'ct6 + (progv + '(*s8*) + (list 0) + (let ((v9 (ignore-errors (throw 'ct6 0)))) + (denominator + (progv nil nil (values (boole boole-and 0 v9))))))))) + 1 2 3))) + +;;; non-continuous dead UVL blocks +(defun non-continuous-stack-test (x) + (multiple-value-call #'list + (eval '(values 11 12)) + (eval '(values 13 14)) + (block ext + (return-from non-continuous-stack-test + (multiple-value-call #'list + (eval '(values :b1 :b2)) + (eval '(values :b3 :b4)) + (block int + (return-from ext + (multiple-value-call (eval #'values) + (eval '(values 1 2)) + (eval '(values 3 4)) + (block ext + (return-from int + (multiple-value-call (eval #'values) + (eval '(values :a1 :a2)) + (eval '(values :a3 :a4)) + (block int + (return-from ext + (multiple-value-call (eval #'values) + (eval '(values 5 6)) + (eval '(values 7 8)) + (if x + :ext + (return-from int :int)))))))))))))))) +(assert (equal (non-continuous-stack-test t) '(11 12 13 14 1 2 3 4 5 6 7 8 :ext))) +(assert (equal (non-continuous-stack-test nil) '(:b1 :b2 :b3 :b4 :a1 :a2 :a3 :a4 :int))) + +;;; MISC.362: environment of UNWIND-PROTECTor is different from that +;;; if ENTRY. +(assert (equal (multiple-value-list (funcall + (compile + nil + '(lambda (b g h) + (declare (optimize (speed 3) (space 3) (safety 2) + (debug 2) (compilation-speed 3))) + (catch 'ct5 + (unwind-protect + (labels ((%f15 (f15-1 f15-2 f15-3) + (rational (throw 'ct5 0)))) + (%f15 0 + (apply #'%f15 + 0 + h + (progn + (progv '(*s2* *s5*) (list 0 (%f15 0 g 0)) b) + 0) + nil) + 0)) + (common-lisp:handler-case 0))))) + 1 2 3)) + '(0))) + + +;;; MISC.275 +(assert + (zerop + (funcall + (compile + nil + '(lambda (b) + (declare (notinline funcall min coerce)) + (declare + (optimize (speed 1) + (space 2) + (safety 2) + (debug 1) + (compilation-speed 1))) + (flet ((%f12 (f12-1) + (coerce + (min + (if f12-1 (multiple-value-prog1 + b (return-from %f12 0)) + 0)) + '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))))))) + +;;; +(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."))) + +(let ((f (compile nil '(lambda (x) + (declare (optimize speed (safety 0))) + (block nil + (the double-float + (multiple-value-prog1 + (sqrt (the double-float x)) + (when (< x 0) + (return :minus))))))))) + (assert (eql (funcall f -1d0) :minus)) + (assert (eql (funcall f 4d0) 2d0))) + +;;; bug 304: SBCL produced something similar to (/ (ASH x 4) 8) +(handler-case + (compile nil '(lambda (a i) + (locally + (declare (optimize (speed 3) (safety 0) (space 0) (debug 0) + (inhibit-warnings 0))) + (declare (type (alien (* (unsigned 8))) a) + (type (unsigned-byte 32) i)) + (deref a i)))) + (compiler-note () (error "The code is not optimized."))) + +(handler-case + (compile nil '(lambda (x) + (declare (type (integer -100 100) x)) + (declare (optimize speed)) + (declare (notinline identity)) + (1+ (identity x)))) + (compiler-note () (error "IDENTITY derive-type not applied."))) + +(assert (null (funcall (compile nil '(lambda (x) (funcall #'cddr x))) nil))) + +;;; MISC.293 = easy variant of bug 303: repeated write to the same +;;; LVAR; here the first write may be cleared before the second is +;;; made. +(assert + (zerop + (funcall + (compile + nil + '(lambda () + (declare (notinline complex)) + (declare (optimize (speed 1) (space 0) (safety 1) + (debug 3) (compilation-speed 3))) + (flet ((%f () (multiple-value-prog1 0 (return-from %f 0)))) + (complex (%f) 0))))))) + +;;; MISC.110A: CAST optimizer forgot to flush LVAR derived type +(assert (zerop (funcall + (compile + nil + '(lambda (a c) + (declare (type (integer -1294746569 1640996137) a)) + (declare (type (integer -807801310 3) c)) + (declare (optimize (speed 3) (space 3) (safety 0) (debug 0) (compilation-speed 3))) + (catch 'ct7 + (if + (logbitp 0 + (if (/= 0 a) + c + (ignore-errors + (progn (if (ldb-test (byte 0 0) (rational (throw 'ct7 0))) 0 0) 0)))) + 0 0)))) + 391833530 -32785211))) + +;;; efficiency notes for ordinary code +(macrolet ((frob (arglist &body body) + `(progn + (handler-case + (compile nil '(lambda ,arglist ,@body)) + (sb-ext:compiler-note (e) + (error "bad compiler note for ~S:~% ~A" ',body e))) + (catch :got-note + (handler-case + (compile nil '(lambda ,arglist (declare (optimize speed)) + ,@body)) + (sb-ext:compiler-note (e) (throw :got-note nil))) + (error "missing compiler note for ~S" ',body))))) + (frob (x) (funcall x)) + (frob (x y) (find x y)) + (frob (x y) (find-if x y)) + (frob (x y) (find-if-not x y)) + (frob (x y) (position x y)) + (frob (x y) (position-if x y)) + (frob (x y) (position-if-not x y)) + (frob (x) (aref x 0))) + +(macrolet ((frob (style-warn-p form) + (if style-warn-p + `(catch :got-style-warning + (handler-case + (eval ',form) + (style-warning (e) (throw :got-style-warning nil))) + (error "missing style-warning for ~S" ',form)) + `(handler-case + (eval ',form) + (style-warning (e) + (error "bad style-warning for ~S: ~A" ',form e)))))) + (frob t (lambda (x &optional y &key z) (list x y z))) + (frob nil (lambda (x &optional y z) (list x y z))) + (frob nil (lambda (x &key y z) (list x y z))) + (frob t (defgeneric #:foo (x &optional y &key z))) + (frob nil (defgeneric #:foo (x &optional y z))) + (frob nil (defgeneric #:foo (x &key y z))) + (frob t (defun #:foo (x) (flet ((foo (x &optional y &key z) (list x y z))) (foo x x :z x))))) + +;;; this was a bug in the LOGXOR type deriver. The top form gave a +;;; note, because the system failed to derive the fact that the return +;;; from LOGXOR was small and negative, though the bottom one worked. +(handler-bind ((sb-ext:compiler-note #'error)) + (compile nil '(lambda () + (declare (optimize speed (safety 0))) + (lambda (x y) + (declare (type (integer 3 6) x) + (type (integer -6 -3) y)) + (+ (logxor x y) most-positive-fixnum))))) +(handler-bind ((sb-ext:compiler-note #'error)) + (compile nil '(lambda () + (declare (optimize speed (safety 0))) + (lambda (x y) + (declare (type (integer 3 6) y) + (type (integer -6 -3) x)) + (+ (logxor x y) most-positive-fixnum))))) + +;;; check that modular ash gives the right answer, to protect against +;;; possible misunderstandings about the hardware shift instruction. +(assert (zerop (funcall + (compile nil '(lambda (x y) + (declare (optimize speed) + (type (unsigned-byte 32) x y)) + (logand #xffffffff (ash x y)))) + 1 257))) + +;;; code instrumenting problems +(compile nil + '(lambda () + (declare (optimize (debug 3))) + (list (the integer (if nil 14 t))))) + +(compile nil + '(LAMBDA (A B C D) + (DECLARE (NOTINLINE LOGORC1 BYTE MASK-FIELD)) + (DECLARE + (OPTIMIZE (SPEED 1) + (SPACE 1) + (SAFETY 1) + (DEBUG 3) + (COMPILATION-SPEED 0))) + (MASK-FIELD (BYTE 7 26) + (PROGN + (TAGBODY (THE INTEGER (CATCH 'CT4 (LOGORC1 C -15950))) 1) + B)))) + +(compile nil + '(lambda (buffer i end) + (declare (optimize (debug 3))) + (loop (when (not (eql 0 end)) (return))) + (let ((s (make-string end))) + (setf (schar s i) (schar buffer i)) + s))) + +;;; check that constant string prefix and suffix don't cause the +;;; compiler to emit code deletion notes. +(handler-bind ((sb-ext:code-deletion-note #'error)) + (compile nil '(lambda (s x) + (pprint-logical-block (s x :prefix "(") + (print x s)))) + (compile nil '(lambda (s x) + (pprint-logical-block (s x :per-line-prefix ";") + (print x s)))) + (compile nil '(lambda (s x) + (pprint-logical-block (s x :suffix ">") + (print x s))))) + +;;; MISC.427: loop analysis requires complete DFO structure +(assert (eql 17 (funcall + (compile + nil + '(lambda (a) + (declare (notinline list reduce logior)) + (declare (optimize (safety 2) (compilation-speed 1) + (speed 3) (space 2) (debug 2))) + (logior + (let* ((v5 (reduce #'+ (list 0 a)))) + (declare (dynamic-extent v5)) + v5)))) + 17))) + +;;; MISC.434 +(assert (zerop (funcall + (compile + nil + '(lambda (a b) + (declare (type (integer -8431780939320 1571817471932) a)) + (declare (type (integer -4085 0) b)) + (declare (ignorable a b)) + (declare + (optimize (space 2) + (compilation-speed 0) + #+sbcl (sb-c:insert-step-conditions 0) + (debug 2) + (safety 0) + (speed 3))) + (let ((*s5* 0)) + (dotimes (iv1 2 0) + (let ((*s5* + (elt '(1954479092053) + (min 0 + (max 0 + (if (< iv1 iv1) + (lognand iv1 (ash iv1 (min 53 iv1))) + iv1)))))) + 0))))) + -7639589303599 -1368))) + +(compile + nil + '(lambda (a b) + (declare (type (integer) a)) + (declare (type (integer) b)) + (declare (ignorable a b)) + (declare (optimize (space 2) (compilation-speed 0) + (debug 0) (safety 0) (speed 3))) + (dotimes (iv1 2 0) + (when (< iv1 2) (print 'x)) ;; request for second constraint propagation pass + (print (if (< iv1 iv1) + (logand (ash iv1 iv1) 1) + iv1))))) + +;;; MISC.435: lambda var substitution in a deleted code. +(assert (zerop (funcall + (compile + nil + '(lambda (a b c d) + (declare (notinline aref logandc2 gcd make-array)) + (declare + (optimize (space 0) (safety 0) (compilation-speed 3) + (speed 3) (debug 1))) + (progn + (tagbody + (let* ((v2 (make-array nil :initial-element (catch 'ct1 (go tag2))))) + (declare (dynamic-extent v2)) + (gcd (go tag2) (logandc2 (catch 'ct2 c) (aref v2)))) + tag2) + 0))) + 3021871717588 -866608 -2 -17194))) + +;;; MISC.436, 438: lost reoptimization +(assert (zerop (funcall + (compile + nil + '(lambda (a b) + (declare (type (integer -2917822 2783884) a)) + (declare (type (integer 0 160159) b)) + (declare (ignorable a b)) + (declare + (optimize (compilation-speed 1) + (speed 3) + (safety 3) + (space 0) + ; #+sbcl (sb-c:insert-step-conditions 0) + (debug 0))) + (if + (oddp + (loop for + lv1 + below + 2 + count + (logbitp 0 + (1- + (ash b + (min 8 + (count 0 + '(-10197561 486 430631291 + 9674068)))))))) + b + 0))) + 1265797 110757))) + +(assert (zerop (funcall + (compile + nil + ' (lambda (a) + (declare (type (integer 0 1696) a)) + ; (declare (ignorable a)) + (declare (optimize (space 2) (debug 0) (safety 1) + (compilation-speed 0) (speed 1))) + (if (logbitp 0 (ash (1- a) (min 11 a))) 0 0))) + 805))) + +;;; bug #302 +(assert (compile + nil + '(lambda (s ei x y) + (declare (type (simple-array function (2)) s) (type ei ei)) + (funcall (aref s ei) x y)))) + +;;; MISC.320: ir1-transform can create an intercomponent reference to +;;; a DEFINED-FUN. +(assert (eql 102 (funcall + (compile + nil + '(lambda () + (declare (optimize (speed 3) (space 0) (safety 2) + (debug 2) (compilation-speed 0))) + (catch 'ct2 + (elt '(102) + (flet ((%f12 () (rem 0 -43))) + (multiple-value-call #'%f12 (values)))))))))) + +;;; MISC.437: lost reoptimization after FLUSH-DEST +(assert (zerop (funcall + (compile + nil + '(lambda (a b c d e) + (declare (notinline values complex eql)) + (declare + (optimize (compilation-speed 3) + (speed 3) + (debug 1) + (safety 1) + (space 0))) + (flet ((%f10 + (f10-1 f10-2 f10-3 + &optional (f10-4 (ignore-errors 0)) (f10-5 0) + &key &allow-other-keys) + (if (or (eql 0 0) t) 0 (if f10-1 0 0)))) + (complex (multiple-value-call #'%f10 (values a c b 0 0)) 0)))) + 80043 74953652306 33658947 -63099937105 -27842393))) + +;;; bug #351 -- program-error for malformed LET and LET*, including those +;;; resulting from SETF of LET. +(dolist (fun (list (compile nil '(lambda () (let :bogus-let :oops))) + (compile nil '(lambda () (let* :bogus-let* :oops))) + (compile nil '(lambda (x) (push x (let ((y 0)) y)))))) + (assert (functionp fun)) + (multiple-value-bind (res err) (ignore-errors (funcall fun)) + (assert (not res)) + (assert (typep err 'program-error))))