[Issue 18730] New: dmd miscompiles core.bitop.bt with -O

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed Apr 4 23:52:51 UTC 2018


https://issues.dlang.org/show_bug.cgi?id=18730

          Issue ID: 18730
           Summary: dmd miscompiles core.bitop.bt with -O
           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

Spin-off from issue 18717 which can be closed as a duplicate when this one gets
fixed.

----
void main()
{
    enum bitsPerSizeT = size_t.sizeof * 8;
    enum bitIndex = int.max + 1L;
    auto a = new size_t[](bitIndex / bitsPerSizeT + 1);
    bt(a.ptr, bitIndex);
}

/* Copied from core.bitop. */
int bt(in size_t* p, size_t bitnum) pure @system
{
    static if (size_t.sizeof == 8)
        return ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0;
    else static if (size_t.sizeof == 4)
        return ((p[bitnum >> 5] & (1  << (bitnum & 31)))) != 0;
    else
        static assert(0);
}
----

Compile with `-O`. Resulting program segfaults.

Generated code for the bt function:

----
   0:   55                      push   rbp
   1:   48 8b ec                mov    rbp,rsp
   4:   0f a3 3e                bt     DWORD PTR [rsi],edi
   7:   19 c0                   sbb    eax,eax
   9:   f7 d8                   neg    eax
   b:   5d                      pop    rbp
   c:   c3                      ret
----

edi should be rdi in the bt instruction.

It's hard to find information on this, but this page says that bt interprets
the offset as signed: <http://faydoc.tripod.com/cpu/bt.htm>. That explains the
segfault, even though `bitIndex` fits into a uint.

--


More information about the Digitalmars-d-bugs mailing list