Bug 89280 - [7/8 Regression] ICE: Segmentation fault (in is_gimple_reg_type)
Summary: [7/8 Regression] ICE: Segmentation fault (in is_gimple_reg_type)
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: 7.5
Assignee: Jakub Jelinek
Keywords: ice-on-valid-code
: 89283 (view as bug list)
Depends on:
Reported: 2019-02-11 07:37 UTC by Arseny Solokha
Modified: 2019-02-27 15:22 UTC (History)
3 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed: 2019-02-11 00:00:00

gcc9-pr89280.patch (1.31 KB, patch)
2019-02-21 10:49 UTC, Jakub Jelinek
Details | Diff
gcc9-pr89280.patch (2.34 KB, patch)
2019-02-22 11:48 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Arseny Solokha 2019-02-11 07:37:14 UTC
gcc-9.0.0-alpha20190210 snapshot (r268755) ICEs when compiling the following testcase containing a call of function w/ returns_twice attribute:

int un;

r8 (void);

__attribute__ ((returns_twice)) int
vfork (void);

ef (int, int);

fx (void)
  for (;;)
    r8 ();

  ef (vfork (), un);

% gcc-9.0.0-alpha20190210 -c df3xie9n.c
during GIMPLE pass: cfg
df3xie9n.c: In function 'fx':
df3xie9n.c:13:1: internal compiler error: Segmentation fault
   13 | fx (void)
      | ^~
0xd6f9bf crash_signal
0xda85b4 is_gimple_reg_type
0xda85b4 verify_gimple_call
0xdbe2ca verify_gimple_in_cfg(function*, bool)
0xc8a4df execute_function_todo
0xc8b3fe execute_todo
Comment 1 Martin Liška 2019-02-11 07:54:33 UTC
Started with r235817.
Comment 2 Jakub Jelinek 2019-02-11 08:28:29 UTC
Ugh, this is nasty.  We add the ABNORMAL_DISPATCHER etc. because vfork returns twice, but because the call is in unreachable code, we remove the block that defines the SSA_NAME but nothing finds out that because the vfork was originally unreachable, it can't be reached abnormally either.
So perhaps improve the unreachable block analysis that edges from ABNORMAL_DISPATCHER are only valid if a block is reachable through some other edges too?
Comment 3 Jakub Jelinek 2019-02-14 11:44:56 UTC
*** Bug 89283 has been marked as a duplicate of this bug. ***
Comment 4 Richard Biener 2019-02-14 12:28:40 UTC
The issue is that r8 () is a source of abnormal edges which makes the abnormal
dispatcher reachable.  I think the testcase becomes clearer when one uses
setjmp instead of vfork since I'm not sure why we have full abnormal handling
for vfork at all.

It might work if we build the CFG first w/o any abnormal edges, then prune
unreachable blocks, and only after that do abnormal edge creation.

Also we could then build dominators on the CFG w/o abnormal edges and use
simple reachability analysis on that to determine if we need to add
outgoing abnormal edges to calls or not (like in this case the one out
of r8() is not needed).

OTOH with non-local goto the reachability analysis w/o abnormals would be
Comment 5 Jakub Jelinek 2019-02-14 12:33:43 UTC
The problem is that it might be still reachable through both normal and abnormal edges during cfg and might become unreachable only later (e.g. inlining or whatever other opt), so we need something that will be able to cope with it at any time.  Even if we improve decisions from which bbs to add edges to the ABNORMAL_DISPATCHER, as we use one dispatcher for the whole function and can mix non-local gotos etc. with returns_twice functions, I think we can't avoid this problem, r8 e.g. could have a non-local goto to some other bb and so would have EDGE_ABNORMAL edge to the dispatcher.
Comment 6 Jakub Jelinek 2019-02-21 09:45:53 UTC
On the other side, after going into SSA, the ABNORMAL_DISPATCHER successors would have PHIs for the SSA_NAMEs and thus ICE like this wouldn't happen, so in theory we could do something in the cfg pass itself only.
Comment 7 Jakub Jelinek 2019-02-21 10:49:21 UTC
Created attachment 45783 [details]

Untested fix.
Comment 8 Jakub Jelinek 2019-02-21 10:56:36 UTC
Seems to work fine even if the dead returns_twice call is found later, e.g. on
int a;
void foo (void);
__attribute__ ((returns_twice)) int bar (void);
void baz (int, int);

static inline void
inl (int x)
  while (x)
    foo ();

qux (void)
  inl (1);
  baz (bar (), a);

it simplifies the GIMPLE IL in einline (and further in ethread), in the end generates in this case the same assembly, because we don't have those edges in RTL and so RTL optimizations cure it.  But the abnormal SSA_NAMEs etc. could get in the way of quite a few optimizations.
Comment 9 Jakub Jelinek 2019-02-22 11:48:29 UTC
Created attachment 45798 [details]

Updated patch.  The previous patch completely broke __builtin_setjmp_{setup,receiver} handling, where the latter is normally only reachable through EDGE_ABNORMAL edge.  We need to make those visited if the corresponding __builtin_setjmp_setup is visited.
Comment 10 Jakub Jelinek 2019-02-27 08:41:33 UTC
Author: jakub
Date: Wed Feb 27 08:41:01 2019
New Revision: 269243

URL: https://gcc.gnu.org/viewcvs?rev=269243&root=gcc&view=rev
	PR tree-optimization/89280
	* tree-cfgcleanup.c (maybe_dead_abnormal_edge_p,
	builtin_setjmp_setup_bb): New functions.
	(cleanup_control_flow_pre): Ignore maybe_dead_abnormal_edge_p edges.
	When visiting __builtin_setjmp_setup block, queue in special
	setjmp_vec vector edges from .ABNORMAL_DISPATCHER to corresponding
	__builtin_setjmp_receiver.  Remove .ABNORMAL_DISPATCHER basic blocks
	from visited after the loop if they don't have any visited successor

	* gcc.c-torture/compile/pr89280.c: New test.
	* gcc.dg/torture/pr57147-2.c: Don't expect a setjmp after noreturn
	function.  Skip the test for -O0.

Comment 11 Jakub Jelinek 2019-02-27 08:52:06 UTC
Fixed on the trunk.
Comment 12 Jakub Jelinek 2019-02-27 15:22:48 UTC
Author: jakub
Date: Wed Feb 27 15:22:16 2019
New Revision: 269256

URL: https://gcc.gnu.org/viewcvs?rev=269256&root=gcc&view=rev
	PR tree-optimization/89280
	* gcc.dg/torture/pr57147-2.c (SetNaClSwitchExpectations): Add static