Bug 14214 – Internal error: backend/go.c 242

Status
RESOLVED
Resolution
WORKSFORME
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-02-22T18:27:48Z
Last change time
2020-03-21T03:56:32Z
Keywords
ice
Assigned to
No Owner
Creator
Mike Wey

Attachments

IDFilenameSummaryContent-TypeSize
1478bug.dTest casetext/x-dsrc3452
16300001-fix_14214.patchhackfixtext/plain1442

Comments

Comment #0 by mike — 2015-02-22T18:27:48Z
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
Comment #4 by ketmar — 2017-01-03T22:26:48Z
Created attachment 1630 hackfix
Comment #5 by ketmar — 2017-01-03T22:29:28Z
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