www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 13190] New: Optimizer breaks comparison with zero

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

          Issue ID: 13190
           Summary: Optimizer breaks comparison with zero
           Product: D
           Version: D1 & D2
          Hardware: x86
                OS: All
            Status: NEW
          Keywords: wrong-code
          Severity: critical
          Priority: P1
         Component: DMD
          Assignee: nobody puremagic.com
          Reporter: yebblies gmail.com

This code, compiled with -release -O, breaks on win32 and linux32 (and
presumably other32).

The for loop comparison (table[i].a != 0) gets implemented as a load+or+bne,
but the increment for the loop index gets inserted between the or and the loop,
which trashes the flags register.  This results in an infinite loop and
eventually a segfault.

extern(C) int printf(const(char)*,...);

struct Struct
{
    ulong a;
    uint b;
};

__gshared Struct[] table = 
[
    Struct(1, 1),
    Struct(0, 2)
];

void main()
{
    for (int i = 0; table[i].a; i++)
    {
        ulong tbl = table[i].a;
        printf("i:%d stc:%lld\n", i, tbl);
        if (1 + tbl)
        {
            if (tbl == 0x80000)
                return;
        }
    }
}

condition asm: _003 == array base, ebx = current offset, esi = loop index
?_016:  add     ebx, 16                                 ; 005E _ 83. C3, 10
        mov     ecx, dword ptr [?_003]                  ; 0061 _ 8B. 0D,
00000034(segrel)
        mov     edx, dword ptr [ebx+ecx+4H]             ; 0067 _ 8B. 54 0B, 04
        or      edx, dword ptr [ebx+ecx]                ; 006B _ 0B. 14 0B
        inc     esi                                     ; 006E _ 46
        jnz     ?_014                                   ; 006F _ 75, A4

--
Jul 22 2014