D-Programming-Language/dmd — pull request #937 by donc (2012-05-09 14:54:35+00:00)
Title: 5809 [64 bit] wrong code for *p, when widening conversion occurs

Need to zero-extend the register BEFORE saving the result.
This needs to be run on the backend test suite as well.

Given this code:

ushort *p = &x[0];
uint b = *p; // this causes the next line to fail
if (*p) {... }

The generated code in cdshtlng() was c1,c2,c3, c4:

mov	RAX,offset FLAT:_D3feq4mainFZv1xxG4t@64 // p = &x[0]
mov	CX,[RAX] // c1
mov	-8[RBP],RCX // c2
movzx	ECX,CX // c3
mov	ECX,ECX // c4

cmp	dword ptr -8[RBP],0
je	L29

But RCX is uninitialized, so the top 48 bits of -8[RBP] are garbage.
After this change, it is now:

mov	RAX,offset FLAT:_D3feq4mainFZv1xxG4t@64

mov	CX,[RAX] // c1
movzx	ECX,CX // c3
mov	-8[RBP],RCX // c2
mov	ECX,ECX // c4

cmp	dword ptr -8[RBP],0
je	L29

Now I still don't know why c4 is generated.
Also, it still saves garbage into the top 32bits of -8[EBP], but at least it only thinks the bottom 32 are valid.