From: <lutz.euler@fr...>  20050129 19:28:45

Dear sbcl developers, in SBCL 0.8.19.3 on x8664 I noticed the following behaviour: * (defun f (x) (declare (type simplebitvector x)) (count 1 x)) F * (defvar b (makearray 64 :elementtype 'bit :initialelement 1)) B * (count 1 b) 64 * (f b) 0 The result is wrong for bit vectors whose length is an integer multiple of 64, except 0: * (dotimes (i 1000) (setf b (makearray i :elementtype 'bit :initialelement 1)) (unless (= (count 1 b) (f b)) (format t "~a ~a~%" (count 1 b) (f b)))) 64 0 128 64 192 128 ... Yours Lutz Euler 
From: Christophe Rhodes <csr21@ca...>  20050131 17:07:32

lutz.euler@... (Lutz Euler) writes: > * (count 1 b) > 64 > * (f b) > 0 Thanks for the report  I committed a fix in sbcl0.8.19.8. (Embarrassingly, this bug was introduced when I fixed a different offbyone error in the same compiler transform). Cheers, Christophe 
From: <lutz.euler@fr...>  20050216 22:53:17

Hi, Christophe Rhodes wrote: > Thanks for the report  I committed a fix in sbcl0.8.19.8. Sorry for warming up this thread after two weeks. First, many thanks for fixing the bug! As you surely will have noticed, now the compiler emits a note (tested under sbcl0.8.19.28 on x8664): * (defun f (x) (declare (type simplebitvector x)) (count 1 x)) ; in: LAMBDA NIL ; (COUNT 1 X) ; > LOCALLY PROGN COUNT LET IF DO BLOCK LET TAGBODY RETURNFROM PROGN LET* 1 ; >  ; ==> ; (ASH 1 SBC::EXTRA) ; ; note: unable to ; optimize ; due to type uncertainty: ; The second argument is a (INTEGER 1 64), not a (UNSIGNEDBYTE 6). ; compilation unit finished ; printed 1 note I took the liberty to try to suppress this note and came up with the following change: In src/compiler/generic/vmtran.lisp in the deftransforms for count and bitvector= on simplebitvectors replace (let* ((extra (1+ (mod (1 length) sb!vm:nwordbits))) (mask (1 (ash 1 extra))) (bits ...)) (declare (type (integer 1 #.sb!vm:nwordbits) extra)) ...) with (let* ((extra1 (mod (1 length) sb!vm:nwordbits)) (extra (1+ extra1)) (mask (1 (ash 2 extra1))) (bits ...)) (declare (type (integer 0 #.(1 sb!vm:nwordbits)) extra1)) (declare (type (integer 1 #.sb!vm:nwordbits) extra)) (declare (ignorable extra)) ...) Well, it seems this makes the source less readable :( so I can't really promote it with a clear conscience ... Might it instead be worthwhile to teach the compiler to do this transformation itself, i.e., given suitable conditions, to replace (ash x n) with (ash (ash x c) ( n c)) where c is a constant chosen such that ( n c) is of type (unsignedbyte 6)? With kind regards Lutz Euler 
From: Christophe Rhodes <csr21@ca...>  20050301 11:27:48

lutz.euler@... (Lutz Euler) writes: > Sorry for warming up this thread after two weeks. First, many thanks > for fixing the bug! As you surely will have noticed, now the compiler > emits a note (tested under sbcl0.8.19.28 on x8664): Thanks for this. In the end I used a slightly different rewrite: from (1 (ash 1 c)) to (ash #xff...ff ( c n)) which I think has all the desired properties. The fix was merged in sbcl0.8.20.2. Cheers, Christophe 