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.  It seems like the idea was to note the 
spill_failure and then try and fix it by jumping to the "failed:" label, but 
obviously this never happens due to the call to spill_failure.  A spill failure 
like this looks very fixable and I would expect the previously live register 
(cc=x) to be spilled.  Is there a reason this isn't attempted here?

Thanks,
Stu

Reply via email to