Summary: | segfault while compiling with -fprofile-use | ||
---|---|---|---|
Product: | gcc | Reporter: | kapalka |
Component: | rtl-optimization | Assignee: | Jim Wilson <wilson> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | gcc-bugs, rguenth |
Priority: | P2 | Keywords: | ice-on-valid-code |
Version: | 3.4.1 | ||
Target Milestone: | 3.4.2 | ||
Host: | Target: | ia64-redhat-linux | |
Build: | Known to work: | ||
Known to fail: | 3.4.1 3.4.2 | Last reconfirmed: | 2004-08-08 01:26:12 |
Attachments: |
the C source file
the profile generated with -fprofile-generate first patch, drop the life info second patch, maintain the life info third patch, for mainline gcc |
Description
kapalka
2004-07-12 08:47:26 UTC
Created attachment 6726 [details]
the C source file
Created attachment 6727 [details]
the profile generated with -fprofile-generate
small testcase, use "-O1 -funroll-loops -fvpt -fbranch-probabilities" : ------------------------------------------------------------------------------ void bar (int k) { while (foo ()) { while (k++ < 0) baz (); } } ------------------------------------------------------------------------------ Program received signal SIGSEGV, Segmentation fault. bitmap_operation (to=0xbfffec40, from1=0x0, from2=0x0, operation=BITMAP_XOR) at ../../gcc/gcc/bitmap.c:511 511 bitmap_element *from2_ptr = from2->first; (gdb) where #0 bitmap_operation (to=0xbfffec40, from1=0x0, from2=0x0, operation=BITMAP_XOR) at ../../gcc/gcc/bitmap.c:511 #1 0x0815e2f2 in init_propagate_block_info (bb=0x851ee28, live=0x0, local_set=0x0, cond_local_set=0x0, flags=0) at ../../gcc/gcc/flow.c:1874 #2 0x0815e628 in propagate_block (bb=0x851ee28, live=0x851bcb8, local_set=0x0, cond_local_set=0x0, flags=0) at ../../gcc/gcc/flow.c:2012 #3 0x080e5c32 in rtl_split_block (bb=0x851eef0, insnp=0xb7b997a0) at ../../gcc/gcc/cfgrtl.c:517 #4 0x080e8bf4 in cfg_layout_split_block (bb=0x0, insnp=0x0) at ../../gcc/gcc/cfgrtl.c:2420 #5 0x080e1814 in make_forwarder_block (bb=0x851eef0, redirect_latch=1, redirect_nonlatch=0, except=0x0, conn_latch=0) at ../../gcc/gcc/cfgloop.c:589 #6 0x080e1a84 in canonicalize_loop_headers () at ../../gcc/gcc/cfgloop.c:722 #7 0x080e1be9 in flow_loops_find (loops=0x8518514, flags=Variable "flags" is not available. ) at ../../gcc/gcc/cfgloop.c:764 #8 0x082c4ef7 in loop_optimizer_init (dumpfile=0x0) at ../../gcc/gcc/loop-init.c:52 #9 0x08275912 in rest_of_handle_loop2 (decl=0x0, insns=0xb7b992e0) at ../../gcc/gcc/toplev.c:3074 #10 0x08276000 in rest_of_compilation (decl=0xb7ae8244) at ../../gcc/gcc/toplev.c:3364 #11 0x082b7214 in tree_rest_of_compilation (fndecl=0xb7ae8244, nested_p=false) at ../../gcc/gcc/tree-optimize.c:168 #12 0x0806b569 in c_expand_body_1 (fndecl=0xb7ae8244, nested_p=0) at ../../gcc/gcc/c-decl.c:6158 #13 0x0806b75d in c_expand_body (fndecl=0xb7ae8244) at ../../gcc/gcc/c-decl.c:6190 #14 0x082b96df in cgraph_expand_function (node=0xb7ae85e4) at ../../gcc/gcc/cgraphunit.c:538 #15 0x082b8ae3 in cgraph_assemble_pending_functions () at ../../gcc/gcc/cgraphunit.c:144 #16 0x082b8c04 in cgraph_finalize_function (decl=0xb7ae8244, nested=false) at ../../gcc/gcc/cgraphunit.c:225 #17 0x0806b451 in finish_function () at ../../gcc/gcc/c-decl.c:6115 #18 0x0804a806 in yyparse () at c-parse.y:385 #19 0x08052870 in c_parse_file () at c-parse.y:3029 #20 0x0809d425 in c_common_parse_file (set_yydebug=0) at ../../gcc/gcc/c-opts.c:1237 #21 0x082736c2 in compile_file () at ../../gcc/gcc/toplev.c:1822 #22 0x08277c5e in do_compile () at ../../gcc/gcc/toplev.c:4651 #23 0x08277cf3 in toplev_main (argc=0, argv=0xbffff8e4) at ../../gcc/gcc/toplev.c:4691 #24 0x080bc32c in main (argc=0, argv=0x0) at ../../gcc/gcc/main.c:35 Confirmed. This dies in bitmap_operation because we were called with a block with a null global_live_at_start field. This happens during the loop2 pass, which is before the life pass, so normally there shouldn't be any life info here. However, the value profiling pass does run life_analysis also, so if we are doing value profiling, we will have life info starting with the branch_prob (bp) pass. Since the cfg* routines check the global_live_at_start field of a block to determine whether it should update life info, we either need to update this field in all blocks once it is created, or else we need to eliminate the info after we are done using it. (Or alternatively, modify the tests used in the cfg* routines, but I didn't seriously consider that alternative.) The exact circumstances that cause the crash happen in loop_optimizer_init. First we have a call chain loop_optimizer_init split_edge cfglayout_split_edge create_basic_block and now we have one basic block that does not have life info, while all others do. Then we have the call chain loop_optimizer_init flow_loops_find canonicalize_loop_headers make_forwarder_block cfg_layout_split_block rtl_split_block propate_block init_propagate_block_info bitmap_operation and we die because one block has life info and the other doesn't. I see two ways to fix this. We can zero out the life info when we are done with the value profiling pass. Or we can modify cfglayout_split_edge to set the global_live_at_start field of the new basic block. Since the rtl_split_edge function already does this, this seems like a reasonable thing to do. I can reproduce the same problem in gcc-3.5 using the parse.i file without the parse.gcda file. The call chain is a bit different, but it is the same problem, and fixed with the same solution. IA-64. Mine. Created attachment 6903 [details]
first patch, drop the life info
This works, but doesn't seem like the right solution. Freeing the info would
be better, but since it is on an obstack, it will get freed at the end of the
function anyways, so there is no permanent memory leakage here. This is a
gcc-3.4.x patch.
Created attachment 6904 [details]
second patch, maintain the life info
This works, and seems better than the first patch. This is a gcc-3.4.x patch.
Created attachment 6905 [details]
third patch, for mainline gcc
This is the same as the second patch, except for mainline gcc instead of for
the gcc-3.4.x branch.
Subject: Bug 16490 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: wilson@gcc.gnu.org 2004-08-11 20:05:09 Modified files: gcc : ChangeLog cfgrtl.c Log message: Fix -fprofile-use ICE. PR rtl-optimization/16490 * cfgrtl.c (cfg_layout_split_edge): Set global_live_at_start and global_live_at_end for new basic block if already set for other blocks. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=2.2326.2.576&r2=2.2326.2.577 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cfgrtl.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.103.2.4&r2=1.103.2.5 Subject: Bug 16490 CVSROOT: /cvs/gcc Module name: gcc Changes by: wilson@gcc.gnu.org 2004-08-11 20:08:01 Modified files: gcc : ChangeLog cfgrtl.c Log message: Fix -fprofile-use ICE. PR rtl-optimization/16490 * cfgrtl.c (cfg_layout_split_edge): Set global_live_at_start and global_live_at_end for new basic block if already set for other blocks. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.4865&r2=2.4866 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cfgrtl.c.diff?cvsroot=gcc&r1=1.125&r2=1.126 Fixed. patch.2 and patch.3 added to gcc-3.4.x branch and mainline respectively. *** Bug 15836 has been marked as a duplicate of this bug. *** *** Bug 13882 has been marked as a duplicate of this bug. *** |