<br><br><div class="gmail_quote">On Thu, Jul 21, 2011 at 4:30 AM, David T. Lewis <span dir="ltr"><<a href="mailto:lewis@mail.msen.com">lewis@mail.msen.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im"><br>
On Thu, Jul 21, 2011 at 07:08:18AM -0400, David T. Lewis wrote:<br>
><br>
> Commit message blocked due to size, forwarding trimmed version:<br>
><br>
> Author: eliot<br>
> Date: 2011-07-18 17:35:51 -0700 (Mon, 18 Jul 2011)<br>
> New Revision: 2463<br>
<br>
</div><snip><br>
<div class="im"><br>
> Log:<br>
> CogVM source as per VMMaker.oscog-eem.105. Fix signed32BitValueOf for most neg-<br>
> ative value C compiler mis-optimization. Speed up primitiveFail using ! trick.<br>
> Add multi-threaded sources to tree (won't build yet due to issue in ia32abicc.c)<br>
> Upgrade nscogsrc/plugins to official versions.<br>
<br>
</div>Hi Eliot,<br>
<br>
Can you say what the issue was with signed32BitValueOf? I can<br>
see the changes in InterpreterPrimitives>>signed32BitValueOf:<br>
but I'm not clear on whether this is something that affects<br>
Alien, or if it is something that has been causing problems<br>
more generally but went unnoticed. Also, I'd like to document<br>
this with a unit test, so if you can suggest a code snippet<br>
that would be great.<br></blockquote><div><br></div><div>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:</div>
<div><br></div><div><div><span class="Apple-tab-span" style="white-space:pre">        </span><var: #value type: #int></div></div><div>...</div><div><div><span class="Apple-tab-span" style="white-space:pre">                </span> (negative</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span> and: [self</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>cCode: [value - 1 > 0]</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>inSmalltalk: [value = -16r80000000]]) ifTrue: "Don't fail for -2147483648 /-16r80000000"</div>
</div><div><br></div><div>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.</div>
<div><br></div><div>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:</div><div><br></div><div><div><span class="Apple-tab-span" style="white-space:pre">                </span> (negative and: [0 = (self cCode: [value << 1]</div>
<div><span class="Apple-tab-span" style="white-space:pre">                                                        </span>inSmalltalk: [value << 1 bitAnd: (1 << 32) - 1])]) ifTrue:</div></div><div><br></div><div>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.</div>
<div><br></div><div>And to those C compilers, grrr.... ;)</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
TIA,<br>
Dave<br>
<br>
</blockquote></div><br><br clear="all"><br>-- <br>best,<div>Eliot</div><br>