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