[Bug target/56858] alpha looks for NOTE_INSN_EH_REGION notes that cannot exist

ubizjak at gmail dot com gcc-bugzilla@gcc.gnu.org
Sun Apr 21 21:15:00 GMT 2013


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

--- Comment #12 from Uros Bizjak <ubizjak at gmail dot com> 2013-04-21 21:15:50 UTC ---
Created attachment 29911
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29911
Patch that introduces trap_shadows pass after eh_ranges

2013-04-18  Uros Bizjak  <ubizjak@gmail.com>

    PR target/56858
    * config/alpha/alpha.c: Include tree-pass.h.
    (gate_handle_trap_shadows): New static function.
    (rest_of_handle_trap_shadows): Ditto.
    (pass_handle_trap_shadows): New rtl_opt_pass structure.
    (alpha_option_override): Register trap_shadows pass after
    eh_ranges pass.
    (alpha_reorg): Do not call alpha_handle_trap_shadows here.

Attached patch adds trap_shadows handling pass after eh_ranges pass. The patch
was bootstrapped (configured with --host=alpha-linux-gnu
--build=alpha-linux-gnu --target=alpha-linux-gnu to make the pass effective).

The patch uncovered one issue with g++.dg/torture/stackalign/eh-vararg-1.C:

eh_ranges pass iserts a note between the call and its CALL_ARG_LOCATION note:

(call_insn:TI 175 238 243 (parallel [
            (call (mem:DI (reg:DI 27 $27) [0 S8 A64])
                (const_int 0 [0]))
            (use (reg:DI 29 $29))
            (use (symbol_ref:DI ("__cxa_throw") [flags 0x41]  <function_decl
0x200068f6300 __cxa_throw>))
            (use (const_int 14 [0xe]))
            (clobber (reg:DI 26 $26))
        ]) eh-vararg-1.C:62 211 {*call_osf_2_er_nogp}
     (expr_list:REG_DEAD (reg:DI 29 $29)
        (expr_list:REG_DEAD (reg:DI 27 $27)
            (expr_list:REG_DEAD (reg:DI 18 $18)
                (expr_list:REG_DEAD (reg:DI 17 $17)
                    (expr_list:REG_DEAD (reg:DI 16 $16)
                        (expr_list:REG_EH_REGION (const_int 1 [0x1])
                            (expr_list:REG_NORETURN (const_int 0 [0])
                                (nil))))))))
    (expr_list:REG_CC_SETTER (use (reg:DI 18 $18))
        (expr_list:REG_CC_SETTER (use (reg:DI 17 $17))
            (expr_list:REG_CC_SETTER (use (reg:DI 16 $16))
                (nil)))))
(note:TI 240 243 222 0 NOTE_INSN_EH_REGION_END)
(note 222 240 234 (expr_list:REG_DEP_TRUE (concat:DI (pc)
        (unspec:DI [
                (reg:DI 29 $29)
                (symbol_ref:DI ("__cxa_throw") [flags 0x41]  <function_decl
0x200068f6300 __cxa_throw>)
                (const_int 14 [0xe])
            ] UNSPEC_LITERAL))
    (expr_list:REG_DEP_TRUE (concat:DI (reg:DI 18 $18)
            (const_int 0 [0]))
        (expr_list:REG_DEP_TRUE (concat:DI (reg:DI 17 $17)
                (unspec:DI [
                        (reg:DI 29 $29)
                        (symbol_ref/i:DI ("_ZTI1A")  <var_decl 0x200067c1b50
_ZTI1A>)
                        (const_int 0 [0])
                    ] UNSPEC_LITERAL))
            (nil)))) NOTE_INSN_CALL_ARG_LOCATION)
(insn 234 222 119 (const_int 2 [0x2]) 294 {unop}
     (nil))

The new trap_shadows pass inserts

(insn:TI 243 175 240 (unspec_volatile [
            (const_int 0 [0])
        ] UNSPECV_TRAPB) -1
     (nil))

just above NOTE_INSN_EH_REGION_END note, and this breaks compilation (-O2 -g)
in:

/home/uros/gcc-svn/trunk/gcc/testsuite/g++.dg/torture/stackalign/eh-vararg-1.C:65:1:
internal compiler error: in dwarf2out_var_location, at dwarf2out.c:20838^M
0x120537c6b dwarf2out_var_location^M
        ../../gcc-svn/trunk/gcc/dwarf2out.c:20834^M
0x1205dd753 final_scan_insn(rtx_def*, _IO_FILE*, int, int, int*)^M
        ../../gcc-svn/trunk/gcc/final.c:2276^M
0x1205deb37 final(rtx_def*, _IO_FILE*, int)^M
        ../../gcc-svn/trunk/gcc/final.c:1957^M
0x1205df0fb rest_of_handle_final^M
        ../../gcc-svn/trunk/gcc/final.c:4332^M
Please submit a full bug report,^M

20829           = ggc_alloc_cleared_call_arg_loc_node ();
20830         rtx prev = prev_real_insn (loc_note), x;
20831         ca_loc->call_arg_loc_note = loc_note;
20832         ca_loc->next = NULL;
20833         ca_loc->label = last_label;
20834         gcc_assert (prev
20835                     && (CALL_P (prev)
20836                         || (NONJUMP_INSN_P (prev)
20837                             && GET_CODE (PATTERN (prev)) == SEQUENCE
20838                             && CALL_P (XVECEXP (PATTERN (prev), 0,
0)))));

Steven, is it possible to emit NOTE_INSN_EH_REGION_END in such way that it
would not split the call and its NOTE_INSN_CALL_ARG_LOCATION? This would solve
the above problem in the most elegant way.



More information about the Gcc-bugs mailing list