www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 13711] New: Optimizer bug (yet another one, with test case)

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

          Issue ID: 13711
           Summary: Optimizer bug (yet another one, with test case)
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Keywords: wrong-code
          Severity: normal
          Priority: P1
         Component: DMD
          Assignee: nobody puremagic.com
          Reporter: Marco.Leise gmx.de

Created attachment 1452
  --> https://issues.dlang.org/attachment.cgi?id=1452&action=edit
test case source code

I get a segmentation fault with -O -release for the read of *src in the
following partial function:

--------8<--------
ubyte* src = …;
uint c;
final switch (pixelSize)
{
    case 16:
        foreach (w; 0 .. count)
        {
            c = *src & 0b000_11111;
            c |= (*src++ & 0b111_00000) << (8-5);
            src++;
            c |= (*src & 0b0_00000_11) << (8+3);
            c |= (*src & 0b0_11111_00) << (16-2);
            src++;                          // *** problematic instruction
            (dst++).color = 0xFF000000 | (c << 3);
        }
        break;
    case 24:
        foreach (w; 0 .. count)
        {
            c = 0xFF000000 | *(src++) | (*(src++) << 8) | (*(src++) << 16);
            (dst++).color = c;
        }
        break;
    case 32:
        foreach (w; 0 .. count)
        {
            c = 0xFF000000 | *(src++) | (*(src++) << 8) | (*(src++) << 16);
            src++;
            (dst++).color = c;
        }
        break;
}
-------->8--------

If I change the location of the problematic instruction from:

    c |= (*src & 0b0_11111_00) << (16-2);
    src++;

to:

    c |= (*src++ & 0b0_11111_00) << (16-2);

I get no crash and the function completes. I was also able to fix it with a
function call right before the snippet, so it is likely to be affected by CPU
register allocation(?)

When I created a test case and removed some files the crash with the -O
-release switches disappeared but could be  reproduced again with `dmd -O
-release -inline main.d && ./main`. The test case requires the .tga file to
work.

--
Nov 11 2014