re PR tree-optimization/60003 (wrong code with __builtin_setjmp/__builtin_longjmp and inlining)

PR tree-optimization/60003
	* gimple-low.c (lower_builtin_setjmp): Set cfun->has_nonlocal_label.
	* profile.c (branch_prob): Use gimple_call_builtin_p
	to check for BUILT_IN_SETJMP_RECEIVER.
	* tree-inline.c (copy_bb): Call notice_special_calls.

	* gcc.c-torture/execute/pr60003.c: New test.

From-SVN: r207382
This commit is contained in:
Jakub Jelinek 2014-02-01 09:40:31 +01:00 committed by Jakub Jelinek
parent b49e41743c
commit 021293cb5a
6 changed files with 69 additions and 11 deletions

View File

@ -1,3 +1,11 @@
2014-02-01 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/60003
* gimple-low.c (lower_builtin_setjmp): Set cfun->has_nonlocal_label.
* profile.c (branch_prob): Use gimple_call_builtin_p
to check for BUILT_IN_SETJMP_RECEIVER.
* tree-inline.c (copy_bb): Call notice_special_calls.
2014-01-31 Vladimir Makarov <vmakarov@redhat.com>
PR bootstrap/59985

View File

@ -709,6 +709,12 @@ lower_builtin_setjmp (gimple_stmt_iterator *gsi)
tree dest, t, arg;
gimple g;
/* __builtin_setjmp_{setup,receiver} aren't ECF_RETURNS_TWICE and for RTL
these builtins are modelled as non-local label jumps to the label
that is passed to these two builtins, so pretend we have a non-local
label during GIMPLE passes too. See PR60003. */
cfun->has_nonlocal_label = true;
/* NEXT_LABEL is the label __builtin_longjmp will jump to. Its address is
passed to both __builtin_setjmp_setup and __builtin_setjmp_receiver. */
FORCED_LABEL (next_label) = 1;

View File

@ -1104,7 +1104,6 @@ branch_prob (void)
{
gimple_stmt_iterator gsi;
gimple first;
tree fndecl;
gsi = gsi_start_nondebug_after_labels_bb (bb);
gcc_checking_assert (!gsi_end_p (gsi));
@ -1114,10 +1113,7 @@ branch_prob (void)
special and don't expect anything to be inserted before
them. */
if (is_gimple_call (first)
&& (((fndecl = gimple_call_fndecl (first)) != NULL
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
&& (DECL_FUNCTION_CODE (fndecl)
== BUILT_IN_SETJMP_RECEIVER))
&& (gimple_call_builtin_p (first, BUILT_IN_SETJMP_RECEIVER)
|| (gimple_call_flags (first) & ECF_RETURNS_TWICE)
|| (gimple_call_internal_p (first)
&& (gimple_call_internal_fn (first)

View File

@ -1,3 +1,8 @@
2014-02-01 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/60003
* gcc.c-torture/execute/pr60003.c: New test.
2014-01-31 Vladimir Makarov <vmakarov@redhat.com>
PR bootstrap/59985

View File

@ -0,0 +1,48 @@
/* PR tree-optimization/60003 */
extern void abort (void);
unsigned long long jmp_buf[5];
__attribute__((noinline, noclone)) void
baz (void)
{
__builtin_longjmp (&jmp_buf, 1);
}
void
bar (void)
{
baz ();
}
__attribute__((noinline, noclone)) int
foo (int x)
{
int a = 0;
if (__builtin_setjmp (&jmp_buf) == 0)
{
while (1)
{
a = 1;
bar (); /* OK if baz () instead */
}
}
else
{
if (a == 0)
return 0;
else
return x;
}
}
int
main ()
{
if (foo (1) == 0)
abort ();
return 0;
}

View File

@ -1745,7 +1745,6 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
if (is_gimple_call (stmt))
{
struct cgraph_edge *edge;
int flags;
switch (id->transform_call_graph_edges)
{
@ -1868,11 +1867,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
}
}
flags = gimple_call_flags (stmt);
if (flags & ECF_MAY_BE_ALLOCA)
cfun->calls_alloca = true;
if (flags & ECF_RETURNS_TWICE)
cfun->calls_setjmp = true;
notice_special_calls (stmt);
}
maybe_duplicate_eh_stmt_fn (cfun, stmt, id->src_cfun, orig_stmt,