This is an ICE due to using single_set on a somewhat unconventional call
pattern. To fix it, I've borrowed code from dse.c which was mentioned in
the PR.
Bootstrapped & tested on x86_64-linux and committed.
Bernd
Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog (revision 187744)
+++ gcc/ChangeLog (working copy)
@@ -1,3 +1,9 @@
+2012-05-21 Bernd Schmidt <ber...@codesourcery.com>
+
+ PR rtl-optimization/53373
+ * caller-save.c (save_call_clobbered_regs): Look into a possible
+ PARALLEL manually rather than using single_set on a call insn.
+
2012-05-21 Jakub Jelinek <ja...@redhat.com>
PR tree-optimization/53436
Index: gcc/caller-save.c
===================================================================
--- gcc/caller-save.c (revision 187744)
+++ gcc/caller-save.c (working copy)
@@ -872,11 +872,13 @@ save_call_clobbered_regs (void)
&& HARD_REGISTER_P (cheap)
&& TEST_HARD_REG_BIT (call_used_reg_set, REGNO (cheap)))
{
- rtx call_set = single_set (insn);
- rtx dest = SET_DEST (call_set);
- rtx pat = gen_rtx_SET (VOIDmode, cheap,
- copy_rtx (dest));
- chain = insert_one_insn (chain, 0, -1, pat);
+ rtx dest, newpat;
+ rtx pat = PATTERN (insn);
+ if (GET_CODE (pat) == PARALLEL)
+ pat = XVECEXP (pat, 0, 0);
+ dest = SET_DEST (pat);
+ newpat = gen_rtx_SET (VOIDmode, cheap, copy_rtx (dest));
+ chain = insert_one_insn (chain, 0, -1, newpat);
}
}
last = chain;