Updating @gcc.gnu.org email forwarding
Hi, I'm looking to update the forwarding address for my @gcc.gnu.org email address, but appear to have lost (if I ever had) my private key. Could someone point me in the right direction for fixing this? Thanks, Stu
RE: spill failure after IF-CASE-2 transformation
>Make an exception for BImode and small_register_classes_for_mode_p >(BImode). Thanks Bernd. Would this be acceptable: diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 8d81c89..e4e13ab 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -2295,7 +2295,9 @@ noce_get_condition (rtx jump, rtx *earliest, bool then_else_reversed) cond = XEXP (SET_SRC (set), 0); tmp = XEXP (cond, 0); - if (REG_P (tmp) && GET_MODE_CLASS (GET_MODE (tmp)) == MODE_INT) + if (REG_P (tmp) && GET_MODE_CLASS (GET_MODE (tmp)) == MODE_INT + && (GET_MODE (tmp) != BImode + || !targetm.small_register_classes_for_mode_p (BImode))) { *earliest = jump;
RE: spill failure after IF-CASE-2 transformation
>Not really. I think in dead_or_predicable you need to check in the > /* Try the NCE path if the CE path did not result in any changes. */ >block (I assume this is where we end up in this testcase) that none of >the live hard regs at the point where we are going to insert the insns >are in small register classes. small_register_classes_for_mode_p is >unfortunately not a good interface to answer that question. > >It looks like noce_get_condition probably didn't find the instruction >setting CC? Maybe you can paper over the problem for the moment by >making sure it does. The problem with noce_get_condition is that if the condition variable is a MODE_INT register it will return it and set earliest as the jump insn itself. I'm not sure why this is the case, but it seems like something we don't want to be doing in this situation. Is there a reasonable check that should be made to avoid noce_get_condition doing this? e.g. if the condition var is a reg and !small_register_classes_for_mode_p. Thanks, Stu
RE: spill failure after IF-CASE-2 transformation
Ping. >>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. > >You suspect correctly, cc=x sets CC whereas cc=y is a pseudo which can >only match CC. > >Presumably I must check all instructions in the else_bb for >modifications to small_register_classes_for_mode_p? e.g. see below. > >Does this seem reasonable? Patch here: http://gcc.gnu.org/ml/gcc/2012-02/msg00296.html Thanks, Stu
RE: spill failure after IF-CASE-2 transformation
>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. ahh, thanks. >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. You suspect correctly, cc=x sets CC whereas cc=y is a pseudo which can only match CC. Presumably I must check all instructions in the else_bb for modifications to small_register_classes_for_mode_p? e.g. see below. Does this seem reasonable? Thanks, Stu diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 8d81c89..b605a63 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -3924,6 +3924,7 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge) basic_block else_bb = else_edge->dest; edge else_succ; int then_prob, else_prob; + rtx insn; /* If we are partitioning hot/cold basic blocks, we don't want to mess up unconditional or indirect jumps that cross between hot @@ -3957,6 +3958,25 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge) /* ELSE has one predecessor. */ if (!single_pred_p (else_bb)) return FALSE; + + /* Avoid small_register_classes_for_mode_p dests. */ + FOR_BB_INSNS (else_bb, insn) +{ + rtx set, dest; + + if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn)) +continue; + set = single_set (insn); + if (!set) +return FALSE; + + dest = SET_DEST (set); + if (!REG_P (dest)) +continue; + if (targetm.small_register_classes_for_mode_p (GET_MODE (dest))) +return FALSE; +} /* THEN is not EXIT. */ if (then_bb->index < NUM_FIXED_BLOCKS)
spill failure after IF-CASE-2 transformation
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
RE: ICE building compiler
>Whilst investigating an ICE with the Blackfin compiler, I bumped in to a >bit of code which seems questionable: > >in reload1.c:reload() we call select_reload_regs() and then check if >failure was set. However, looking at find_reload_regs() (called via >select_reload_regs()), the only time we set failure is immediately after >a call to spill_failure() which doesn't return. Is spill_failure the >correct function to be using here? It seems like the intention of the >code was to note the spill_failure and then try and fix it >by jumping to the "failed:" label. any feedback on this? Thanks, Stu
RE: ICE building compiler
Hi, Whilst investigating an ICE with the Blackfin compiler, I bumped in to a bit of code which seems questionable: in reload1.c:reload() we call select_reload_regs() and then check if failure was set. However, looking at find_reload_regs() (called via select_reload_regs()), the only time we set failure is immediately after a call to spill_failure() which doesn't return. Is spill_failure the correct function to be using here? It seems like the intention of the code was to note the spill_failure and then try and then try and fix it by jumping to the "failed:" label. Cheers, Stu
ICE building compiler
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
RE: GCC 4.7 Status Report for *-rtems
> bfin - REGRESSION - ICE - >http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51003 This looks like a known, general issue which Bernd had a fix for, but it doesn't appear to have been checked in yet: http://gcc.gnu.org/ml/gcc-patches/2011-11/msg01524.html Stu