Thread overview
Another interesting difference
Dec 12, 2013
bearophile
Dec 12, 2013
David Nadlinger
Dec 13, 2013
Kai Nacke
Dec 16, 2013
Kai Nacke
December 12, 2013
I am trying the following program with both the latest dmd 2.065alpha and ldc2 2.063.2, with no optimizations:


int fun(int[3] a) {
    return a[0]+ a[1] + a[2];
}
int main() {
    int total = 0;
    foreach (immutable _; 0 .. 100_000_000)
        total += fun([1, 2, 3]);
    return total;
}


The results, both in run-time and x86 asm:

-------------------------

dmd test2.d
runtime: 0.81

_D5test23funFG3iZi  comdat
        mov EAX,4[ESP]
        add EAX,8[ESP]
        add EAX,0Ch[ESP]
        ret 0Ch

__Dmain comdat
L0:     enter   014h,0
        push    EBX
        xor EAX,EAX
        mov -014h[EBP],EAX
        mov -010h[EBP],EAX
LD:     cmp dword ptr -010h[EBP],05F5E100h
        jge L47
        mov ECX,-010h[EBP]
        mov EDX,1
        mov -0Ch[EBP],EDX
        mov dword ptr -8[EBP],2
        mov dword ptr -4[EBP],3
        lea EBX,-0Ch[EBP]
        push    dword ptr 8[EBX]
        push    dword ptr 4[EBX]
        push    dword ptr [EBX]
        call    near ptr _D5test23funFG3iZi
        add -014h[EBP],EAX
        inc dword ptr -010h[EBP]
        jmp short   LD
L47:        mov EAX,-014h[EBP]
        pop EBX
        leave
        ret

-------------------------

ldmd2 test2.d
runtime: 1.94


ldmd2 -output-s test2.d

__D5test23funFG3iZi:
    subl    $28, %esp
    leal    32(%esp), %eax
    movb    $1, %cl
    testb   $1, %cl
    movl    %eax, 24(%esp)
    jne LBB0_2
    jmp LBB0_1
LBB0_1:
    leal    __D5test212__ModuleInfoZ, %eax
    movl    $2, %ecx
    movl    %eax, (%esp)
    movl    $2, 4(%esp)
    movl    %ecx, 20(%esp)
    calll   __d_array_bounds
LBB0_2:
    movb    $1, %al
    testb   $1, %al
    jne LBB0_4
    leal    __D5test212__ModuleInfoZ, %eax
    movl    $2, %ecx
    movl    %eax, (%esp)
    movl    $2, 4(%esp)
    movl    %ecx, 16(%esp)
    calll   __d_array_bounds
LBB0_4:
    movb    $1, %al
    movl    24(%esp), %ecx
    movl    (%ecx), %edx
    addl    4(%ecx), %edx
    testb   $1, %al
    movl    %edx, 12(%esp)
    jne LBB0_6
    leal    __D5test212__ModuleInfoZ, %eax
    movl    $2, %ecx
    movl    %eax, (%esp)
    movl    $2, 4(%esp)
    movl    %ecx, 8(%esp)
    calll   __d_array_bounds
LBB0_6:
    movl    24(%esp), %eax
    movl    8(%eax), %ecx
    movl    12(%esp), %edx
    addl    %ecx, %edx
    movl    %edx, %eax
    addl    $28, %esp
    ret $12

__Dmain:
    subl    $40, %esp
    movl    $0, 36(%esp)
    movl    $0, 32(%esp)
    movl    $100000000, 28(%esp)
LBB1_1:
    cmpl    $100000000, 32(%esp)
    jge LBB1_4
    movl    32(%esp), %eax
    movl    %eax, 24(%esp)
    movl    $3, 20(%esp)
    movl    $2, 16(%esp)
    movl    $1, 12(%esp)
    movl    20(%esp), %eax
    movl    %esp, %ecx
    movl    %eax, 8(%ecx)
    movsd   12(%esp), %xmm0
    movsd   %xmm0, (%ecx)
    calll   __D5test23funFG3iZi
    subl    $12, %esp
    movl    36(%esp), %ecx
    addl    %eax, %ecx
    movl    %ecx, 36(%esp)
    movl    32(%esp), %eax
    addl    $1, %eax
    movl    %eax, 32(%esp)
    jmp LBB1_1
LBB1_4:
    movl    36(%esp), %eax
    addl    $40, %esp
    ret

-------------------------

Do you know why ldc2 puts array bound tests inside fun()? The array 'a' inside fun() is a fixed size array, so there is no need to verify at run-time that 0 1 2 are within the array bounds.

Bye,
bearophile
December 12, 2013
On 12 Dec 2013, at 10:00, bearophile wrote:
> Do you know why ldc2 puts array bound tests inside fun()? The array 'a' inside fun() is a fixed size array, so there is no need to verify at run-time that 0 1 2 are within the array bounds.

I don't know why we are, but we shouldn't: https://github.com/ldc-developers/ldc/issues/553

David
December 13, 2013
On Thursday, 12 December 2013 at 09:37:36 UTC, David Nadlinger wrote:
> On 12 Dec 2013, at 10:00, bearophile wrote:
>> Do you know why ldc2 puts array bound tests inside fun()? The array 'a' inside fun() is a fixed size array, so there is no need to verify at run-time that 0 1 2 are within the array bounds.
>
> I don't know why we are, but we shouldn't: https://github.com/ldc-developers/ldc/issues/553
>
> David

This is the solution:

https://github.com/ldc-developers/ldc/pull/554

Regards,
Kai
December 16, 2013
On Thursday, 12 December 2013 at 09:00:08 UTC, bearophile wrote:
> I am trying the following program with both the latest dmd 2.065alpha and ldc2 2.063.2, with no optimizations:
>
[..snip..]
> Do you know why ldc2 puts array bound tests inside fun()?

Yes! There was no check for this situation in ldc2. Bounds checking code was emitted for all array references. dmd 2.064 omits the bounds checking code if the access can be checked at compile time. Therefore you see the difference.

I fixed this in the master and the merge-2.064 branch. The next release will include the fix.

Regards,
Kai