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: nob...@puremagic.com Reporter: ag0ae...@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. --