https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56858
--- Comment #14 from Uroš Bizjak <ubizjak at gmail dot com> --- (In reply to Uroš Bizjak from comment #12) > 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. Actually, it is "barriers" pass that splits the call and its NOTE_INSN_CALL_ARG_LOCATION. Before the pass, we have: (call_insn:TI 117 113 196 (parallel [ (call (mem:DI (symbol_ref:DI ("__cxa_throw") [flags 0x41] <function_decl 0x7ff44719f900 __cxa_throw>) [0 __cxa_throw S8 A64]) (const_int 0 [0])) (use (reg:DI 29 $29)) (clobber (reg:DI 26 $26)) ]) eh-vararg-1.C:62 207 {*call_osf_1_noreturn} (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_CALL_DECL (symbol_ref:DI ("__cxa_throw") [flags 0x41] <function_decl 0x7ff44719f900 __cxa_throw>) (expr_list:REG_NORETURN (const_int 0 [0]) (nil))))))) (expr_list:DI (use (reg:DI 16 $16)) (expr_list:DI (use (reg:DI 17 $17)) (expr_list:DI (use (reg:DI 18 $18)) (nil))))) (note 196 117 195 (expr_list:REG_DEP_TRUE (concat:DI (reg:DI 17 $17) (symbol_ref/i:DI ("_ZTI1A") <var_decl 0x7ff447194630 _ZTI1A>)) (expr_list:REG_DEP_TRUE (concat:DI (reg:DI 18 $18) (const_int 0 [0])) (nil))) NOTE_INSN_CALL_ARG_LOCATION) (note/c 195 196 118 (var_location this (nil)) NOTE_INSN_VAR_LOCATION) (barrier 118 195 197) and "barriers" pass reorders this sequence to: (call_insn:TI 117 113 118 (parallel [ (call (mem:DI (symbol_ref:DI ("__cxa_throw") [flags 0x41] <function_decl 0x7f21556d0900 __cxa_throw>) [0 __cxa_throw S8 A64]) (const_int 0 [0])) (use (reg:DI 29 $29)) (clobber (reg:DI 26 $26)) ]) eh-vararg-1.C:62 207 {*call_osf_1_noreturn} (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_CALL_DECL (symbol_ref:DI ("__cxa_throw") [flags 0x41] <function_decl 0x7f21556d0900 __cxa_throw>) (expr_list:REG_NORETURN (const_int 0 [0]) (nil))))))) (expr_list:DI (use (reg:DI 16 $16)) (expr_list:DI (use (reg:DI 17 $17)) (expr_list:DI (use (reg:DI 18 $18)) (nil))))) (barrier 118 117 196) (note 196 118 195 (expr_list:REG_DEP_TRUE (concat:DI (reg:DI 17 $17) (symbol_ref/i:DI ("_ZTI1A") <var_decl 0x7f21556c5630 _ZTI1A>)) (expr_list:REG_DEP_TRUE (concat:DI (reg:DI 18 $18) (const_int 0 [0])) (nil))) NOTE_INSN_CALL_ARG_LOCATION) (note/c 195 196 197 (var_location this (nil)) NOTE_INSN_VAR_LOCATION) Indeed the purpose of "barriers" RTL pass is (from jump.c): --cut here-- /* Some old code expects exactly one BARRIER as the NEXT_INSN of a non-fallthru insn. This is not generally true, as multiple barriers may have crept in, or the BARRIER may be separated from the last real insn by one or more NOTEs. This simple pass moves barriers and removes duplicates so that the old code is happy. */ static unsigned int cleanup_barriers (void) { rtx insn, next, prev; for (insn = get_insns (); insn; insn = next) { next = NEXT_INSN (insn); if (BARRIER_P (insn)) { prev = prev_nonnote_insn (insn); if (!prev) continue; if (BARRIER_P (prev)) delete_insn (insn); else if (prev != PREV_INSN (insn)) reorder_insns_nobb (insn, insn, prev); } } return 0; } --cut here-- This is the hack to "keep the old code happy" (?!), instead of teaching the problematic code that varous debug notes can be between paired insns in the insn stream.