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.  */

Reply via email to