Created attachment 1478
Test case
With the attached code dmd exits with an internal error, when compiling with optimizations on.
"dmd -O"
Commenting out line 13. or Making the Enum smaller the error no longer occurs.
Comment #1 by ketmar — 2015-02-22T21:54:01Z
this is general arch-independent optimiser bug, so i changed hardware section.
Comment #2 by k.hara.pg — 2015-06-22T07:03:25Z
Further reduced test case:
alias TypeTuple(T...) = T;
alias members = TypeTuple!(
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0, // error will disappear by removing one element
);
void main()
{
int row = 0;
foreach (_unused; members) // copy the loop body 100 times
{
++row;
if (row)
row = 0; // error triggered by this line.
}
}
----------------------
The ICE seems happened by the assertion with incorrect assumption for "infinite loop check". But I'm not sure the correct iteration limit...
backend/go.c =======
// Each pass through the loop can reduce only one level of comma expression.
// The infinite loop check needs to take this into account.
// Add 100 just to give optimizer more rope to try to converge.
int iterationLimit = 0;
for (b = startblock; b; b = b->Bnext)
{
if (!b->Belem)
continue;
int d = el_countCommas(b->Belem) + 100;
if (d > iterationLimit)
iterationLimit = d;
}
// Some functions can take enormous amounts of time to optimize.
// We try to put a lid on it.
starttime = clock();
do
{
//printf("iter = %d\n", iter);
if (++iter > 200)
{ assert(iter < iterationLimit); // infinite loop check
<-- the assert is on line 242
break;
}
Comment #3 by timothee.cour2 — 2017-01-03T22:15:14Z
the core issue is that optimizer is failed to distinguish comma expressions from enumerations, so it sees huge enumeration as alot of comma-expressions, tries to optimize that and fails. in my hackfix i just made optimizer to give up if it sees "alot of commas".
Comment #6 by timothee.cour2 — 2017-01-03T22:50:17Z
NOTE: ldc doesn't have this issue and is faster;
for this particular bug, a workaround as to use
```
s/foreach(_a; members)/foreach(_a; [members])/
```
but it won't work if types are distinct