This backport contains 3 patch from releases/gcc-8.3.0 stream tree. The commit id of these patchs list as following in the order of time. 0001-tree-ssa-pre.c-print_pre_expr-Handle-NULL-expr.patch 34e5c5116fa58f77ea5eef61d8fb6b9e91c92d79 0001-re-PR-tree-optimization-81900-GCC-trunk-miscompiles-.patch 404938eda1ea3f5dcbca089aa7b23dc04f75b9e0 0001-re-PR-tree-optimization-83685-ICE-SSA-corruption.patch e207c07997748ec104a1caf295e66abb75f0eb3f diff --git a/gcc/cfganal.c b/gcc/cfganal.c index 7377a7a04..3c127d6a4 100644 --- a/gcc/cfganal.c +++ b/gcc/cfganal.c @@ -752,23 +752,24 @@ post_order_compute (int *post_order, bool include_entry_exit, basic_block dfs_find_deadend (basic_block bb) { - bitmap visited = BITMAP_ALLOC (NULL); + auto_bitmap visited; + basic_block next = bb; for (;;) { - if (EDGE_COUNT (bb->succs) == 0 - || ! bitmap_set_bit (visited, bb->index)) - { - BITMAP_FREE (visited); - return bb; - } + if (EDGE_COUNT (next->succs) == 0) + return next; + + if (! bitmap_set_bit (visited, next->index)) + return bb; + bb = next; /* If we are in an analyzed cycle make sure to try exiting it. Note this is a heuristic only and expected to work when loop fixup is needed as well. */ if (! bb->loop_father || ! loop_outer (bb->loop_father)) - bb = EDGE_SUCC (bb, 0)->dest; + next = EDGE_SUCC (bb, 0)->dest; else { edge_iterator ei; @@ -776,7 +777,7 @@ dfs_find_deadend (basic_block bb) FOR_EACH_EDGE (e, ei, bb->succs) if (loop_exit_edge_p (bb->loop_father, e)) break; - bb = e ? e->dest : EDGE_SUCC (bb, 0)->dest; + next = e ? e->dest : EDGE_SUCC (bb, 0)->dest; } } diff --git a/gcc/testsuite/gcc.dg/torture/pr81900.c b/gcc/testsuite/gcc.dg/torture/pr81900.c new file mode 100644 index 000000000..9e4e8f4a7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr81900.c @@ -0,0 +1,19 @@ +/* PR/81900 */ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ +/* { dg-options "-fdump-tree-optimized" } */ + +void Perl_croak() __attribute__((noreturn)); +char *Perl_sv_gets(); +void __attribute__((returns_twice)) __sigsetjmp (); +void a() { + __sigsetjmp(); + char *b; + if ((b = Perl_sv_gets()) == 0) + Perl_croak("No Perl script found in input\n"); + if (*b == '#') + __asm__("" : : ""("badbad")); +} + +/* Do not elide the test against zero. */ +/* { dg-final { scan-tree-dump " == 0B" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pr83685.c b/gcc/testsuite/gcc.dg/torture/pr83685.c new file mode 100644 index 000000000..062f75d23 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr83685.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +int _setjmp (void *); +void foo (int); + +void +bar (int e, int b, char c, void *d) +{ + while (b) + { + if (_setjmp (d)) + foo (e); + if (c) + { + e--; + foo (0); + } + e++; + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-5.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-5.c index 5044c7301..95aabdaf6 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-5.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/split-path-5.c @@ -41,20 +41,4 @@ bmhi_init (const char *pattern) } } -char * -bmhi_search (const char *string, const int stringlen) -{ - int i, j; - char *s; - for (;;) - { - while (--j >= 0 && ( - { - __typeof__ (s[j]) __x = (s[j]); - ((((__ctype_ptr__ + - sizeof (""[__x]))[(int) (__x)]) & - (01 | 02)) == - 02) ? (int) __x - 'a' + - 'A' : (int) __x;}) == pat[j]); -}} -/* { dg-final { scan-tree-dump-times "Duplicating join block" 2 "split-paths" } } */ +/* { dg-final { scan-tree-dump-times "Duplicating join block" 1 "split-paths" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c index 64b30ca1e..863aa79b4 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c @@ -26,9 +26,6 @@ int main(void) by marking the j % 7 condition as useful. See PR45178. */ /* We should eliminate the inner condition, but the loop must be preserved - as it is infinite. Therefore there should be just one phi node (for i): */ -/* { dg-final { scan-tree-dump-times "PHI " 1 "cddce1" { xfail *-*-* } } } */ - -/* And one if (for the exit condition of the loop): */ -/* { dg-final { scan-tree-dump-times "if " 1 "cddce1" } } */ - + as it is infinite. Therefore there should be just one goto and no PHI. */ +/* { dg-final { scan-tree-dump-times "PHI " 0 "cddce1" } } */ +/* { dg-final { scan-tree-dump-times "goto" 1 "cddce1" } } */ diff --git a/gcc/testsuite/gcc.dg/uninit-23.c b/gcc/testsuite/gcc.dg/uninit-23.c index b38e1d08e..d64eb7d2e 100644 --- a/gcc/testsuite/gcc.dg/uninit-23.c +++ b/gcc/testsuite/gcc.dg/uninit-23.c @@ -15,10 +15,10 @@ ql (void) for (;;) { int *go; - int *t4 = go; + int *t4 = go; /* { dg-warning "is used uninitialized" } */ l1: - *t4 = (*t4 != 0) ? 0 : 2; /* { dg-warning "may be used uninitialized" } */ + *t4 = (*t4 != 0) ? 0 : 2; } if (ij != 0) diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 0ab36bb64..b7cc7a399 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -834,7 +834,7 @@ bitmap_set_and (bitmap_set_t dest, bitmap_set_t orig) } } -/* Subtract all values and expressions contained in ORIG from DEST. */ +/* Subtract all expressions contained in ORIG from DEST. */ static bitmap_set_t bitmap_set_subtract (bitmap_set_t dest, bitmap_set_t orig) @@ -856,7 +856,7 @@ bitmap_set_subtract (bitmap_set_t dest, bitmap_set_t orig) return result; } -/* Subtract all the values in bitmap set B from bitmap set A. */ +/* Subtract all values in bitmap set B from bitmap set A. */ static void bitmap_set_subtract_values (bitmap_set_t a, bitmap_set_t b) @@ -982,6 +982,11 @@ bitmap_value_insert_into_set (bitmap_set_t set, pre_expr expr) static void print_pre_expr (FILE *outfile, const pre_expr expr) { + if (! expr) + { + fprintf (outfile, "NULL"); + return; + } switch (expr->kind) { case CONSTANT: @@ -2097,16 +2102,15 @@ static sbitmap has_abnormal_preds; static bool compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) { - bool changed = false; bitmap_set_t S, old, ANTIC_OUT; bitmap_iterator bi; unsigned int bii; edge e; edge_iterator ei; - bool was_visited = BB_VISITED (block); - old = ANTIC_OUT = S = NULL; + bool changed = ! BB_VISITED (block); BB_VISITED (block) = 1; + old = ANTIC_OUT = S = NULL; /* If any edges from predecessors are abnormal, antic_in is empty, so do nothing. */ @@ -2195,7 +2199,7 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) /* clean (ANTIC_IN (block)) is defered to after the iteration converged because it can cause non-convergence, see for example PR81181. */ - if (!was_visited || !bitmap_set_equal (old, ANTIC_IN (block))) + if (!bitmap_set_equal (old, ANTIC_IN (block))) changed = true; maybe_dump_sets: @@ -2374,9 +2378,6 @@ compute_antic (void) if (e->flags & EDGE_ABNORMAL) { bitmap_set_bit (has_abnormal_preds, block->index); - - /* We also anticipate nothing. */ - BB_VISITED (block) = 1; break; } @@ -2396,7 +2397,9 @@ compute_antic (void) int postorder_num = inverted_post_order_compute (postorder); auto_sbitmap worklist (last_basic_block_for_fn (cfun) + 1); - bitmap_ones (worklist); + bitmap_clear (worklist); + FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) + bitmap_set_bit (worklist, e->src->index); while (changed) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -2770,6 +2773,8 @@ create_expression_by_pieces (basic_block block, pre_expr expr, that value numbering saw through. */ case NAME: folded = PRE_EXPR_NAME (expr); + if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (folded)) + return NULL_TREE; if (useless_type_conversion_p (exprtype, TREE_TYPE (folded))) return folded; break;