On 02/07/2012 07:42 PM, Henderson, Stuart wrote: > Hi, > I'm investigating the following ICE building the Blackfin compiler from trunk: > /home/shender/gnu-upstream/toolchain/gcc-4.7/libgfortran/generated/eoshift1_4.c: > In function ÃâËeoshift1Ãââ: > /home/shender/gnu-upstream/toolchain/gcc-4.7/libgfortran/generated/eoshift1_4.c:250:1: > error: unable to find a register to spill in class ÃâËCCREGSÃââ > /home/shender/gnu-upstream/toolchain/gcc-4.7/libgfortran/generated/eoshift1_4.c:250:1: > error: this is the insn: > (insn 546 540 479 46 (set (reg:BI 455) > (le:BI (reg/v:SI 6 R6 [orig:122 size ] [122]) > (const_int 0 [0]))) > /home/shender/gnu-upstream/toolchain/gcc-4.7/libgfortran/generated/eoshift1_4.c:212 > 119 {compare_le} > (nil)) > /home/shender/gnu-upstream/toolchain/gcc-4.7/libgfortran/generated/eoshift1_4.c:250:1: > internal compiler error: in spill_failure, at reload1.c:2123 > > > The problem occurs when the ce2 pass does an IF-CASE-2 transformation, moving > an instruction which sets the condition code register into a block between > another instruction which sets the condition code register and its > conditional jump. > > e.g. > block 44: > set cc = x; > if cc jump; > ... > block 49: > set cc = y; > block 51: > if cc jump; > > gets transformed into... > > block 44: > set cc = x; > set cc = y; > if cc jump; > ... > block 51: > if cc jump; > > When we reach cc=y in > reload1.c:reload()->select_reload_regs()->find_reload_regs(), find_reg() > fails and we call spill_failure(), which doesn't return. However, right > after the call to spill_failure, we set the failure flag, which is > checked for right after select_reload_regs returns. I'm a little > confused as to what the intention of this code was.
spill_failure does return for asms since we don't want to ICE on bad user code. That's all that's going on here. It sounds like ifcvt needs to be fixed. Your example: > block 44: > set cc = x; > set cc = y; (*) > if cc jump; looks like an invalid transformation, but I suspect rather than setting the CC register, the (*) insn is setting a pseudo (more accurate RTL would be useful). There are some cases in ifcvt.c which check targetm.small_register_classes_for_mode already, this is probably what should be done to prevent this transformation. Bernd