Bug 16490 - segfault while compiling with -fprofile-use
segfault while compiling with -fprofile-use
Product: gcc
Classification: Unclassified
Component: rtl-optimization
: P2 normal
: 3.4.2
Assigned To: Jim Wilson
: ice-on-valid-code
: 13882 15836 (view as bug list)
Depends on:
  Show dependency treegraph
Reported: 2004-07-12 08:47 UTC by kapalka
Modified: 2004-08-17 00:14 UTC (History)
2 users (show)

See Also:
Target: ia64-redhat-linux
Known to work:
Known to fail: 3.4.1 3.4.2
Last reconfirmed: 2004-08-08 01:26:12

the C source file (54.96 KB, text/plain)
2004-07-12 08:50 UTC, kapalka
the profile generated with -fprofile-generate (2.04 KB, text/plain)
2004-07-12 08:51 UTC, kapalka
first patch, drop the life info (806 bytes, patch)
2004-08-08 01:29 UTC, Jim Wilson
Details | Diff
second patch, maintain the life info (1.09 KB, patch)
2004-08-08 01:30 UTC, Jim Wilson
Details | Diff
third patch, for mainline gcc (1.24 KB, patch)
2004-08-08 02:00 UTC, Jim Wilson
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description kapalka 2004-07-12 08:47:26 UTC
Good morning,

I was compiling the ROOT v4.00.06a (root.cern.ch) on Itanium 2 platform, Linux
system with -fprofile-generate, I run a few benchmarks and next I tried to
re-compile the package with -fprofile-use. Unfortunately, the compilation
process stopped on the file "build/rmkdepend/parse.c" with the following error:

build/rmkdepend/parse.c: In function `undefine':
build/rmkdepend/parse.c:535: internal compiler error: Segmentation fault

To reproduce the bug, you should use the 2 files I'm enclosing with the bug
report. The command-line causing the error:

gcc -O2 -fprofile-use -fPIC -D_REENTRANT -c parse.i

However, even "gcc -O2 -fprofile-use -c parse.i" when the "parse.gcda" file is
NOT present gives the same error, obviously together with the information "file
parse.gcda not found, execution counts assumed to be zero".

My compiler version:
Reading specs from /opt/gcc3.4.1/lib/gcc/ia64-redhat-linux/3.4.1/specs
Configured with: ./configure --prefix=/opt/gcc3.4.1 --enable-shared
--enable-threads=posix --disable-checking --with-system-zlib
--enable-__cxa_atexit --host=ia64-redhat-linux --enable-languages=c,c++,f77
Thread model: posix
gcc version 3.4.1

Best regards,

Michal Kapalka
Comment 1 kapalka 2004-07-12 08:50:53 UTC
Created attachment 6726 [details]
the C source file
Comment 2 kapalka 2004-07-12 08:51:40 UTC
Created attachment 6727 [details]
the profile generated with -fprofile-generate
Comment 3 Serge Belyshev 2004-08-05 15:26:01 UTC
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
#5  0x080e1814 in make_forwarder_block (bb=0x851eef0, redirect_latch=1,
    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
#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
#15 0x082b8ae3 in cgraph_assemble_pending_functions () at
#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
#24 0x080bc32c in main (argc=0, argv=0x0) at ../../gcc/gcc/main.c:35

Comment 4 Jim Wilson 2004-08-08 01:26:11 UTC
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
and now we have one basic block that does not have life info, while all others do.

Then we have the call chain
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.
Comment 5 Jim Wilson 2004-08-08 01:26:49 UTC
IA-64.  Mine.
Comment 6 Jim Wilson 2004-08-08 01:29:28 UTC
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.
Comment 7 Jim Wilson 2004-08-08 01:30:28 UTC
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.
Comment 8 Jim Wilson 2004-08-08 02:00:19 UTC
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.
Comment 9 CVS Commits 2004-08-11 20:05:18 UTC
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.


Comment 10 CVS Commits 2004-08-11 20:08:05 UTC
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.


Comment 11 Jim Wilson 2004-08-11 20:10:00 UTC
Fixed.  patch.2 and patch.3 added to gcc-3.4.x branch and mainline respectively.
Comment 12 Jim Wilson 2004-08-16 22:03:54 UTC
*** Bug 15836 has been marked as a duplicate of this bug. ***
Comment 13 Jim Wilson 2004-08-17 00:14:16 UTC
*** Bug 13882 has been marked as a duplicate of this bug. ***