> bisect result (have not investigated further, but certainly seems
> plausible):
Yes, completely.
The problem is that my oh-so-clever bug fix for the previous bugs
involving using signed modular arithmetic to implement unsigned
arithmetic is incomplete. The transformation that needs to be done is
something like
with precondition that <e1> and <e2> are known positive quantities, and
that the logand itself is known to return a positive fixnum.
Before the patch identified, this transformation was done for <e1>, <e2>
being known modular-type expressions (i.e. involving mostly bitwise
logical and arithmetic operators). After the patch identified, this
transformation was also done for constants. However, simple variables
such as x don't have this applied, which causes the bug. An example of
something that is now correctly optimized which wasn't previously is
(defun not-bug (x)
(declare (optimize (space 3))
(type (integer 12417236377505266230 12417274239874990070)
x))
(logand 8459622733968096971 (logior 1 x)))
Now, it's fairly easy to wrap x in the correct (mask-signed-field ...)
in the compiler, using (I think) filter-lvar. What isn't easy is to
tell the compiler not to recurse infinitely in modular arithmetic
optimization, optimizing away infinitely; I think this or something like
it is the "right" solution, however. Options that might fix the problem
but would be a long way from the right solution are:
1. disable using signed modular arithmetic to implement unsigned
computations
(a) and call it a day;
(b) and also implement positive-fixnum modular arithmetic variants;
2. having some kind of non-modular-optimizeable
%mask-signed-field-but-dont-recurse to mark some generated forms as
being "finished with": though judging by my comments regarding
previous work in src/compiler/srctran.lisp around the area, maybe
that might be right after all if all the details are sorted.
I'm not going to get to any of these options for at least three weeks.
David Lichteblau <email address hidden> writes:
> bisect result (have not investigated further, but certainly seems
> plausible):
Yes, completely.
The problem is that my oh-so-clever bug fix for the previous bugs
involving using signed modular arithmetic to implement unsigned
arithmetic is incomplete. The transformation that needs to be done is
something like
(logand <e1> <e2>)
=> (logand (mask-signed-field 63 <e1>) (mask-signed-field 63 <e2>))
with precondition that <e1> and <e2> are known positive quantities, and
that the logand itself is known to return a positive fixnum.
Before the patch identified, this transformation was done for <e1>, <e2> 66230 124172742398749 90070)
being known modular-type expressions (i.e. involving mostly bitwise
logical and arithmetic operators). After the patch identified, this
transformation was also done for constants. However, simple variables
such as x don't have this applied, which causes the bug. An example of
something that is now correctly optimized which wasn't previously is
(defun not-bug (x)
(declare (optimize (space 3))
(type (integer 124172363775052
x))
(logand 8459622733968096971 (logior 1 x)))
Now, it's fairly easy to wrap x in the correct (mask-signed-field ...)
in the compiler, using (I think) filter-lvar. What isn't easy is to
tell the compiler not to recurse infinitely in modular arithmetic
optimization, optimizing away infinitely; I think this or something like
it is the "right" solution, however. Options that might fix the problem
but would be a long way from the right solution are:
1. disable using signed modular arithmetic to implement unsigned optimizeable signed- field-but- dont-recurse to mark some generated forms as srctran. lisp around the area, maybe
computations
(a) and call it a day;
(b) and also implement positive-fixnum modular arithmetic variants;
2. having some kind of non-modular-
%mask-
being "finished with": though judging by my comments regarding
previous work in src/compiler/
that might be right after all if all the details are sorted.
I'm not going to get to any of these options for at least three weeks.
Christophe