This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug rtl-optimization/34456] New: Flaw in branch delay optimization (patch included).


This was discovered in GCC 4.1.1 on MIPS, but the problem is in the current SVN
head.

The mark_set_resources function incorrectly calculates the potentially
clobbered registers for a CALL_INSN, using an obsolete approach relying on the
call_used_regs array.

A potential consequence of this is that a register which should be live is
marked dead during the liveness analysis which is done in order to determine
whether an instruction move into a delay slot is free of resource conflicts.

Thus, it's possible that an instruction which clobbers a register that is live
in the fall-through path is moved into a non-annulled delay slot of a branch
instruction. This behavior in fact happened when compiling a C++ application
for MIPS (n32). The MIPS GP register ($28) is in call_used_regs, but not in
call_really_used_regs. 

The hard reg set regs_invalidated_by_call should be used; it contains the right
information compiled from global_regs and call_really_used_regs.

The target of the branch instruction in the failed program is an epilogue which
restores registers, the first being the GP. This GP-restoring instruction is
moved into the branch delay slot, because in the fall-through-code
mark_target_live_regs finds a call instruction ahead of anything which uses the
GP, and concludes that GP is a dead register.

The result is that a GOT-based indirect function call is made using the
caller's GP, which is different from the caller's.

After this patch, nearly the same code is generated, except that the branch is
correctly changed to an annulling one (MIPS ``branch likely'').

--- gcc-4.1.1.orig/gcc/resource.c       2007-12-16 11:59:18.000000000 -0800
+++ gcc-4.1.1/gcc/resource.c    2007-12-19 20:59:02.724735120 -0800
@@ -664,9 +664,8 @@
          rtx link;

          res->cc = res->memory = 1;
-         for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
-           if (call_used_regs[r] || global_regs[r])
-             SET_HARD_REG_BIT (res->regs, r);
+
+         IOR_HARD_REG_SET (res->regs, regs_invalidated_by_call);

          for (link = CALL_INSN_FUNCTION_USAGE (x);
               link; link = XEXP (link, 1))


-- 
           Summary: Flaw in branch delay optimization (patch included).
           Product: gcc
           Version: 4.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: kkylheku at gmail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34456


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]