#dbugfix Issue 16189

Seb seb at wilzba.ch
Wed Feb 7 14:37:30 UTC 2018


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 at PC32[RIP]
		lea	RDI,_TMP0 at PC32[RIP]
		call	  __assert at 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 at PLT32                  ; printf("%d", a)
		mov	EDX,0Ch
		lea	RSI,_TMP0 at PC32[RIP]             ; load function arguments 
(in reverse order)
		lea	RDI,_TMP0 at PC32[RIP]
		call	  __assert at 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 at PLT32
---


More information about the Digitalmars-d mailing list