Bug 71132 - [7 Regression] gcc ICE at -O3 on valid code on x86_64-linux-gnu with “seg fault”
Summary: [7 Regression] gcc ICE at -O3 on valid code on x86_64-linux-gnu with “seg fault”
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: 7.0
Assignee: Richard Biener
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-05-15 22:26 UTC by Qirun Zhang
Modified: 2016-05-17 12:54 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2016-05-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Qirun Zhang 2016-05-15 22:26:33 UTC
The following valid code causes an ICE when compiled with the current gcc trunk at only -O3 on x86_64-linux-gnu in both 32-bit and 64-bit modes.

It appears to be a 7 regression.

$ gcc-trunk -v
Using built-in specs.
COLLECT_GCC=gcc-trunk
COLLECT_LTO_WRAPPER=/home/absozero/trunk/root-gcc/libexec/gcc/x86_64-pc-linux-gnu/7.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc/configure --prefix=/home/absozero/trunk/root-gcc --enable-languages=c,c++ --disable-werror --enable-multilib
Thread model: posix
gcc version 7.0.0 20160515 (experimental) [trunk revision 236250] (GCC) 



$ gcc-trunk -O3 abc.c
abc.c: In function ‘main’:
abc.c:6:5: internal compiler error: Segmentation fault
 int main() {
     ^~~~
0xbaa52f crash_signal
	../../gcc/gcc/toplev.c:333
0xbe18e0 bb_seq_addr
	../../gcc/gcc/gimple.h:1654
0xbe18e0 gsi_last_bb
	../../gcc/gcc/gimple-iterator.h:163
0xbe18e0 last_stmt(basic_block_def*)
	../../gcc/gcc/tree-cfg.c:2640
0xc38900 create_edge_for_control_dependence
	../../gcc/gcc/tree-loop-distribution.c:282
0xc39bb6 create_rdg_cd_edges
	../../gcc/gcc/tree-loop-distribution.c:327
0xc39bb6 build_rdg
	../../gcc/gcc/tree-loop-distribution.c:458
0xc39f0b distribute_loop
	../../gcc/gcc/tree-loop-distribution.c:1418
0xc3cdc7 execute
	../../gcc/gcc/tree-loop-distribution.c:1791
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.

$ cat abc.c
typedef unsigned size_t;
struct {
  unsigned char buf[sizeof(long)];
} a;
size_t b;
int main() {
  size_t c, i;
  unsigned char *d;
  for (; c < sizeof(long);) {
    d = a.buf;
    b = 0;
    for (; b < i; b++)
      *d++ = '\0';
    for (; c < b; c++)
      *d++ = 'a';
    c = 0;
    for (; i < sizeof(long); i++)
      ;
  }
}
Comment 1 Marek Polacek 2016-05-16 13:07:24 UTC
Started with:

commit f52a3ef65a923faa1c22a8c04cda64ed8f0b2234
Author: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Thu May 12 07:18:58 2016 +0000

    2016-05-12  Richard Biener  <rguenther@suse.de>
    
        PR tree-optimization/70986
        * cfganal.c: Include cfgloop.h.
        (dfs_find_deadend): Prefer to take edges exiting loops.
    
        * gcc.dg/torture/pr70986-1.c: New testcase.
        * gcc.dg/torture/pr70986-2.c: Likewise.
        * gcc.dg/torture/pr70986-3.c: Likewise.
    
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@236158 138bc75d-0d04-0410-961f-82ee72b054a4
Comment 2 Richard Biener 2016-05-17 08:39:24 UTC
Mine then.  Looks like a latent bug.
Comment 3 Richard Biener 2016-05-17 09:36:35 UTC
So the issue is that loop distribution computes control dependences in the
function once and queries them after processing some loops already (in this
case removing a loop and replacing it with a builtin memset).  In this case
this leads to the loop header being control dependent on the exit test
of the memset loop (sth that doesn't require the endless loop we have here).
Comment 4 Richard Biener 2016-05-17 12:54:02 UTC
Author: rguenth
Date: Tue May 17 12:53:30 2016
New Revision: 236320

URL: https://gcc.gnu.org/viewcvs?rev=236320&root=gcc&view=rev
Log:
2016-05-17  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/71132
	* tree-loop-distribution.c (create_rdg_cd_edges): Pass in loop.
	Only add control dependences for blocks in the loop.
	(build_rdg): Adjust.
	(generate_code_for_partition): Return whether loop should
	be destroyed and delay that.
	(distribute_loop): Likewise.
	(pass_loop_distribution::execute): Record loops to be destroyed
	and perform delayed destroying of loops.

	* gcc.dg/torture/pr71132.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr71132.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-loop-distribution.c
Comment 5 Richard Biener 2016-05-17 12:54:15 UTC
Fixed.