Scheduler hoists an x86 IMUL (clobbers %eax) ahead of the first reference to a parameter passed in %eax.
% /Volumes/sandbox/stuart/gcc.fsf.pure.debug.obj/gcc/cc1 reduce.c -quiet -mtune=generic -O2 -fschedule-insns reduce.c: In function '_perfInitPerfTable': reduce.c:43: error: unable to find a register to spill in class 'AREG' reduce.c:43: error: this is the insn: (insn:HI 21 83 9 2 (parallel [ (set (reg/v:SI 5 di [orig:66 maxNvClk ] [66]) (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (mem/s:SI (plus:SI (reg/v/f:SI 1 dx [orig:71 thisPerf ] [71]) (const_int 80 [0x50])) [7 <variable>.MaxNvclkAllowed+0 S4 A32])) (zero_extend:DI (reg:SI 3 bx [78]))) (const_int 32 [0x20])))) (clobber (scratch:SI)) (clobber (reg:CC 17 flags)) ]) 189 {*umulsi3_highpart_insn} (nil) (expr_list:REG_DEAD (reg/v/f:SI 1 dx [orig:71 thisPerf ] [71]) (expr_list:REG_DEAD (reg:SI 3 bx [78]) (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_UNUSED (scratch:SI) (nil)))))) reduce.c:43: internal compiler error: in spill_failure, at reload1.c:1911 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. Here is the testcase: typedef unsigned long U32; typedef U32 U032; typedef struct RMTIMEOUT { } NODE, *PNODE; typedef struct OBJP OBJP, *POBJP; typedef struct OBJPERF *POBJPERF; typedef struct _def_ext_y_gen_params { U032 G; } YFREQ, *PYFREQ; typedef void PerfInitPerfTables (POBJP, POBJPERF); typedef struct _perf_level { YFREQ Y; } PERF_LEVEL, *PPERF_LEVEL; typedef struct _perf_table { PERF_LEVEL Levels[10]; } PERF_TABLE, *PPERF_TABLE; struct OBJPERF { PERF_TABLE lowPower; PERF_TABLE fullPower; U032 MaxyAllowed; PerfInitPerfTables *perfInitPerfTables; }; static PerfInitPerfTables perfInitPerfTables; void constructObjPerf(POBJPERF thisPerf, U032 thisPublicHalID) { thisPerf->perfInitPerfTables = perfInitPerfTables; } static U032 _perfInitPerfTable(POBJP pP, POBJPERF thisPerf, PPERF_TABLE pPerfTable, U032 startEntry, U032 flagMask, U032 flagVal) { U032 i, matchingLevels = 0; U032 maxY, maxMY; maxY = thisPerf->MaxyAllowed / (10 * 1000); for (i = 0; i < 10; i++) { if (DevinitGetPerfLevelEntry(pP, startEntry + i, &pPerfTable->Levels[i]) != 0x00000000) break; if (maxY) { if (pPerfTable->Levels[i].Y.G > maxY) pPerfTable->Levels[i].Y.G = maxY; } } } static void perfInitPerfTables(POBJP pP, POBJPERF thisPerf) { U032 i, data, levelsFound; levelsFound = _perfInitPerfTable(pP, thisPerf, &thisPerf->lowPower, 0, (1<<(0)), 0); levelsFound = _perfInitPerfTable(pP, thisPerf, &thisPerf->fullPower, levelsFound, (1<<(0)), 1); } -- Summary: ICE: x86 scheduler upsets local reg alloc Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: stuart at apple dot com GCC build triplet: i386-apple-darwin8.7.2 GCC host triplet: i386-apple-darwin8.7.2 GCC target triplet: i386-apple-darwin8.7.2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28019