[Vm-dev] [commit] r2463 - CogVM source as per VMMaker.oscog-eem.105. Fix signed32BitValueOf for most neg-

David T. Lewis lewis at mail.msen.com
Thu Jul 21 18:01:36 UTC 2011


Thanks a lot Eliot, and Igor also!

Dave

On Thu, Jul 21, 2011 at 10:35:00AM -0700, Eliot Miranda wrote:
>  
> On Thu, Jul 21, 2011 at 4:30 AM, David T. Lewis <lewis at mail.msen.com> wrote:
> 
> >
> > On Thu, Jul 21, 2011 at 07:08:18AM -0400, David T. Lewis wrote:
> > >
> > > Commit message blocked due to size, forwarding trimmed version:
> > >
> > > Author: eliot
> > > Date: 2011-07-18 17:35:51 -0700 (Mon, 18 Jul 2011)
> > > New Revision: 2463
> >
> > <snip>
> >
> > > Log:
> > > CogVM source as per VMMaker.oscog-eem.105.  Fix signed32BitValueOf for
> > most neg-
> > > ative value C compiler mis-optimization.  Speed up primitiveFail using !
> > trick.
> > > Add multi-threaded sources to tree (won't build yet due to issue in
> > ia32abicc.c)
> > > Upgrade nscogsrc/plugins to official versions.
> >
> > Hi Eliot,
> >
> > Can you say what the issue was with signed32BitValueOf? I can
> > see the changes in InterpreterPrimitives>>signed32BitValueOf:
> > but I'm not clear on whether this is something that affects
> > Alien, or if it is something that has been causing problems
> > more generally but went unnoticed. Also, I'd like to document
> > this with a unit test, so if you can suggest a code snippet
> > that would be great.
> >
> 
> The unit test is in the lien tests and is the attempt to assign max neg int
> (-2^31) through signedLongAt:put:.  The problem is due to a pervasive C
> compiler bug with optimization.  Recall that max neg int is exceptional in
> that it is the only value in a 2's complement representation that can't be
> negated since max neg int = -max pos int - 1.  Here's the bug, and it
> occurred in signed64BitValueOf: and signedMachineIntegerValueOf: as well; I
> slipped in not fixing signed32BitValueOf:
> 
> <var: #value type: #int>
> ...
>  (negative
>  and: [self
> cCode: [value - 1 > 0]
> inSmalltalk: [value = -16r80000000]]) ifTrue: "Don't fail for -2147483648
> /-16r80000000"
> 
> Since value is int (32 bits on relevant systems) then if value =
> 16r80000000, value - 1 will wrap around to 16r7fffffff, bit all other
> negative values will remain negative.  Hence value - 1 > 0 /should/ cheaply
> identify max neg int.  But both gcc in many versions, and icc, the intel
> compiler, under optimization assume that value - 1 > 0 is always false, and
> hence cause the primitive to fail for max neg int.
> 
> Instead, the solution I've adopted is to use a different sequence using
> shifts that is not mis-optimized, at least by gcc and icc:
> 
>  (negative and: [0 = (self cCode: [value << 1]
> inSmalltalk: [value << 1 bitAnd: (1 << 32) - 1])]) ifTrue:
> 
> i.e. 16r8000000 is the only negative value (0 is positive) that when shifted
> left within a 32-bit type equals zero since the sign bit is shifted out.
> 
> And to those C compilers, grrr.... ;)
> 
> 
> > TIA,
> > Dave
> >
> >
> 
> 
> -- 
> best,
> Eliot



More information about the Vm-dev mailing list