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:
parent
b49e41743c
commit
021293cb5a
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
48
gcc/testsuite/gcc.c-torture/execute/pr60003.c
Normal file
48
gcc/testsuite/gcc.c-torture/execute/pr60003.c
Normal 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;
|
||||
}
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user