Issue 18749 - bt instruction using 64-bit register for 32-bit offset
Summary: bt instruction using 64-bit register for 32-bit offset
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 Linux
: P1 normal
Assignee: No Owner
URL:
Keywords: pull, wrong-code
Depends on:
Blocks: 18750
  Show dependency treegraph
 
Reported: 2018-04-09 22:44 UTC by ag0aep6g
Modified: 2020-06-25 02:36 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description ag0aep6g 2018-04-09 22:44:05 UTC
----
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 Dlang Bot 2020-06-21 06:10:15 UTC
@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 Dlang Bot 2020-06-25 02:36:01 UTC
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