>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)