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

Reply via email to