Hi! The GIMPLE bb removal code doesn't really remove GIMPLE_LABEL stmts referencing FORCED_LABELs (and likewise non-local labels, except it turns them into FORCED_LABELs), but instead moves them at the start of some other bb.
As can be seen on the testcases, that breaks if (prev_stmt && EH_LANDING_PAD_NR (label) != 0) { error ("EH landing pad label "); print_generic_expr (stderr, label); fprintf (stderr, " is not first in a sequence of labels in bb %d", bb->index); err = 1; } checking and in theory could break if (prev_stmt && DECL_NONLOCAL (label)) { error ("nonlocal label "); print_generic_expr (stderr, label); fprintf (stderr, " is not first in a sequence of labels in bb %d", bb->index); err = 1; } too. Fixed by moving these FORCED_LABELs after the existing labels in the other bb, rather than before those. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-04-24 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/90208 * tree-cfg.c (remove_bb): Move forced labels from removed bbs after labels of new_bb, not before them. * gcc.dg/tsan/pr90208-1.c: New test. * gcc.dg/tsan/pr90208-2.c: New test. --- gcc/tree-cfg.c.jj 2019-03-14 23:44:27.861560155 +0100 +++ gcc/tree-cfg.c 2019-04-23 14:40:05.949571172 +0200 @@ -2265,7 +2265,7 @@ remove_bb (basic_block bb) new_bb = single_succ (new_bb); gcc_assert (new_bb != bb); } - new_gsi = gsi_start_bb (new_bb); + new_gsi = gsi_after_labels (new_bb); gsi_remove (&i, false); gsi_insert_before (&new_gsi, stmt, GSI_NEW_STMT); } --- gcc/testsuite/gcc.dg/tsan/pr90208-1.c.jj 2019-04-23 14:48:16.034625947 +0200 +++ gcc/testsuite/gcc.dg/tsan/pr90208-1.c 2019-04-23 14:48:12.450684051 +0200 @@ -0,0 +1,5 @@ +/* PR tree-optimization/90208 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fexceptions -fsanitize=thread" } */ + +#include "../../gcc.c-torture/compile/pr89280.c" --- gcc/testsuite/gcc.dg/tsan/pr90208-2.c.jj 2019-04-23 14:50:23.850553809 +0200 +++ gcc/testsuite/gcc.dg/tsan/pr90208-2.c 2019-04-23 14:51:09.819808554 +0200 @@ -0,0 +1,20 @@ +/* PR tree-optimization/90208 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fexceptions -fsanitize=thread" } */ + +void *b[5]; +void foo (void); + +void +bar (int d) +{ + while (d) + foo (); +} + +void +baz (void) +{ + bar (2); + __builtin_setjmp (b); +} Jakub