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

Reply via email to