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

--- Comment #4 from Paolo Bonzini <bonzini at gnu dot org> 2011-12-07 13:48:42 
UTC ---
The bug is that rbx is added to the EXIT_BLOCK uses:

Basic block 1 , prev 2, loop_depth 0, count 0, freq 0.
Predecessors:
;; bb 1 artificial_defs: { }
;; bb 1 artificial_uses: { u-1(3){ }u-1(6){ }u-1(7){ }u-1(20){ }}

Successors:

but "jmp *%rbx" does not have the EXIT_BLOCK as a successor:


Basic block 2 , prev 0, next 1, loop_depth 0, count 0, freq 10000, maybe hot.
Predecessors:  ENTRY [100.0%]  (fallthru)
;; bb 2 artificial_defs: { }
;; bb 2 artificial_uses: { u-1(6){ }u-1(7){ }u-1(16){ }u-1(20){ }}

Successors:

;; Pred edge  ENTRY [100.0%]  (fallthru)
(note 4 0 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(insn 2 4 3 2 (set (reg/v/f:DI 59 [ func ])
        (reg:DI 5 di [ func ])) f.c:4 62 {*movdi_internal_rex64}
     (nil))

(note 3 2 7 2 NOTE_INSN_FUNCTION_BEG)

(jump_insn 7 3 0 2 (set (pc)
        (reg/v/f:DI 59 [ func ])) f.c:5 608 {*indirect_jump}
     (nil))
;; End of basic block 2 -> ()


... so the liveness of rbx is not propagated from the end of basic block 1 to
the end of basic block 2.

I think the testcase is bogus:

   You may not use [goto void *] to jump to code in a different function.
   If you do that, totally unpredictable things will happen.  The best way
   to avoid this is to store the label address only in automatic variables
   and never pass it as an argument.

However, this one also shows the same issue:

  register void *volatile ptr asm("rbx") ;
  void testfn1(void* func)
  {
    for(;;)
      ptr = func;
  }

and the fix should likely work for both.

Reply via email to