I posted this on the learn section of the forum earlier in the week, but I'm reasonably certain this is a compiler bug. Essentially, when I run some code which has inline assembly through the profiler, I get unexpected results. Here's a reproduction: // bsf is Bitscan Forward. It should return the index of the least significant bit which is on. ubyte LS1B(ulong board) { asm { bsf RAX, board; } } void main() { import std.conv; for (int i = 0; i < 63; ++i) { auto slide = (1UL << i); auto ls1b = slide.LS1B; assert(ls1b == i, "Incorrect LS1B ~ expected: " ~ i.to!string ~ " got: " ~ ls1b.to!string); } } If I run the above like so: dmd -debug app.d; ./app It doesn't assert. But if I run it like so: dmd -profile app.d; ./app It asserts, and comes back with a different answer every time.
DMD 2.070 on Arch Linux for reference.
The trouble is the profiler inserts function calls to the profiler library code in each function. This interferes with the register contents of RAX.
@WalterBright created dlang/dmd pull request #11608 "fix Issue 15745 - Inline Assembly stomped on by Profiling" fixing this issue: - fix Issue 15745 - Inline Assembly stomped on by Profiling https://github.com/dlang/dmd/pull/11608
dlang/dmd pull request #11608 "fix Issue 15745 - Inline Assembly stomped on by Profiling" was merged into master: - c557bcbcb2b52cd3faaa4bb698c0a3b0a9fdffe8 by Walter Bright: fix Issue 15745 - Inline Assembly stomped on by Profiling https://github.com/dlang/dmd/pull/11608