Hi,
I'm investigating an 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 the reload pass the CC reg is already in use from cc=x,
find_reg fails to find an alternative and we bomb out.
This seems like something IF-CASE-2 could do a lot, so is it supposed to avoid
such scenarios? or should reload handle the situation by finding the previous
use of CC and spilling it to memory?
Any pointers would be appreciated.
Thanks,
Stu