[PATCH] Cope with exception_receiver on Alpha/Tru64 5.x

Eric Botcazou ebotcazou@adacore.com
Mon Nov 20 22:02:00 GMT 2006


Hi,

We recently run into a checking failure on Alpha/Tru64 5.x with a modified 
4.1-based compiler (unfortunately no testcase for FSF compilers).  This is an 
ICE triggered by the CFG verification code during the RTL EH finalization 
pass.  dw2_build_landing_pads emits the exception_receiver pattern in the RTL 
stream if present for the target.  Now on the Alpha:

(define_expand "exception_receiver"
  [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
  "TARGET_ABI_OSF"
{
  if (TARGET_LD_BUGGY_LDGP)
    operands[0] = alpha_gp_save_rtx ();
  else
    operands[0] = const0_rtx;
})

And in config/alpha/osf5.h:

/* The linker appears to perform invalid code optimizations that result
   in the ldgp emitted for the exception_receiver pattern being incorrectly
   linked.  */
#undef TARGET_LD_BUGGY_LDGP
#define TARGET_LD_BUGGY_LDGP 1

And in config/alpha/alpha.c:

/* Return or create a memory slot containing the gp value for the current
   function.  Needed only if TARGET_LD_BUGGY_LDGP.  */

rtx
alpha_gp_save_rtx (void)
{
  rtx seq, m = cfun->machine->gp_save_rtx;

  if (m == NULL)
    {
      start_sequence ();

      m = assign_stack_local (DImode, UNITS_PER_WORD, BITS_PER_WORD);
      m = validize_mem (m);
      emit_move_insn (m, pic_offset_table_rtx);

      seq = get_insns ();
      end_sequence ();
      emit_insn_after (seq, entry_of_function ());

      cfun->machine->gp_save_rtx = m;
    }

  return m;
}


The problem is that the first BB of the function starts with a label:

;; Start of basic block 0, registers live: (nil)
(code_label 7 6 8 2 78 "" [3 uses])

(note 8 7 10 2 [bb 0] NOTE_INSN_BASIC_BLOCK)

(insn 10 8 11 2 (set (reg:DI 75)
        (symbol_ref:DI ("p__all_events") [flags 0x2] <var_decl 0x2a961e8a50 
p__all_events>)) -1 (nil)
    (nil))

(insn 11 10 12 2 (set (reg:DI 16 $16)
        (reg:DI 75)) -1 (nil)
    (nil))

and entry_of_function () returns the label.  So alpha_gp_save_rtx will insert

(insn 93 104 7 0 (set (mem/c:DI (reg/f:DI 65 virtual-stack-vars) [0 S8 A64])
        (reg:DI 29 $29)) -1 (nil)
    (nil))

between the label and the NOTE_INSN_BASIC_BLOCK, which is invalid.


entry_of_function () was added for CFG transparent RTL expansion and I think 
it is OK for that purpose.  It was later reused in alpha_gp_save_rtx and this 
latter use is clearly problematic.

The proposed fix is to insert properly the insns on the entry edge using a 
little kludge.  OK for mainline?


2006-11-20  Eric Botcazou  <ebotcazou@adacore.com>

        * except.c (finish_eh_generation): Call commit_edge_insertions if
        there are insns queued on the entry edge.
        * config/alpha/alpha.c (alpha_gp_save_rtx): Insert the insns on
        the entry edge.


:ADDPATCH middle-end:

-- 
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fa04-006_fsf.diff
Type: text/x-diff
Size: 1373 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20061120/168e81e5/attachment.bin>


More information about the Gcc-patches mailing list