From 351168fe551a792fac3dac3359de72c1bcdc651e Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 14 Jul 2016 12:15:38 +0000 Subject: [PATCH] re PR tree-optimization/71866 (gcc locks up after fix for PR70159) 2016-07-14 Richard Biener PR tree-optimization/71866 * tree-ssa-pre.c (get_constant_for_value_id): Remove. (do_hoist_insertion): Avoid endless recursion when we didn't insert anything because we managed to simplify things down to a constant or SSA name. (fully_constant_expression): Re-write in terms of ... * tree-ssa-sccvn.h (vn_nary_simplify): ... this. Declare. * tree-ssa-sccvn.c (vn_nary_simplify): New wrapper around vn_nary_build_or_lookup_1. (vn_nary_build_or_lookup_1): Added flag and renamed from ... (vn_nary_build_or_lookup): ... this which now wraps it. * gcc.dg/torture/pr71866.c: New testcase. From-SVN: r238334 --- gcc/ChangeLog | 14 +++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/torture/pr71866.c | 40 +++++++++ gcc/tree-ssa-pre.c | 117 +++++-------------------- gcc/tree-ssa-sccvn.c | 31 ++++++- gcc/tree-ssa-sccvn.h | 1 + 6 files changed, 109 insertions(+), 99 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr71866.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a1cf7424d9d..24b929812b6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2016-07-14 Richard Biener + + PR tree-optimization/71866 + * tree-ssa-pre.c (get_constant_for_value_id): Remove. + (do_hoist_insertion): Avoid endless recursion when we + didn't insert anything because we managed to simplify + things down to a constant or SSA name. + (fully_constant_expression): Re-write in terms of ... + * tree-ssa-sccvn.h (vn_nary_simplify): ... this. Declare. + * tree-ssa-sccvn.c (vn_nary_simplify): New wrapper around + vn_nary_build_or_lookup_1. + (vn_nary_build_or_lookup_1): Added flag and renamed from ... + (vn_nary_build_or_lookup): ... this which now wraps it. + 2016-07-14 Alan Modra PR target/71733 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c5a737926a1..6c85d55bcad 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-07-14 Richard Biener + + PR tree-optimization/71866 + * gcc.dg/torture/pr71866.c: New testcase. + 2016-07-14 Thomas Preud'homme * gcc.target/arm/pr42574.c: Add missing target keyword for the dg-do diff --git a/gcc/testsuite/gcc.dg/torture/pr71866.c b/gcc/testsuite/gcc.dg/torture/pr71866.c new file mode 100644 index 00000000000..e1b36cb8b7d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr71866.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ftree-pre -fcode-hoisting" } */ + +typedef unsigned char u8; +extern unsigned long pci_io_base; +u8 in_8 (const volatile void *); +int eeh_enabled (); +void eeh_check_failure (); +static inline +u8 eeh_readb(const volatile void *addr) +{ + u8 val = in_8(addr); + if (((val) == (u8)~0 && eeh_enabled())) eeh_check_failure(); + return val; +} +extern struct ppc_pci_io { + void (*outb) (u8 val, unsigned long port); +} +ppc_pci_io; +static inline +u8 readb (const volatile void * addr) +{ + return eeh_readb((addr)); +} +static inline +u8 inb (unsigned long port) +{ + return readb((volatile void *)pci_io_base + port); +} +static inline +void outb (u8 val, unsigned long port) +{ + if (ppc_pci_io.outb != ((void *)0)) ppc_pci_io.outb (val, port); +}; +void frob_econtrol(unsigned long base_hi, unsigned char m, unsigned char v) +{ + unsigned char ectr = 0; + if (m != 0xff) ectr = inb((base_hi + 0x2)); + outb((ectr & ~m) ^ v, (base_hi + 0x2)); +} diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index a5f3f712da1..518346aa8f2 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -1164,29 +1164,6 @@ get_or_alloc_expr_for_constant (tree constant) return newexpr; } -/* Given a value id V, find the actual tree representing the constant - value if there is one, and return it. Return NULL if we can't find - a constant. */ - -static tree -get_constant_for_value_id (unsigned int v) -{ - if (value_id_constant_p (v)) - { - unsigned int i; - bitmap_iterator bi; - bitmap exprset = value_expressions[v]; - - EXECUTE_IF_SET_IN_BITMAP (exprset, 0, i, bi) - { - pre_expr expr = expression_for_id (i); - if (expr->kind == CONSTANT) - return PRE_EXPR_CONSTANT (expr); - } - } - return NULL; -} - /* Get or allocate a pre_expr for a piece of GIMPLE, and return it. Currently only supports constants and SSA_NAMES. */ static pre_expr @@ -1236,76 +1213,16 @@ fully_constant_expression (pre_expr e) case NARY: { vn_nary_op_t nary = PRE_EXPR_NARY (e); - switch (TREE_CODE_CLASS (nary->opcode)) - { - case tcc_binary: - case tcc_comparison: - { - /* We have to go from trees to pre exprs to value ids to - constants. */ - tree naryop0 = nary->op[0]; - tree naryop1 = nary->op[1]; - tree result; - if (!is_gimple_min_invariant (naryop0)) - { - pre_expr rep0 = get_or_alloc_expr_for (naryop0); - unsigned int vrep0 = get_expr_value_id (rep0); - tree const0 = get_constant_for_value_id (vrep0); - if (const0) - naryop0 = fold_convert (TREE_TYPE (naryop0), const0); - } - if (!is_gimple_min_invariant (naryop1)) - { - pre_expr rep1 = get_or_alloc_expr_for (naryop1); - unsigned int vrep1 = get_expr_value_id (rep1); - tree const1 = get_constant_for_value_id (vrep1); - if (const1) - naryop1 = fold_convert (TREE_TYPE (naryop1), const1); - } - result = fold_binary (nary->opcode, nary->type, - naryop0, naryop1); - if (result && is_gimple_min_invariant (result)) - return get_or_alloc_expr_for_constant (result); - /* We might have simplified the expression to a - SSA_NAME for example from x_1 * 1. But we cannot - insert a PHI for x_1 unconditionally as x_1 might - not be available readily. */ - return e; - } - case tcc_reference: - if (nary->opcode != REALPART_EXPR - && nary->opcode != IMAGPART_EXPR - && nary->opcode != VIEW_CONVERT_EXPR) - return e; - /* Fallthrough. */ - case tcc_unary: - { - /* We have to go from trees to pre exprs to value ids to - constants. */ - tree naryop0 = nary->op[0]; - tree const0, result; - if (is_gimple_min_invariant (naryop0)) - const0 = naryop0; - else - { - pre_expr rep0 = get_or_alloc_expr_for (naryop0); - unsigned int vrep0 = get_expr_value_id (rep0); - const0 = get_constant_for_value_id (vrep0); - } - result = NULL; - if (const0) - { - tree type1 = TREE_TYPE (nary->op[0]); - const0 = fold_convert (type1, const0); - result = fold_unary (nary->opcode, nary->type, const0); - } - if (result && is_gimple_min_invariant (result)) - return get_or_alloc_expr_for_constant (result); - return e; - } - default: - return e; - } + tree res = vn_nary_simplify (nary); + if (!res) + return e; + if (is_gimple_min_invariant (res)) + return get_or_alloc_expr_for_constant (res); + /* We might have simplified the expression to a + SSA_NAME for example from x_1 * 1. But we cannot + insert a PHI for x_1 unconditionally as x_1 might + not be available readily. */ + return e; } case REFERENCE: { @@ -3618,10 +3535,18 @@ do_hoist_insertion (basic_block block) gimple_seq stmts = NULL; tree res = create_expression_by_pieces (block, expr, &stmts, get_expr_type (expr)); - if (gsi_end_p (last) || is_ctrl_stmt (gsi_stmt (last))) - gsi_insert_seq_before (&last, stmts, GSI_SAME_STMT); + + /* Do not return true if expression creation ultimately + did not insert any statements. */ + if (gimple_seq_empty_p (stmts)) + res = NULL_TREE; else - gsi_insert_seq_after (&last, stmts, GSI_NEW_STMT); + { + if (gsi_end_p (last) || is_ctrl_stmt (gsi_stmt (last))) + gsi_insert_seq_before (&last, stmts, GSI_SAME_STMT); + else + gsi_insert_seq_after (&last, stmts, GSI_NEW_STMT); + } /* Make sure to not return true if expression creation ultimately failed but also make sure to insert any stmts produced as they diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 9427bfc6062..bd752a5eccd 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -1625,10 +1625,12 @@ vn_lookup_simplify_result (code_helper rcode, tree type, tree *ops) } /* Return a value-number for RCODE OPS... either by looking up an existing - value-number for the simplified result or by inserting the operation. */ + value-number for the simplified result or by inserting the operation if + INSERT is true. */ static tree -vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops) +vn_nary_build_or_lookup_1 (code_helper rcode, tree type, tree *ops, + bool insert) { tree result = NULL_TREE; /* We will be creating a value number for @@ -1658,7 +1660,7 @@ vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops) else { tree val = vn_lookup_simplify_result (rcode, type, ops); - if (!val) + if (!val && insert) { gimple_seq stmts = NULL; result = maybe_push_res_to_seq (rcode, type, ops, &stmts); @@ -1719,6 +1721,29 @@ vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops) return result; } +/* Return a value-number for RCODE OPS... either by looking up an existing + value-number for the simplified result or by inserting the operation. */ + +static tree +vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops) +{ + return vn_nary_build_or_lookup_1 (rcode, type, ops, true); +} + +/* Try to simplify the expression RCODE OPS... of type TYPE and return + its value if present. */ + +tree +vn_nary_simplify (vn_nary_op_t nary) +{ + if (nary->length > 3) + return NULL_TREE; + tree ops[3]; + memcpy (ops, nary->op, sizeof (tree) * nary->length); + return vn_nary_build_or_lookup_1 (nary->opcode, nary->type, ops, false); +} + + /* Callback for walk_non_aliased_vuses. Tries to perform a lookup from the statement defining VUSE and if not successful tries to translate *REFP and VR_ through an aggregate copy at the definition diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h index 069590a0b01..92c255d93d2 100644 --- a/gcc/tree-ssa-sccvn.h +++ b/gcc/tree-ssa-sccvn.h @@ -234,6 +234,7 @@ unsigned int get_constant_value_id (tree); unsigned int get_or_alloc_constant_value_id (tree); bool value_id_constant_p (unsigned int); tree fully_constant_vn_reference_p (vn_reference_t); +tree vn_nary_simplify (vn_nary_op_t); /* Valueize NAME if it is an SSA name, otherwise just return it. */ -- 2.30.2