[Issue 18749] New: bt instruction using 64-bit register for 32-bit offset
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Mon Apr 9 22:44:05 UTC 2018
https://issues.dlang.org/show_bug.cgi?id=18749
Issue ID: 18749
Summary: bt instruction using 64-bit register for 32-bit offset
Product: D
Version: D2
Hardware: x86_64
OS: Linux
Status: NEW
Keywords: wrong-code
Severity: normal
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: ag0aep6g at gmail.com
----
ulong f(ulong* p, uint shift)
{
return (*p >> shift) & 1;
}
ulong g(ulong* p, ulong shift)
{
return f(p, cast(uint) shift);
}
void main()
{
enum shift = uint.max + 1L;
assert(cast(uint) shift == 0);
ulong s = 1;
assert(g(&s, shift));
}
----
Compile with `-O`. Resulting program segfaults.
Generated code for f and g:
----
0000000000000000 <_D4test1fFPmkZm>:
0: 55 push rbp
1: 48 8b ec mov rbp,rsp
4: 48 0f a3 3e bt QWORD PTR [rsi],rdi
8: 19 c0 sbb eax,eax
a: f7 d8 neg eax
c: 5d pop rbp
d: c3 ret
0000000000000000 <_D4test1gFPmmZm>:
0: 55 push rbp
1: 48 8b ec mov rbp,rsp
4: e8 00 00 00 00 call 9 <_D4test1gFPmmZm+0x9>
5: R_X86_64_PLT32 _D4test1fFPmkZm-0x4
9: 5d pop rbp
a: c3 ret
----
The bt instruction in f should use edi instead of rdi. The high bits of rdi are
garbage left over from the call to g.
The code for g is correct. It's only included to show what's going on: g
immediately calls f, without zeroing the high bits of rdi.
--
More information about the Digitalmars-d-bugs
mailing list