Bug 37377 - [4.4 Regression] Bootstrap failure compiling libgcc
Summary: [4.4 Regression] Bootstrap failure compiling libgcc
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.4.0
: P3 blocker
Target Milestone: 4.4.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2008-09-04 20:22 UTC by Eric Botcazou
Modified: 2008-09-18 19:57 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build: i586-*-linux
Known to work:
Known to fail:
Last reconfirmed: 2008-09-05 13:46:52


Attachments
Preprocessed source (130.39 KB, text/plain)
2008-09-04 20:32 UTC, Eric Botcazou
Details
Simplified testcase. (98.17 KB, text/plain)
2008-09-07 15:45 UTC, Eric Botcazou
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Botcazou 2008-09-04 20:22:30 UTC
At revision 140002 I get on i586-linux:

/home/eric/build/gcc/native32/./gcc/xgcc -B/home/eric/build/gcc/native32/./gcc/ -B/home/eric/install/gcc/i586-suse-linux/bin/ -B/home/eric/install/gcc/i586-suse-linux/lib/ -isystem /home/eric/install/gcc/i586-suse-linux/include -isystem /home/eric/install/gcc/i586-suse-linux/sys-include -g -O2 -O2  -g -O2 -DIN_GCC   -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wold-style-definition  -isystem ./include  -fPIC -g -DHAVE_GTHR_DEFAULT -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED   -I. -I. -I../.././gcc -I/home/eric/svn/gcc/libgcc -I/home/eric/svn/gcc/libgcc/. -I/home/eric/svn/gcc/libgcc/../gcc -I/home/eric/svn/gcc/libgcc/../include -I/home/eric/svn/gcc/libgcc/config/libbid -DENABLE_DECIMAL_BID_FORMAT -DHAVE_CC_TLS -DUSE_TLS -o _popcountdi2.o -MT _popcountdi2.o -MD -MP -MF _popcountdi2.dep -DL_popcountdi2 -c /home/eric/svn/gcc/libgcc/../gcc/libgcc2.c \
          -fvisibility=hidden -DHIDE_EXPORTS
