Bug 18749 – bt instruction using 64-bit register for 32-bit offset

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2018-04-09T22:44:05Z
Last change time
2020-06-25T02:36:01Z
Keywords
pull, wrong-code
Assigned to
No Owner
Creator
ag0aep6g
Blocks
18750

Comments

Comment #0 by ag0aep6g — 2018-04-09T22:44:05Z
---- 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.
Comment #1 by dlang-bot — 2020-06-21T06:10:15Z
@WalterBright created dlang/dmd pull request #11304 "fix Issue 18749 - bt instruction using 64-bit register for 32-bit offset" fixing this issue: - fix Issue 18749 - bt instruction using 64-bit register for 32-bit offset https://github.com/dlang/dmd/pull/11304
Comment #2 by dlang-bot — 2020-06-25T02:36:01Z
dlang/dmd pull request #11304 "fix Issue 18749 - bt instruction using 64-bit register for 32-bit offset" was merged into master: - 94fe8606b02f7065d85393ed9d2685a55012378a by Walter Bright: fix Issue 18749 - bt instruction using 64-bit register for 32-bit offset https://github.com/dlang/dmd/pull/11304