Thread overview
[Issue 17220] invalid code with -m32 -inline and struct that's size_t.sizeof x the size of an assigned enum value
[Issue 17220] invalid code with -m32 -inline and struct that's 4x the size of an assigned enum value
Feb 24, 2017
Stefan Koch
Feb 24, 2017
Stefan Koch
Feb 24, 2017
Martin Nowak
Feb 24, 2017
Martin Nowak
Feb 24, 2017
Martin Nowak
February 24, 2017
https://issues.dlang.org/show_bug.cgi?id=17220

Stefan Koch <uplink.coder@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |uplink.coder@gmail.com
                 OS|Linux                       |All
           Severity|normal                      |major

--
February 24, 2017
https://issues.dlang.org/show_bug.cgi?id=17220

Stefan Koch <uplink.coder@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Hardware|x86                         |x86_64

--- Comment #1 from Stefan Koch <uplink.coder@gmail.com> ---
Happens on 64bit as well
Slightly modified:

void emitArithInstruction2(BCValue lhs)
{
    if (lhs.type != BCTypeEnum.i32) // type get's overwritten
        assert(0);
}

enum BCTypeEnum : ubyte
{
    Undef,
    i32 = 8, // value must be >= 8
}

struct BCValue // size must be size_t.sizeof x BCTypeEnum.i32
{
    BCTypeEnum type; // position doesn't matter
    ubyte[size_t.sizeof * BCTypeEnum.i32 - type.sizeof] more;
}
static assert(BCValue.sizeof == size_t.sizeof * BCTypeEnum.i32);

BCValue i32()
{
    BCValue result; // must be default 0 initialized
    result.type = BCTypeEnum.i32; // set value
    return result;
}

void main()
{
    auto val = i32();
    emitArithInstruction2(val);
}
CODE

--
February 24, 2017
https://issues.dlang.org/show_bug.cgi?id=17220

Martin Nowak <code@dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Hardware|x86_64                      |All
            Summary|invalid code with -m32      |invalid code with -m32
                   |-inline and struct that's   |-inline and struct that's
                   |4x the size of an assigned  |size_t.sizeof x the size of
                   |enum value                  |an assigned enum value
                 OS|All                         |Linux

--- Comment #2 from Martin Nowak <code@dawg.eu> ---
Ah thanks for size_t.sizeof times enum value finding.
This is easily the weirdest backend bug I've seen so far.

--
February 24, 2017
https://issues.dlang.org/show_bug.cgi?id=17220

--- Comment #3 from Martin Nowak <code@dawg.eu> ---
The cmp runs on the `lhs` symbol, while only the `val` symbol get's
initialized.
Not sure, but seems like the copy got elided.

Here is the assembly for when the size of BCValue != size_t.sizeof * BCTypeEnum.i32

        mov     cl, 8                                   ; 0018 _ B1, 08
        mov     byte ptr [rbp-78H], cl                  ; 001A _ 88. 4D, 88
        lea     rsi, [rbp-78H]                          ; 001D _ 48: 8D. 75, 88
        lea     rdi, [rbp-38H]                          ; 0021 _ 48: 8D. 7D, C8
        mov     cl, 7                                   ; 0025 _ B1, 07
        rep movsq                                       ; 0027 _ F3 48: A5
        cmp     byte ptr [rbp-38H], 8                   ; 002A _ 80. 7D, C8, 08
        jz      ?_003                                   ; 002E _ 74, 0A

Apparently the `mov cl, 8` instruction is a CSE in the bug case, no idea why the rep movsq get's omitted b/c of that though.

--
February 24, 2017
https://issues.dlang.org/show_bug.cgi?id=17220

Martin Nowak <code@dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #4 from Martin Nowak <code@dawg.eu> ---
This got accidentally fixed by https://github.com/dlang/dmd/pull/6410/files#diff-0630e1297bdecef97aded9af2ddb879cL4041.

Seems like the problem was indeed a CSE which caused that no code was generated for `mov cl, 8`, but the following `gen1(c3, 0xF3)` didn't deal with c3 being CNIL, hence the code wasn't appended/emitted.

--
March 12, 2017
https://issues.dlang.org/show_bug.cgi?id=17220

--- Comment #5 from github-bugzilla@puremagic.com ---
Commit pushed to newCTFE at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/3dc0fa957ef362ba42779e3dd953931f9a908f45 workaround Issue #17220

--