Some bugs are more fun than others.
<Kryztof> could be a ppc backend bug 21:16:47 <antifuchs> what's the difference that makes the ppc act up on that? 21:16:56
So apart from demonstrating my latent psychic abilities, this bug was responsible for quite some head-scratching:
(iter (for i in '(1 2 3)) (+ i 50)) => NIL ; on x86 and sparc => ERROR "2 is not a LIST" ; on ppc
Eventually, though, I tracked it down (:TRACE-FILE as an option to COMPILE-FILE is a wonderful thing), and it was amusing. The distilled test case I came up with was as follows
(defun foo () (values 1 2 3 4 5 6 7)) (defun bar (fn) (let (aa bb cc dd ee ff gg hh) (multiple-value-bind (a b c d e f g h) (funcall fn) (setq aa a) (setq bb b) (setq cc c) (setq dd d) (setq ee e) (setq ff f) (setq gg g) (setq hh h)) (values aa bb cc dd ee ff gg hh))) (assert (null (nth 7 (bar #'foo))))
So what's going on here? Well, the relevant piece of information here is that since calling FOO only returns seven values, the 8th (or, counting from zero, the 7th) should default to NIL. So that's what the ASSERT is doing; what's going wrong? To answer that, it helps to know that Gary Byers based his PPC backend of CMUCL (from which SBCL liberally borrowed) on the already-existing SPARC backend. However, the SPARC instruction set architecture has branch delay slots, such that the instruction following a branch is executed whether the branch is taken or not; the PPC has no such thing. So the cleverly-optimized loop for defaulting unknown values in the SPARC backend, when transcribed into PPC, doesn't work nearly so well...