#20: Modular arith bug?
--------------------+-------------------------------------------------------
Reporter: rtoy | Owner: somebody
Type: defect | Status: new
Priority: major | Milestone:
Component: Core | Version: 19e
Keywords: |
--------------------+-------------------------------------------------------
{{{
(defun mat3neg (tt v)
(ldb (byte 32 0) (ash v (- tt))))
(defun mat3neg-a (tt v)
(logand #xffffffff (ash v (- tt))))
(defun zot (z2)
(declare (type (unsigned-byte 32) z2)
(optimize speed (safety 0)))
(mat3neg -28 z2))
(defun zot-a (z2)
(declare (type (unsigned-byte 32) z2)
(optimize speed (safety 0)))
(mat3neg-a -28 z2))
}}}
Compile {{{zot}}} and there are lots of compiler notes, from
{{{mat3neg}}}. But compile {{{zot-a}}} and there's just one for boxing up
the result.
However, {{{zot}}} and {{{zot-a}}} are functionally identical, so
{{{zot}}} and {{{zot-a}}} should produce the same code. But {{{zot}}} has
to do a full call to {{{ash}}} and {{{two-arg-and}}}.
The {{{ldb}}} must be confusing the compiler somehow.
--
Ticket URL: <http://trac.common-lisp.net/cmucl/ticket/20>
cmucl <http://common-lisp.net/project/cmucl>
cmucl
#19: Modular arith bug 2
--------------------+-------------------------------------------------------
Reporter: rtoy | Owner: somebody
Type: defect | Status: new
Priority: major | Milestone:
Component: Core | Version: 19b
Keywords: |
--------------------+-------------------------------------------------------
This was reported by Martin Cracauer to cmucl-imp, 2005-07-20.
{{{
(defun fixnum-hasher (a)
(declare
(optimize (speed 3) (safety 0) #+nil(debug 1)) ;; BUG HERE, only in
fast mode
(type fixnum a)) ;; bug equally apears if you leave this out
(logand
(the fixnum ;; BUG HERE. Drop this declaration and the bug disappears
(logxor (ash a -20) -482305527))
1023))
}}}
Repeatedly calling {{{(fixnum-hasher 27)}}} returns random values! The
problem is caused by modular arithmetic because if it is turned off (by
{{{setf c::*enable-modular-arithmetic* nil)}}} the bug doesn't happen.
The answer should be 521.
A related bug is
{{{
(defun foo (a b)
(locally (declare (optimize (speed 3) (safety 0) (debug 1)))
(the fixnum
(logand (the fixnum
(logxor (the fixnum a)
(the fixnum b)))
(the fixnum (1- (ash 1 18)))))))
}}}
This bug is mentioned in the same thread, but is from sbcl-devel, 2005-04-
29.
{{{(foo -1234 1234)}}} returns random values. The correct answer is
262140.
In both cases, there is a call to vm::logxor-mod32 with fixnum args,
returning an unsigned 32-bit result. This is not right.
--
Ticket URL: <http://trac.common-lisp.net/cmucl/ticket/19>
cmucl <http://common-lisp.net/project/cmucl>
cmucl
#18: Modular arith bug 1
--------------------+-------------------------------------------------------
Reporter: rtoy | Owner: somebody
Type: defect | Status: new
Priority: minor | Milestone:
Component: Core | Version: 19d
Keywords: |
--------------------+-------------------------------------------------------
Not really a bug, but a deficiency.
{{{
(defun ref (a n)
(declare (type (simple-array single-float (*)) a)
(type (integer 0 15) n)
(optimize (speed 3) (safety 0)))
(aref a (logand #xf (+ n 15))))
}}}
Relevant disassembly on sparc:
{{{
68: SRA %A1, 2, %NL0 ; %A1 = N
; No-arg-parsing
entry point
; [:NON-LOCAL-
ENTRY]
6C: ADD 15, %NL0
70: AND 15, %NL0
74: SLL %NL0, 2, %NL1
78: ADD %NL1, 1, %NL0
7C: LDF [%A0+%NL0], %F0 ; %A0 = A
}}}
So {{{N}}} is converted from a fixnum to an integer, the appropriate
operations are done, and then converted back to a fixnum. All of this
could have been done without the conversion like so:
{{{
40: ADD 60, %A1 ; %A1 = N
; No-arg-parsing
entry point
; [:NON-LOCAL-
ENTRY]
44: AND 60, %A1
48: ADD %A1, 1, %NL0
4C: LDF [%A0+%NL0], %F0 ; %A0 = A
}}}
--
Ticket URL: <http://trac.common-lisp.net/cmucl/ticket/18>
cmucl <http://common-lisp.net/project/cmucl>
cmucl
#21: Modular arith bug 3
--------------------+-------------------------------------------------------
Reporter: rtoy | Owner: somebody
Type: defect | Status: new
Priority: major | Milestone:
Component: Core | Version: 2008-08
Keywords: |
--------------------+-------------------------------------------------------
The following code doesn't use modular arithmetic for ash:
{{{
(defun bug (v)
(declare (type (unsigned-byte 32) v)
(optimize (speed 3) (safety 0)))
(logand #xffffffff (logxor v (ash v (- -16)))))
}}}
You get compiler warnings about {{{ASH}}}.
But the equivalent code is ok:
{{{
(defun bug-a (v)
(declare (type (unsigned-byte 32) v)
(optimize (speed 3) (safety 0)))
(ldb (byte 32 0) (logxor v (ash v (- -16)))))
}}}
Also, if in {{{bug}}}, you change {{{(- -16)}}} to the obvious {{{16}}},
the compiler notes are gone, and the generated code is as expected.
What appears to be happening is that when {{{logand-defopt-helper}}} is
run, the compiler doesn't know the type of the shift for {{{ASH}}}.
Hence, it can't do modular arithmetic stuff. However, when the code is
finally generated, you can see that the shift is now a known constant
value of 16. I don't know why.
--
Ticket URL: <http://trac.common-lisp.net/cmucl/ticket/21>
cmucl <http://common-lisp.net/project/cmucl>
cmucl