Bug 16490

Summary: segfault while compiling with -fprofile-use
Product: gcc Reporter: kapalka
Component: rtl-optimizationAssignee: 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
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
../../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.
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
  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.
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 GCC 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.

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

Comment 10 GCC 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.

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

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. ***