/home/eric/svn/gcc/libgcc/../gcc/libgcc2.c: In function '__popcountdi2':
/home/eric/svn/gcc/libgcc/../gcc/libgcc2.c:813: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
make[3]: *** [_popcountdi2.o] Error 1
make[3]: Leaving directory `/home/eric/build/gcc/native32/i586-suse-linux/libgcc'
make[2]: *** [all-stage2-target-libgcc] Error 2
make[2]: Leaving directory `/home/eric/build/gcc/native32'
make[1]: *** [stage2-bubble] Error 2
make[1]: Leaving directory `/home/eric/build/gcc/native32'
make: *** [all] Error 2
Comment 1 Eric Botcazou 2008-09-04 20:30:21 UTC
It's a miscompilation of df-scan.c:df_reorganize_refs_by_reg by regalloc/reload.
Comment 2 Eric Botcazou 2008-09-04 20:32:23 UTC
Created attachment 16225 [details]
Preprocessed source

Sorry, I don't have time to reduce it.

Compile with -O2 -fomit-frame-pointer -mtune=pentium.
Comment 3 Eric Botcazou 2008-09-04 20:36:06 UTC
In the assembly file:

.L871:
	movl	%ebx, %eax
	movl	%edx, 20(%ebx)
	call	T.911
	movl	df, %esi
	movl	60(%esi), %eax
	movl	%esi, 36(%esp)  <-- save df
	movl	(%eax), %eax
	movl	%eax, 44(%esp)
	testl	%eax, %eax
	je	.L1052

[...]

L895:
	movl	4(%ecx), %esi
	cmpb	$0, 22(%esp)
	je	.L896
	movl	144(%edi), %eax
	movl	(%eax,%esi,4), %eax
	movl	4(%eax), %edx
	movl	(%edx), %eax
	testl	%eax, %eax
	je	.L896
	movl	16(%esp), %ebp
	movl	8(%ebp), %ebp
	movl	%ebp, 36(%esp)  <-- overwrite df
	.p2align 4,,7
	.p2align 3
.L897:
	movl	28(%eax), %eax
	addl	$4, %edx
	incl	(%ebp,%eax,4)
	movl	(%edx), %eax
	testl	%eax, %eax
	jne	.L897
.L896:
	cmpb	$0, 23(%esp)
	je	.L898
	movl	144(%edi), %eax
	movl	(%eax,%esi,4), %eax
	movl	8(%eax), %edx
	movl	(%edx), %eax
	testl	%eax, %eax
	je	.L898
	movl	16(%esp), %ebp
	movl	8(%ebp), %ebp
	movl	%ebp, 36(%esp)  <-- overwrite df

[...]

.L995:
	movl	36(%esp), %ecx  <-- load df
	movl	60(%ecx), %eax
	movl	(%eax), %eax    <-- segv (eax == 0)
	movl	%eax, 60(%esp)
	testl	%eax, %eax
	je	.L1059
Comment 4 Eric Botcazou 2008-09-04 20:46:23 UTC
Excerpt from 168r.asmcons:

(insn:HI 108 107 109 14 /home/eric/svn/gcc/gcc/df-scan.c:1479 (set (reg/f:SI 373 [ df.3419 ])
        (mem/f/c/i:SI (symbol_ref:SI ("df") [flags 0x40] <var_decl 0xf759baa8 df>) [166 df+0 S4 A32])) 41 {*movsi_1} (nil))

[...]
(insn:HI 301 300 309 49 /home/eric/svn/gcc/gcc/df-scan.c:1508 (set (reg/f:SI 87 [ temp.3399 ])
        (mem/s/f:SI (plus:SI (reg/v/f:SI 214 [ ref_info ])
                (const_int 8 [0x8])) [160 <variable>.count+0 S4 A32])) 41 {*movsi_1} (nil))

[...]

(insn:HI 324 323 332 53 /home/eric/svn/gcc/gcc/df-scan.c:1514 (set (reg/f:SI 85 [ temp.3405 ])
        (mem/s/f:SI (plus:SI (reg/v/f:SI 214 [ ref_info ])
                (const_int 8 [0x8])) [160 <variable>.count+0 S4 A32])) 41 {*movsi_1} (nil))


Excerpt from 174r.ira:

changing reg in insn 324
changing reg in insn 1590
      Assigning 85(freq=162) slot 14 of 373
 Register 85 now on stack.

changing reg in insn 301
changing reg in insn 1579
      Assigning 87(freq=162) slot 14 of 85 373
 Register 87 now on stack.
Comment 5 H.J. Lu 2008-09-05 04:47:14 UTC
I tried revision 140023 on RHEL4U6. I can bootstrap
with --enable-languages=c i586-linux. 
Comment 6 Eric Botcazou 2008-09-05 06:24:33 UTC
> I tried revision 140023 on RHEL4U6. I can bootstrap
> with --enable-languages=c i586-linux. 

Which branch?  I still get the failure on mainline at revision 140025.
Comment 7 H.J. Lu 2008-09-05 13:46:52 UTC
(In reply to comment #6)
> > I tried revision 140023 on RHEL4U6. I can bootstrap
> > with --enable-languages=c i586-linux. 
> 
> Which branch?  I still get the failure on mainline at revision 140025.
> 

See

http://gcc.gnu.org/ml/gcc-testresults/2008-09/msg00384.html

Mainline can bootstrap with i586-linux. But there are some additional
testsuite failures.
Comment 8 Eric Botcazou 2008-09-07 13:58:45 UTC
> See
>
> http://gcc.gnu.org/ml/gcc-testresults/2008-09/msg00384.html
> 
> Mainline can bootstrap with i586-linux. But there are some additional
> testsuite failures.

Thanks for trying to reproduce, this is very helpful.  I'm sorry, I forgot
something: you must configure with RTL checking (--enable-checking=yes,rtl)
in order to have the miscompilation.

I'm going to attach a simplified testcase (which can be compiled by any x86 compiler) and the analysis.
Comment 9 Eric Botcazou 2008-09-07 15:45:41 UTC
Created attachment 16247 [details]
Simplified testcase.

It is still big, but only 2 functions eventually reach IRA.

Compile with -O2 -fomit-frame-pointer -mtune=pentium.
Comment 10 Eric Botcazou 2008-09-07 16:01:18 UTC
The problem is the 4th line in

      Remove r222:a590->a10(mem)
      Remove r69:a566->a389(mem)
      Remove r69:a549->a389(mem)
      Remove r376:a432->a12(mem)
      Remove r220:a148->a9(mem)

(r373 is now r376 on mainline) generated by generate_edge_moves:

	/* Actually it is not a optimization we need this code because
	   the memory (remember about equivalent memory) might be ROM
	   (or placed in read only section).  */
 	if (ALLOCNO_HARD_REGNO (dest_allocno) < 0
	    && ALLOCNO_HARD_REGNO (src_allocno) >= 0
	    && not_modified_p (src_allocno, dest_allocno))
	  {
	    ALLOCNO_MEM_OPTIMIZED_DEST (src_allocno) = dest_allocno;
	    ALLOCNO_MEM_OPTIMIZED_DEST_P (dest_allocno) = true;
	    if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
	      fprintf (ira_dump_file, "      Remove r%d:a%d->a%d(mem)\n",
		       regno, ALLOCNO_NUM (src_allocno),
		       ALLOCNO_NUM (dest_allocno));
	    continue;
	  }

Here's the list of allocnos for r376:

579:r376 l20    5  562:r376 l21    5  545:r376 l23    5
  526:r376 l24    5  507:r376 l25    5  460:r376 l22    5  446:r376 l19    5
  432:r376 l8     5  398:r376 l7     5  386:r376 l9   mem  366:r376 l13  mem
  343:r376 l14  mem  320:r376 l16  mem  295:r376 l17  mem  270:r376 l18  mem
  227:r376 l15  mem  213:r376 l12  mem  199:r376 l11  mem  167:r376 l10  mem
   12:r376 l0   mem

The move putting back r376 to its memory location is not generated on a border
of the "5" domain.  This domain contains the 2nd and 3rd insns of comment #4.
Moreover, the live range of a460 is not added to that of a12 during flattening
so r376 is not detected as conflicting with r90 (formerly r85) and r92 (f r87).
In the end, the memory location of r376 is reused within the "5" domain without
being reset at the border.

If I comment out the code quoted above, the compiler bootstraps fine.
Comment 11 Vladimir Makarov 2008-09-08 14:11:21 UTC
Eric, thanks a lot for your analysis.  It was very helpful. I've reproduced the bug.

IRA uses live ranges to find conflicts for spill slots during reload.  Live ranges for r376 were wrong after IR flattening.  We have the following loop structure for the case

    l8->l7->l0
         ^
l24->l22-|

and we remove mem<-reg coping allocno values from l8 to l0 because allocnos corresponding to r376 are not modified in the loops.  Allocno for r376 in l0 got live ranges only from l8 and l7 but not from l22 ...  Therefore IRA does not find conflicts with another allocno (r90) in l22 and l24.

I'll send a patch to solve the problem today.  Just removing the optimization (removing unnecessary mem<-reg) is not wise because it has significant impact on the generated code performance.
Comment 12 Eric Botcazou 2008-09-08 15:25:41 UTC
> Eric, thanks a lot for your analysis.  It was very helpful.

You're welcome!

> IRA uses live ranges to find conflicts for spill slots during reload.  Live
> ranges for r376 were wrong after IR flattening.  We have the following loop
> structure for the case
> 
>     l8->l7->l0
>          ^
> l24->l22-|
> 
> and we remove mem<-reg coping allocno values from l8 to l0 because allocnos
> corresponding to r376 are not modified in the loops.  Allocno for r376 in l0
> got live ranges only from l8 and l7 but not from l22 ...  Therefore IRA does
> not find conflicts with another allocno (r90) in l22 and l24.

Yes, my understanding was that the flattening code currently assumes that the
moves are always generated at the borders.

> I'll send a patch to solve the problem today.  Just removing the optimization
> (removing unnecessary mem<-reg) is not wise because it has significant impact
> on the generated code performance.

OK, thanks for the explanation.
Comment 13 hjl@gcc.gnu.org 2008-09-09 00:03:02 UTC
Subject: Bug 37377

Author: hjl
Date: Tue Sep  9 00:01:40 2008
New Revision: 140131

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=140131
Log:
2008-09-08 Vladimir Makarov <vmakarov@redhat.com>

	PR rtl-opt/37377
	* ira-build.c (common_loop_tree_node_dominator): Remove.
	(copy_live_ranges_to_removed_store_destinations): New function.
	(regno_top_level_allocno_map): Move to top level from ...
	(ira_flattening): ... here. Use
	copy_live_ranges_to_removed_store_destinations.

	* ira-emit.c (generate_edge_moves): Fix a comment.

Modified:
    branches/ira-merge/gcc/ChangeLog.ira
    branches/ira-merge/gcc/ira-build.c
    branches/ira-merge/gcc/ira-emit.c

Comment 14 Vladimir Makarov 2008-09-12 22:56:46 UTC
Subject: Bug 37377

Author: vmakarov
Date: Fri Sep 12 22:55:23 2008
New Revision: 140325

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=140325
Log:
2008-09-12  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-opt/37377
	
	* ira-build.c (common_loop_tree_node_dominator): Remove.
	(copy_live_ranges_to_removed_store_destinations): New function.
	(regno_top_level_allocno_map): Move to top level from ...
	(ira_flattening): ... here.  Use
	copy_live_ranges_to_removed_store_destinations.

	* ira-emit.c (generate_edge_moves): Fix a comment.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/ira-build.c
    trunk/gcc/ira-emit.c

Comment 15 Eric Botcazou 2008-09-13 08:51:19 UTC
This works fine now.
Comment 16 Thomas Koenig 2009-04-11 19:48:31 UTC
Subject: Bug 37377

Author: tkoenig
Date: Sat Apr 11 19:48:19 2009
New Revision: 145965

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=145965
Log:
2009-04-11  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/37377
	* libgfortran.h:  Introduce new macros GFC_DIMENSION_LBOUND,
	GFC_DIMENSION_UBOUND,GFC_DIMENSION_STRIDE, GFC_DIMENSION_EXTENT,
	GFC_DIMENSION_SET, GFC_DESCRIPTOR_LBOUND, GFC_DESCRIPTOR_UBOUND,
	GFC_DESCRIPTOR_EXTENT, GFC_DESCRIPTOR_EXTENT_BYTES,
	GFC_DESCRIPTOR_STRIDE, GFC_DESCRIPTOR_STRIDE_BYTES
	* runtime/in_pack_generic.c (internal_pack):  Use new macros
	for array descriptor access.
	* runtime/in_unpack_generic.c (internal_unpack):  Likewise.
	* intrinsics/dtime.c (dtime_sub):  Likewise.
	* intrinsics/cshift0 (cshift0):  Remove argument size,
	calculate directly from the array descriptor.  Use new macros
	for array descriptor access.
	* cshift0_##N:  Remove shift argument in call to cshift0.
	* cshift0_##N_char:  Mark array_length as unused.  Remove
	array_length in call to cshift0.
	* cshift0_##N_char4:  Likewise.
	* intrisics/etime.c:  Use new macros for array descriptor access.
	* intrinsics/stat.c (stat_i4_sub_0):  Likewise.
	(stat_i8_sub_0):  Likewise.
	(fstat_i4_sub):  Likewise.
	(fstat_i8_sub):  Likewise.
	* intrinsics/date_and_time.c (date_and_time):  Likewise.
	(secnds):  Likewise.
	(itime_i4):  Likewise.
	(itime_i8):  Likewise.
	(idate_i4):  Likewise.
	(idate_i8):  Likewise.
	(gmtime_i4):  Likewise.
	(gmtime_i8):  Likewise.
	(ltime_i4):  Likewise.
	(litme_i8):  Likewise.
	* intrinsics/associated.c (associated):  Likewise.
	* intrinsics/eoshift0.c (eoshift0):  Likewise.
	* intriniscs/size.c (size0):  Likewise.
	* intrinsics/random.c (arandom_r4):  Likewise.
	(arandom_r8):  Likewise.
	(arandom_r10):  Likewise.
	(arandom_r16):  Likewise.
	(random_seed_i4):  Likewise.
	(random_seed_i8):  Likewise.
	* io/list_read.c (nml_parse_qualifier):  Likewise.
	(nml_touch_nodes):  Likewise.
	(nml_read_obj):  Likewise.
	(get_name):  Likewise.
	* io/transfer.c (transfer_array):  Likewise.
	(init_loop_spec):  Likewise.
	(st_set_nml_var_dim):  Likewise.
	* io/write.c (nml_write_obj):  Likewise.
	(obj_loop):  Likewise.


Modified:
    branches/fortran-dev/libgfortran/ChangeLog.dev
    branches/fortran-dev/libgfortran/intrinsics/associated.c
    branches/fortran-dev/libgfortran/intrinsics/cshift0.c
    branches/fortran-dev/libgfortran/intrinsics/date_and_time.c
    branches/fortran-dev/libgfortran/intrinsics/dtime.c
    branches/fortran-dev/libgfortran/intrinsics/eoshift0.c
    branches/fortran-dev/libgfortran/intrinsics/etime.c
    branches/fortran-dev/libgfortran/intrinsics/random.c
    branches/fortran-dev/libgfortran/intrinsics/size.c
    branches/fortran-dev/libgfortran/intrinsics/stat.c
    branches/fortran-dev/libgfortran/io/list_read.c
    branches/fortran-dev/libgfortran/io/transfer.c
    branches/fortran-dev/libgfortran/io/write.c
    branches/fortran-dev/libgfortran/libgfortran.h
    branches/fortran-dev/libgfortran/runtime/in_pack_generic.c
    branches/fortran-dev/libgfortran/runtime/in_unpack_generic.c