On Wednesday, 7 February 2018 at 13:50:06 UTC, Bastiaan Veelo wrote:
On Wednesday, 7 February 2018 at 11:37:19 UTC, Michael wrote:
Does it work with slightly varied examples like where a = -1, and is incremented etc.?

I played with it here https://run.dlang.io/is/15sr6c and every variation I tried worked (correctly). So the example seems to be pretty minimal. Maybe someone understanding assembly is able to see what is going on after pressing that nice [ASM] button?

You don't need to understand assembler to grasp what's going on. A printf does a good job too:

    printf("%d\n", a); // 1908874352

It's even more fun, reduce the size of the static array to 8:

    ubyte[8][1] data; // works

However, with 7 it fails again:

    ubyte[7][1] data;

If you look at the assembly you will see that the compiler didn't even include the assert calls for even static arrays:

https://run.dlang.io/is/Qkt1nA (-O)
https://run.dlang.io/is/7UfmXJ (-O [8])
https://run.dlang.io/is/QrtNeI (normal)


Here's an annotated excerpt from the normal build:

---
                dec     qword ptr -010h[RBP]
                xor     EDX,EDX                ; a--
                mov     -8[RBP],DL
                test    DL,DL                  ; if (b)
                je      L5C
                jmp short       L18            ; goto loop
L5C:            cmp     qword ptr -010h[RBP],0FFFFFFFFFFFFFFFFh
                je      L78                    ; assert(a == -1)
                mov     DL,0Ah
                lea     RSI,_TMP0@PC32[RIP]
                lea     RDI,_TMP0@PC32[RIP]
                call      __assert@PLT32
L78:            xor     EAX,EAX
---


The same looks slightly different with -O.
Here with printf and a different value to be compared with a because it's easier to read:

---
main:
                push    RBP
                mov     RBP,RSP
                sub     RSP,010h
                lea     RAX,-010h[RBP]
                xor     ECX,ECX
                mov     [RAX],RCX
                mov     8[RAX],CL
                lea     RSI,-010h[RBP]
                lea     RDI,-010h[RBP]
                movsd
                movsb
mov RSI,01C71C71C71C71C70h ; 2 function argument (value of a) lea RDI,FLAT:.rodata[00h][RIP] ; "%d" (1st function argument)
                xor     EAX,EAX                         ; set eax to 0
                call      printf@PLT32                  ; printf("%d", a)
                mov     EDX,0Ch
lea RSI,_TMP0@PC32[RIP] ; load function arguments (in reverse order)
                lea     RDI,_TMP0@PC32[RIP]
call __assert@PLT32 ; values load, let's call assert
                add     [RAX],AL
.text.main      ends
        end
----

So the optimizer seems to be confused and wrongly precomputes a.
Note that if you change something, a will be correctly statically set in the printf too:

---
                mov     RSI,0FFFFFFFFh                ; look ma - a is now -1
                lea     RDI,FLAT:.rodata[00h][RIP]
                xor     EAX,EAX                       ; set eax to 0
                call      printf@PLT32
---

Reply via email to