From: <lut...@fr...> - 2005-01-29 19:28:45
|
Dear sbcl developers, in SBCL 0.8.19.3 on x86-64 I noticed the following behaviour: * (defun f (x) (declare (type simple-bit-vector x)) (count 1 x)) F * (defvar b (make-array 64 :element-type 'bit :initial-element 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 (make-array i :element-type 'bit :initial-element 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 R. <cs...@ca...> - 2005-01-31 17:07:32
|
lut...@fr... (Lutz Euler) writes: > * (count 1 b) > 64 > * (f b) > 0 Thanks for the report -- I committed a fix in sbcl-0.8.19.8. (Embarrassingly, this bug was introduced when I fixed a different off-by-one error in the same compiler transform). Cheers, Christophe |
From: <lut...@fr...> - 2005-02-16 22:53:17
|
Hi, Christophe Rhodes wrote: > Thanks for the report -- I committed a fix in sbcl-0.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 sbcl-0.8.19.28 on x86-64): * (defun f (x) (declare (type simple-bit-vector x)) (count 1 x)) ; in: LAMBDA NIL ; (COUNT 1 X) ; --> LOCALLY PROGN COUNT LET IF DO BLOCK LET TAGBODY RETURN-FROM PROGN LET* 1- ; --> - ; ==> ; (ASH 1 SB-C::EXTRA) ; ; note: unable to ; optimize ; due to type uncertainty: ; The second argument is a (INTEGER 1 64), not a (UNSIGNED-BYTE 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/vm-tran.lisp in the deftransforms for count and bit-vector-= on simple-bit-vectors replace (let* ((extra (1+ (mod (1- length) sb!vm:n-word-bits))) (mask (1- (ash 1 extra))) (bits ...)) (declare (type (integer 1 #.sb!vm:n-word-bits) extra)) ...) with (let* ((extra-1 (mod (1- length) sb!vm:n-word-bits)) (extra (1+ extra-1)) (mask (1- (ash 2 extra-1))) (bits ...)) (declare (type (integer 0 #.(1- sb!vm:n-word-bits)) extra-1)) (declare (type (integer 1 #.sb!vm:n-word-bits) 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 (unsigned-byte 6)? With kind regards Lutz Euler |
From: Christophe R. <cs...@ca...> - 2005-03-01 11:27:48
|
lut...@fr... (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 sbcl-0.8.19.28 on x86-64): 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 sbcl-0.8.20.2. Cheers, Christophe |