We found that std::basic_string<char, std::char_traits<char>, std::allocator<char> ::copy(char*, unsigned long, unsigned long) const
got miscompiled for ARC because reorg thought that all call-clobbered registers were dead after a conditional call. I can't reproduce the test case with current trunk + ARC port, but I reckon this is just due to the fickleness of the register allocator. Chances are, every other version, some other obscure function is miscompiled without this patch. bootstrapped on i686-pc-linux-gnu. OK to apply?
2013-04-29 Claudiu Zissulescu <claz...@synopsys.com> * resource.c (mark_target_live_regs): Compute resources taking into account if a call is predicated or not. diff --git a/gcc/resource.c b/gcc/resource.c Index: resource.c =================================================================== --- resource.c (revision 202295) +++ resource.c (working copy) @@ -994,11 +994,18 @@ mark_target_live_regs (rtx insns, rtx ta if (CALL_P (real_insn)) { - /* CALL clobbers all call-used regs that aren't fixed except - sp, ap, and fp. Do this before setting the result of the - call live. */ - AND_COMPL_HARD_REG_SET (current_live_regs, - regs_invalidated_by_call); + /* Values in call-clobbered registers survive a COND_EXEC CALL + if that is not executed; this matters for resoure use because + they may be used by a complementarily (or more strictly) + predicated instruction, or if the CALL is NORETURN. */ + if (GET_CODE (PATTERN (real_insn)) != COND_EXEC) + { + /* CALL clobbers all call-used regs that aren't fixed except + sp, ap, and fp. Do this before setting the result of the + call live. */ + AND_COMPL_HARD_REG_SET (current_live_regs, + regs_invalidated_by_call); + } /* A CALL_INSN sets any global register live, since it may have been modified by the call. */