Hi!

   void
   foo (void)
   {
     register long s __asm ("r13");
     register long t __asm ("r14");
     register long u __asm ("r15");
     asm volatile ("xorq %%r12, %%r12" : : : "r12");
     asm volatile ("xorq %0, %0" : "=r" (s));
     asm volatile ("xorq %0, %0" : "=r" (t));
     asm volatile ("xorq %0, %0" : "=r" (u));
   }

has wrong unwind info on x86_64-linux with -O2, the problem is
that dwarf2_frame_debug isn't called on the inline asm which
clobbers registers which have queued register saves.
This leads to the queued register saves to be emitted only after
all the inline asms, while they need to be flushed before the first
inline asm that clobbers any of the registers.
In the originally reported problem, there was just one inline asm
early in the function and the bug was mitigated by the
http://gcc.gnu.org/ml/gcc-patches/2010-09/msg01557.html
patch.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
ok for trunk/4.6?

2011-04-14  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/48597
        * final.c (final_scan_insn): Call dwarf2out_frame_debug even for
        inline asm.

--- gcc/final.c.jj      2011-04-11 19:26:53.000000000 +0200
+++ gcc/final.c 2011-04-14 14:09:05.602402069 +0200
@@ -2313,6 +2313,9 @@ final_scan_insn (rtx insn, FILE *file, i
            location_t loc;
            expanded_location expanded;
 
+           if (dwarf2out_do_frame ())
+             dwarf2out_frame_debug (insn, false);
+
            /* There's no telling what that did to the condition codes.  */
            CC_STATUS_INIT;
 


        Jakub

Reply via email to