[Vm-dev] clang and bytecodePrimMultiply
John McIntosh
johnmci at smalltalkconsulting.com
Tue Nov 24 19:58:04 UTC 2015
yet more
https://llvm.org/bugs/show_bug.cgi?id=25552;
On Tue, Nov 24, 2015 at 11:44 AM, Eliot Miranda <eliot.miranda at gmail.com>
wrote:
>
> Hi All,
>
> I'm trying to use clang in Xcode on Mac OS X to compile a new 32-bit
> VM. One of my installations is Mavericks 10.9 with Xcode 6.2 and clang
> 6.0. The other is 10.10.5 with Xcode 7.1 and clang 7.0. Both seem to have
> problems with the integer side of bytecodePrimMultiply, the interpreter's
> multiplication routine:
>
> CASE(184)
> /* bytecodePrimMultiply */
> {
> sqInt arg;
> sqInt rcvr;
> sqInt result;
> char *sp;
>
> VM_LABEL(bytecodePrimMultiply);
> rcvr = longAtPointer(localSP + (1 * BytesPerOop));
> arg = longAtPointer(localSP + (0 * BytesPerOop));
> if (((rcvr & arg) & 1) != 0) { // both SmallIntegers?
> rcvr = (rcvr >> 1); // convert from SmallInteger to
> value
> arg = (arg >> 1);
> result = rcvr * arg; // multiply
> if ((arg == 0)
> || (((result / arg) == rcvr) // check for overflow
> && ((((sqInt)(result ^ (result << 1)))) >= 0))) { //
> check for SmallInteger overflow
> /* begin internalPop:thenPush: */
> longAtPointerput((localSP += (2 - 1) *
> BytesPerOop), ((result << 1) | 1));
> /* begin fetchNextBytecode */
> currentBytecode = byteAtPointer(++localIP);
>
> goto l58;
> }
> }
> else {
>
> clang 6 inserts a spurious instruction at 0x36799:
>
> 0x36784: 89 ca movl %ecx, %edx // both SmallIntegers?
> 0x36786: 83 e2 01 andl $0x1, %edx
> 0x36789: 85 d0 testl %eax, %edx
> 0x3678b: 74 6b je 0x367f8
> 0x3678d: d1 f9 sarl %ecx // convert from SmallInteger to value
> 0x3678f: d1 f8 sarl %eax
> 0x36791: 0f af c8 imull %eax, %ecx // do the multiply
> 0x36794: 8d 14 09 leal (%ecx,%ecx), %edx
> 0x36797: 85 c0 testl %eax, %eax
> 0x36799: 89 f7 movl %esi, %edi // AFAICS, totally spurious
> 0x3679b: 74 08 je 0x367a5
> 0x3679d: 31 d1 xorl %edx, %ecx // check for SmallInteger overflow
> 0x3679f: 0f 88 96 01 00 00 js 0x3693b
> 0x367a5: 83 ca 01 orl $0x1, %edx
>
> clang 7 does better:
> 0x36741: 89 ca movl %ecx, %edx // both SmallIntegers?
> 0x36743: 83 e2 01 andl $0x1, %edx
> 0x36746: 85 d0 testl %eax, %edx
> 0x36748: 74 67 je 0x367b1
> 0x3674a: d1 f9 sarl %ecx // convert from SmallInteger to value
> 0x3674c: d1 f8 sarl %eax
> 0x3674e: 0f af c8 imull %eax, %ecx // do the multiply
> 0x36751: 8d 14 09 leal (%ecx,%ecx), %edx
> 0x36754: 85 c0 testl %eax, %eax
> 0x36756: 74 08 je 0x36760
> 0x36758: 31 d1 xorl %edx, %ecx // check for SmallInteger overflow
> 0x3675a: 0f 88 a9 01 00 00 js 0x36909
> 0x36760: 83 ca 01 orl $0x1, %edx
>
>
> What I don't understand is how, given
>
> typedef long sqInt;
> sqInt arg;
> sqInt rcvr;
> sqInt result;
> ...
> result = rcvr * arg; // multiply
>
> clang reasons it doesn't need to evaluate
>
> || (((result / arg) == rcvr) // check for overflow
>
> Given that arg and receiver can both have values > 64k, the result can of
> course overflow and there's no guarantee that because result = rcvr * arg,
> that (result / arg) == rcvr.
>
> Am I missing something? Are there flags I should be using? This looks
> like a pretty basic issue.
>
> _,,,^..^,,,_
> best, Eliot
>
>
--
===========================================================================
John M. McIntosh. Corporate Smalltalk Consulting Ltd
https://www.linkedin.com/in/smalltalk
===========================================================================
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20151124/7fc04e84/attachment.htm
More information about the Vm-dev
mailing list