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