From: Richard Biener Date: Thu, 8 Mar 2018 09:23:44 +0000 (+0000) Subject: re PR tree-optimization/84746 (ICE on valid code at -O2 and -O3: Segmentation fault) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=de341bf0fbfddec8a7c0711ac5503a55f7aaf6dc;p=gcc.git re PR tree-optimization/84746 (ICE on valid code at -O2 and -O3: Segmentation fault) 2018-03-08 Richard Biener PR tree-optimization/84746 * tree-ssa-pre.c (find_leader_in_sets): Deal with SET1 being NULL. (phi_translate): Pass in destination ANTIC_OUT set. (phi_translate_1): Likewise. For a simplified result lookup a leader in ANTIC_OUT and AVAIL_OUT, not the ANTIC_IN sets. (phi_translate_set): Adjust. (do_pre_regular_insertion): Likewise. (do_pre_partial_partial_insertion): Likewise. * gcc.dg/torture/pr84746.c: New testcase. From-SVN: r258361 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2a7939745e0..380b023270e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2018-03-08 Richard Biener + + PR tree-optimization/84746 + * tree-ssa-pre.c (find_leader_in_sets): Deal with SET1 being NULL. + (phi_translate): Pass in destination ANTIC_OUT set. + (phi_translate_1): Likewise. For a simplified result lookup + a leader in ANTIC_OUT and AVAIL_OUT, not the ANTIC_IN sets. + (phi_translate_set): Adjust. + (do_pre_regular_insertion): Likewise. + (do_pre_partial_partial_insertion): Likewise. + 2018-03-08 Martin Liska PR gcov-profile/84735 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7ba35557579..4d3535d9633 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-03-08 Richard Biener + + PR tree-optimization/84746 + * gcc.dg/torture/pr84746.c: New testcase. + 2018-03-08 Alexandre Oliva PR debug/84404 diff --git a/gcc/testsuite/gcc.dg/torture/pr84746.c b/gcc/testsuite/gcc.dg/torture/pr84746.c new file mode 100644 index 00000000000..5c00a91874f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr84746.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ + +int a, b, c, d, e; +char f, g; + +void fn1 () +{ + while (1) + { + if (d) + goto L1; + if (e) + goto L3; + int q = (c && a) % (f * (d || a)) && b; + e = q; + if (b) + break; +L1: +L2: + c = f; +L3: + f = g; + while (a) + goto L2; + } +} diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 8df15bfcdb3..f165a1eb975 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -1226,9 +1226,10 @@ static inline pre_expr find_leader_in_sets (unsigned int val, bitmap_set_t set1, bitmap_set_t set2, bitmap_set_t set3 = NULL) { - pre_expr result; + pre_expr result = NULL; - result = bitmap_find_leader (set1, val); + if (set1) + result = bitmap_find_leader (set1, val); if (!result && set2) result = bitmap_find_leader (set2, val); if (!result && set3) @@ -1332,14 +1333,15 @@ get_representative_for (const pre_expr e, basic_block b = NULL) static pre_expr -phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e); +phi_translate (bitmap_set_t, pre_expr, bitmap_set_t, bitmap_set_t, edge); /* Translate EXPR using phis in PHIBLOCK, so that it has the values of the phis in PRED. Return NULL if we can't find a leader for each part of the translated expression. */ static pre_expr -phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e) +phi_translate_1 (bitmap_set_t dest, + pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e) { basic_block pred = e->src; basic_block phiblock = e->dest; @@ -1363,10 +1365,11 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e) pre_expr leader, result; unsigned int op_val_id = VN_INFO (newnary->op[i])->value_id; leader = find_leader_in_sets (op_val_id, set1, set2); - result = phi_translate (leader, set1, set2, e); + result = phi_translate (dest, leader, set1, set2, e); if (result && result != leader) - /* Force a leader as well as we are simplifying this - expression. */ + /* If op has a leader in the sets we translate make + sure to use the value of the translated expression. + We might need a new representative for that. */ newnary->op[i] = get_representative_for (result, pred); else if (!result) return NULL; @@ -1399,7 +1402,12 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e) else { unsigned value_id = get_expr_value_id (constant); - constant = find_leader_in_sets (value_id, set1, set2, + /* We want a leader in ANTIC_OUT or AVAIL_OUT here. + dest has what we computed into ANTIC_OUT sofar + so pick from that - since topological sorting + by sorted_array_from_bitmap_set isn't perfect + we may lose some cases here. */ + constant = find_leader_in_sets (value_id, dest, AVAIL_OUT (pred)); if (constant) return constant; @@ -1485,7 +1493,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e) } op_val_id = VN_INFO (op[n])->value_id; leader = find_leader_in_sets (op_val_id, set1, set2); - opresult = phi_translate (leader, set1, set2, e); + opresult = phi_translate (dest, leader, set1, set2, e); if (opresult && opresult != leader) { tree name = get_representative_for (opresult); @@ -1635,7 +1643,8 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e) /* Wrapper around phi_translate_1 providing caching functionality. */ static pre_expr -phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e) +phi_translate (bitmap_set_t dest, pre_expr expr, + bitmap_set_t set1, bitmap_set_t set2, edge e) { expr_pred_trans_t slot = NULL; pre_expr phitrans; @@ -1661,7 +1670,7 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e) } /* Translate. */ - phitrans = phi_translate_1 (expr, set1, set2, e); + phitrans = phi_translate_1 (dest, expr, set1, set2, e); if (slot) { @@ -1698,7 +1707,7 @@ phi_translate_set (bitmap_set_t dest, bitmap_set_t set, edge e) FOR_EACH_VEC_ELT (exprs, i, expr) { pre_expr translated; - translated = phi_translate (expr, set, NULL, e); + translated = phi_translate (dest, expr, set, NULL, e); if (!translated) continue; @@ -3199,7 +3208,7 @@ do_pre_regular_insertion (basic_block block, basic_block dom) gcc_assert (!(pred->flags & EDGE_FAKE)); bprime = pred->src; /* We are looking at ANTIC_OUT of bprime. */ - eprime = phi_translate (expr, ANTIC_IN (block), NULL, pred); + eprime = phi_translate (NULL, expr, ANTIC_IN (block), NULL, pred); /* eprime will generally only be NULL if the value of the expression, translated @@ -3354,7 +3363,7 @@ do_pre_partial_partial_insertion (basic_block block, basic_block dom) and so not come across fake pred edges. */ gcc_assert (!(pred->flags & EDGE_FAKE)); bprime = pred->src; - eprime = phi_translate (expr, ANTIC_IN (block), + eprime = phi_translate (NULL, expr, ANTIC_IN (block), PA_IN (block), pred); /* eprime will generally only be NULL if the