diff options
author | Alexander Monakov <amonakov@ispras.ru> | 2022-01-14 20:23:41 +0300 |
---|---|---|
committer | Alexander Monakov <amonakov@ispras.ru> | 2022-07-19 17:16:08 +0300 |
commit | 76c3f0dc2f815e0e450642efd5348c3ab852e4d0 (patch) | |
tree | 97cd38a4036696f3ac21df724c76360ab15e90d9 /gcc | |
parent | 465802c0d40adca5fd5b0a2af6ff8a323a55b589 (diff) | |
download | gcc-76c3f0dc2f815e0e450642efd5348c3ab852e4d0.zip gcc-76c3f0dc2f815e0e450642efd5348c3ab852e4d0.tar.gz gcc-76c3f0dc2f815e0e450642efd5348c3ab852e4d0.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.dg/setjmp-7.c | 13 | ||||
-rw-r--r-- | gcc/tree-ssa-sink.cc | 6 |
2 files changed, 19 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/setjmp-7.c b/gcc/testsuite/gcc.dg/setjmp-7.c new file mode 100644 index 0000000..44b5bcb --- /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 2e744d6..9213052 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. */ |