From: Alexander Monakov Date: Fri, 14 Jan 2022 17:23:41 +0000 (+0300) Subject: tree-ssa-sink: do not sink to in front of setjmp X-Git-Tag: basepoints/gcc-14~5455 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=76c3f0dc2f815e0e450642efd5348c3ab852e4d0;p=thirdparty%2Fgcc.git tree-ssa-sink: do not sink to in front of setjmp gcc/ChangeLog: * tree-ssa-sink.cc (select_best_block): Punt if selected block has incoming abnormal edges. gcc/testsuite/ChangeLog: * gcc.dg/setjmp-7.c: New test. --- diff --git a/gcc/testsuite/gcc.dg/setjmp-7.c b/gcc/testsuite/gcc.dg/setjmp-7.c new file mode 100644 index 00000000000..44b5bcbfa9d --- /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.cc b/gcc/tree-ssa-sink.cc index 2e744d6ae50..9213052017a 100644 --- a/gcc/tree-ssa-sink.cc +++ b/gcc/tree-ssa-sink.cc @@ -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. */