Bug 50682 - [4.7 Regression] ICE: SIGSEGV in main_block_label with -O2 -fnon-call-exceptions -ftracer
Summary: [4.7 Regression] ICE: SIGSEGV in main_block_label with -O2 -fnon-call-excepti...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.7.0
: P1 normal
Target Milestone: 4.7.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2011-10-09 19:07 UTC by Zdenek Sojka
Modified: 2011-11-28 21:08 UTC (History)
1 user (show)

See Also:
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Build:
Known to work: 4.6.2
Known to fail: 4.7.0
Last reconfirmed: 2011-10-10 00:00:00


Attachments
reduced testcase (237 bytes, text/plain)
2011-10-09 19:07 UTC, Zdenek Sojka
Details
gcc47-pr50682.patch (1.15 KB, patch)
2011-11-23 16:47 UTC, Jakub Jelinek
Details | Diff
another testcase (197 bytes, text/plain)
2011-11-27 13:13 UTC, Zdenek Sojka
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Zdenek Sojka 2011-10-09 19:07:31 UTC
Created attachment 25450 [details]
reduced testcase

Compiler output:
$ gcc -O2 -fnon-call-exceptions -ftracer -fno-tree-ccp -fno-tree-copy-prop -fno-tree-dce testcase.C
==3654== Invalid read of size 4
==3654==    at 0xB65233: main_block_label(tree_node*) (tree-cfg.c:1082)
==3654==    by 0xB6965E: cleanup_dead_labels() (tree-cfg.c:1111)
==3654==    by 0xBBA2EC: execute_cleanup_cfg_post_optimizing() (tree-optimize.c:162)
==3654==    by 0xA62BF7: execute_one_pass(opt_pass*) (passes.c:2064)
==3654==    by 0xA62F64: execute_pass_list(opt_pass*) (passes.c:2119)
==3654==    by 0xBBACFD: tree_rest_of_compilation(tree_node*) (tree-optimize.c:420)
==3654==    by 0x815EE5: cgraph_expand_function(cgraph_node*) (cgraphunit.c:1805)
==3654==    by 0x817E2B: cgraph_optimize() (cgraphunit.c:1864)
==3654==    by 0x818219: cgraph_finalize_compilation_unit() (cgraphunit.c:1312)
==3654==    by 0x64266A: cp_write_global_declarations() (decl2.c:4008)
==3654==    by 0xB58803: toplev_main(int, char**) (toplev.c:581)
==3654==    by 0x674ED2C: (below main) (in /lib64/libc-2.12.2.so)
==3654==  Address 0x50 is not stack'd, malloc'd or (recently) free'd
==3654== 
testcase.C: In function 'void test01()':
testcase.C:29:1: 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.

Tested revisions:
r179711 - crash
r178498 - crash
4.6 r177922 - OK
Comment 1 Richard Biener 2011-10-10 15:33:23 UTC
Confirmed.
Comment 2 Jakub Jelinek 2011-11-23 16:43:36 UTC
The problem here is that with all the -fno-* options we end up with code like:
<bb 14>:
  D.2284_38 = &__size;

<bb 35>:
  # D.2281_58 = PHI <&__size(14)>
  D.2283_59 = D.2281_58;
  D.2281_60 = D.2281_58;
  D.2281_61 = D.2281_58;
  __r_62 = *D.2281_58;
at the beginning of ehcleanup2 pass.  Then we clean up eh and as something changed, TODO_cleanup_cfg is requested.  Only the cfgcleanup after ehcleanup2
will attempt to merge the above two blocks, which changes it to
  D.2284_38 = &__size;
  D.2283_59 = &__size;
  D.2281_60 = &__size;
  D.2281_61 = &__size;
  __r_62 = &__size;
which unfortunately means that the last stmt in thise bb is considered to no longer throw and gimple_purge_dead_eh_edges is called on it.  But there is no further ehcleanup afterwards.  Calling remove_unreachable_handlers () from execute_cleanup_cfg_post_optimizing or scheduling another ehcleanup pass right before it would fix it, but it would make compilation tiny bit slower because of another pass through all stmts.
Comment 3 Jakub Jelinek 2011-11-23 16:47:04 UTC
Created attachment 25903 [details]
gcc47-pr50682.patch

We can perhaps only call it if any landing pads were actually removed after the last ehcleanup pass.
Comment 4 Zdenek Sojka 2011-11-27 13:13:45 UTC
Created attachment 25919 [details]
another testcase

This testcase doesn't need any -fno-* flags. It might be the same problem (the backtrace is the same).

$ gcc -O2 -fnon-call-exceptions -mfma4 testcase.C
==18808== Invalid read of size 4
==18808==    at 0xB961F3: main_block_label(tree_node*) (tree-cfg.c:1092)
==18808==    by 0xB9A56B: cleanup_dead_labels() (tree-cfg.c:1121)
==18808==    by 0xBEAB9C: execute_cleanup_cfg_post_optimizing() (tree-optimize.c:162)
==18808==    by 0xA89CF4: execute_one_pass(opt_pass*) (passes.c:2074)
==18808==    by 0xA8A094: execute_pass_list(opt_pass*) (passes.c:2129)
==18808==    by 0xBEB5BD: tree_rest_of_compilation(tree_node*) (tree-optimize.c:420)
==18808==    by 0x83F949: cgraph_expand_function(cgraph_node*) (cgraphunit.c:1819)
==18808==    by 0x8416EB: cgraph_optimize() (cgraphunit.c:1886)
==18808==    by 0x841E59: cgraph_finalize_compilation_unit() (cgraphunit.c:1327)
==18808==    by 0x6632EA: cp_write_global_declarations() (decl2.c:4050)
==18808==    by 0xB7EE43: toplev_main(int, char**) (toplev.c:581)
==18808==    by 0x674ED2C: (below main) (in /lib64/libc-2.12.2.so)
==18808==  Address 0x50 is not stack'd, malloc'd or (recently) free'd
==18808== 
testcase.C: In function 'void test01()':
testcase.C:21:1: 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.

However, when the code is modified a little (ternary operator is replaced by if/else), the crash is different:
$ gcc -O2 -fnon-call-exceptions -mfma4 testcase.C                     
testcase.C: In function 'void test01()':
testcase.C:21:1: error: BB 2 can not throw but has an EH edge
testcase.C:21:1: internal compiler error: verify_flow_info failed
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
Comment 5 Jakub Jelinek 2011-11-28 21:02:33 UTC
Author: jakub
Date: Mon Nov 28 21:02:27 2011
New Revision: 181785

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=181785
Log:
	PR tree-optimization/50682
	* tree-eh.c (maybe_remove_unreachable_handlers): New function.
	* tree-flow.h (maybe_remove_unreachable_handlers): New prototype.
	* tree-optimize.c (execute_cleanup_cfg_post_optimizing): Call it.

	* g++.dg/opt/pr50682.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/opt/pr50682.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-eh.c
    trunk/gcc/tree-flow.h
    trunk/gcc/tree-optimize.c
Comment 6 Jakub Jelinek 2011-11-28 21:08:07 UTC
Fixed.