gcc/ChangeLog: * tree-ssa-sink.c (select_best_block): Punt if selected block has incoming abnormal edges.
gcc/testsuite/ChangeLog: * gcc.dg/setjmp-7.c: New test. --- gcc/testsuite/gcc.dg/setjmp-7.c | 13 +++++++++++++ gcc/tree-ssa-sink.c | 6 ++++++ 2 files changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/setjmp-7.c diff --git a/gcc/testsuite/gcc.dg/setjmp-7.c b/gcc/testsuite/gcc.dg/setjmp-7.c new file mode 100644 index 000000000..44b5bcbfa --- /dev/null +++ b/gcc/testsuite/gcc.dg/setjmp-7.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-guess-branch-probability -w" } */ +/* { dg-require-effective-target indirect_jumps } */ + +struct __jmp_buf_tag { }; +typedef struct __jmp_buf_tag jmp_buf[1]; +struct globals { jmp_buf listingbuf; }; +extern struct globals *const ptr_to_globals; +void foo() +{ + if ( _setjmp ( ((*ptr_to_globals).listingbuf ))) + ; +} diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c index 66d7ae89e..016ecbaec 100644 --- a/gcc/tree-ssa-sink.c +++ b/gcc/tree-ssa-sink.c @@ -208,6 +208,12 @@ select_best_block (basic_block early_bb, temp_bb = get_immediate_dominator (CDI_DOMINATORS, temp_bb); } + /* Placing a statement before a setjmp-like function would be invalid + (it cannot be reevaluated when execution follows an abnormal edge). + If we selected a block with abnormal predecessors, just punt. */ + if (bb_has_abnormal_pred (best_bb)) + return early_bb; + /* If we found a shallower loop nest, then we always consider that a win. This will always give us the most control dependent block within that loop nest. */ -- 2.33.1