D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 12862 - [ICE] backend assertion (Internal error: backend/cg87.c 331) with inline, optimizing and floats
Summary: [ICE] backend assertion (Internal error: backend/cg87.c 331) with inline, opt...
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 Linux
: P1 critical
Assignee: No Owner
URL:
Keywords: ice, ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2014-06-06 01:28 UTC by Martin Nowak
Modified: 2020-03-21 03:56 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Martin Nowak 2014-06-06 01:28:03 UTC
cat > bug.d << CODE
struct FRect
{
    float left, top, right, bottom;
}

void formatValue(float obj)
{
    static void byRef(ref float a) {}
    byRef(obj);
}

void formatValue(FRect val)
{
    formatValue(val.left);
    formatValue(val.top);
}

struct Foo
{
    void bug()
    {
        formatValue(bounds);
    }

    @property FRect bounds()
    {
        if (&this !is null)
            return FRect();
        else
            return FRect();
    }
}
CODE

dmd -c -O -inline bug.d
----
Internal error: backend/cg87.c 331
----

The assertion is in
    STATIC code * makesure87(elem *e,unsigned offset,int i,unsigned flag)

    assert(_8087elems[i].e == NULL);

Debug output for the assertion is
    _8087elems[0].e = 0x1050968, .offset = 8

Looks like a place in the floating point stack is still occupied by some older value. No idea how to fix this though.
Comment 1 yebblies 2014-06-07 23:57:39 UTC
I can't reproduce this on win32 or linux64
Comment 2 Martin Nowak 2014-06-16 21:36:34 UTC
Mmh, the codegen assertion vanished with this commit (https://github.com/D-Programming-Language/dmd/commit/9efe7f74c2462e8743f5a479cd04f9be733be4b0).
I reproduced another test case for the issue.

cat > bug.d << CODE
struct FPoint
{
    float x, y;
}

struct FRect
{
    float left, top, right, bottom;
    static FRect calcBounds(FPoint[] )
    {
        return FRect();
    }
}

struct Matrix
{
    FRect mapRect(FRect src) {
        FPoint[] pts = new FPoint[](1);
        pts[0].x = src.left;
        pts[0].y = src.top;
        return FRect.calcBounds(pts);
    }
}


// TODO: FPoint -> Point!T
struct Path
{
    @property FRect bounds()
    {
        if (points.length)
            return FRect();
        else
            return FRect();
    }

    FPoint[] points;
}

void foo()
{
    Matrix mat;
    Path path;
    mat.mapRect(path.bounds);
}
CODE

The issues first appeared with dmd2.060 and seems to be triggered by assigning tym = TYucent to 16 byte structs that consist of either 4 floats or 2 doubles in elstruct (https://github.com/D-Programming-Language/dmd/blob/5cc1c812227440d199f265dec8fb976bea7ad943/src/backend/cgelem.c#L3077). I don't understand that code good enough to fix the issue though.
Comment 3 basile-z 2019-03-10 21:39:00 UTC
this works fine nowadays (git 7036b216dcb5d2b8394ae5c12324227c8ca47187), w or w/o -O -inline, -m32 or -m64.