This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
CFG operation leading to errors
- From: Claudiu Zissulescu <Claudiu dot Zissulescu at synopsys dot com>
- To: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Cc: Cupertino Miranda <Cupertino dot Miranda at synopsys dot com>, Francois Bedard <Francois dot Bedard at synopsys dot com>
- Date: Fri, 17 Nov 2017 15:05:23 +0000
- Subject: CFG operation leading to errors
- Authentication-results: sourceware.org; auth=none
Hi,
I've found a potential issue when performing CFG operations for hardware loops.
When a port is using hardware loops (like ARC) makes use of reorg_loops to find and analyze loops that end in loop_end instructions. The very same function can be set to reorder the cfg such that the loop end occurs after the loop start. This task is performed by reoder_loops function which at its turn calls cfg_layout_finalize -> fixup_reoreder_chain -> force_nonfallthru_and_redirect (cfgrtl.c:1476).
However, the latter is splitting a call and its corresponding CALL_ARG_LOCATION note, leading to an assert in dwarf2out_var_location() at dwarf2out.c:26391. Thus, I've made a hack which patches the force_nonfallthru_and_redirect() function to avoid splitting calls and their note:
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index ae46908..38a739c 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1626,6 +1626,9 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
else
new_head = BB_END (e->src);
new_head = NEXT_INSN (new_head);
+ if (new_head && NOTE_P (new_head)
+ && NOTE_KIND (new_head) == NOTE_INSN_CALL_ARG_LOCATION)
+ new_head = NEXT_INSN (new_head);
jump_block = create_basic_block (new_head, NULL, e->src);
jump_block->count = count;
I do not know if this is the way forward and I would like to have your input on this subject.
To reproduce the issue one can use ARC backend and the following test code with option -O2 -mcpu=arc700 -g :
typedef void Trans_NS_std_new_handler();
void *operator new(unsigned) {
void *p;
while (__builtin_expect(p == 0, false)) {
Trans_NS_std_new_handler handler;
try {
handler();
} catch (int) {
}
}
return (void*) 0xdead;
}
Thank you,
Claudiu