From 83692f96622d65acd462df4cea225b7bc2827d80 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 2 Mar 2017 07:53:42 +0000 Subject: [PATCH] re PR tree-optimization/79777 (ICE on -Os and above in on aarch64-linux-gnu (internal compiler error: in VN_INFO_GET, at tree-ssa-sccvn.c:407 })) 2017-03-02 Richard Biener PR tree-optimization/79777 * tree-ssa-pre.c (eliminate_insert): Give up if we simplify the to insert expression to sth existing. * gcc.dg/torture/pr79777.c: New testcase. From-SVN: r245830 --- gcc/ChangeLog | 6 ++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/torture/pr79777.c | 38 +++++++++++++++++++++++++ gcc/tree-ssa-pre.c | 39 +++++++++++++++++++++++--- 4 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr79777.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4f440866081..530acbb9ba3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-03-02 Richard Biener + + PR tree-optimization/79777 + * tree-ssa-pre.c (eliminate_insert): Give up if we simplify + the to insert expression to sth existing. + 2017-03-01 Martin Sebor PR middle-end/79692 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 59264c2d4ef..8d926096459 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-03-02 Richard Biener + + PR tree-optimization/79777 + * gcc.dg/torture/pr79777.c: New testcase. + 2017-03-01 Martin Sebor PR middle-end/79692 diff --git a/gcc/testsuite/gcc.dg/torture/pr79777.c b/gcc/testsuite/gcc.dg/torture/pr79777.c new file mode 100644 index 00000000000..eb1bec776e2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr79777.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ + +typedef unsigned short __u16; +typedef unsigned int __u32; +typedef unsigned char u8; +typedef unsigned int u32; +typedef __u16 __le16; +typedef __u32 __le32; +typedef u32 secno; +struct bplus_internal_node { + __le32 file_secno; + __le32 down; +}; +struct bplus_header { + u8 n_used_nodes; + __le16 first_free; + union { + struct bplus_internal_node internal[0]; + } + u; +}; + +__u16 __fswab16(__u16 val); +__u32 __fswab32(__u32 val); +void hpfs_ea_remove (__u32); + +void hpfs_truncate_btree(secno f, int fno, unsigned secs, struct bplus_header *btree) +{ + int i, j; + for (i = 0; i < btree->n_used_nodes; i++) + if ((__builtin_constant_p((__u32)(( __u32)(__le32)(btree->u.internal[i].file_secno))) ? ((__u32)( (((__u32)(( __u32)(__le32)(btree->u.internal[i].file_secno)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__le32)(btree->u.internal[i].file_secno)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__le32)(btree->u.internal[i].file_secno)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__le32)(btree->u.internal[i].file_secno)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__le32)(btree->u.internal[i].file_secno))) >= secs) goto f; + return; +f: + for (j = i + 1; j < btree->n_used_nodes; j++) + hpfs_ea_remove((__builtin_constant_p((__u32)(( __u32)(__le32)(btree->u.internal[j].down))) ? ((__u32)( (((__u32)(( __u32)(__le32)(btree->u.internal[j].down)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__le32)(btree->u.internal[j].down)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__le32)(btree->u.internal[j].down)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__le32)(btree->u.internal[j].down)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__le32)(btree->u.internal[j].down)))); + btree->n_used_nodes = i + 1; + btree->first_free = (( __le16)(__builtin_constant_p((__u16)((8 + 8 * btree->n_used_nodes))) ? ((__u16)( (((__u16)((8 + 8 * btree->n_used_nodes)) & (__u16)0x00ffU) << 8) | (((__u16)((8 + 8 * btree->n_used_nodes)) & (__u16)0xff00U) >> 8))) : __fswab16((8 + 8 * btree->n_used_nodes)))); +} diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index bdf48ad7d8a..ff59d536678 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -4133,11 +4133,42 @@ eliminate_insert (gimple_stmt_iterator *gsi, tree val) else res = gimple_build (&stmts, gimple_assign_rhs_code (stmt), TREE_TYPE (val), leader); - gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); - VN_INFO_GET (res)->valnum = val; + if (TREE_CODE (res) != SSA_NAME + || SSA_NAME_IS_DEFAULT_DEF (res) + || gimple_bb (SSA_NAME_DEF_STMT (res))) + { + gimple_seq_discard (stmts); + + /* During propagation we have to treat SSA info conservatively + and thus we can end up simplifying the inserted expression + at elimination time to sth not defined in stmts. */ + /* But then this is a redundancy we failed to detect. Which means + res now has two values. That doesn't play well with how + we track availability here, so give up. */ + if (dump_file && (dump_flags & TDF_DETAILS)) + { + if (TREE_CODE (res) == SSA_NAME) + res = eliminate_avail (res); + if (res) + { + fprintf (dump_file, "Failed to insert expression for value "); + print_generic_expr (dump_file, val, 0); + fprintf (dump_file, " which is really fully redundant to "); + print_generic_expr (dump_file, res, 0); + fprintf (dump_file, "\n"); + } + } - if (TREE_CODE (leader) == SSA_NAME) - gimple_set_plf (SSA_NAME_DEF_STMT (leader), NECESSARY, true); + return NULL_TREE; + } + else + { + gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); + VN_INFO_GET (res)->valnum = val; + + if (TREE_CODE (leader) == SSA_NAME) + gimple_set_plf (SSA_NAME_DEF_STMT (leader), NECESSARY, true); + } pre_stats.insertions++; if (dump_file && (dump_flags & TDF_DETAILS)) -- 2.30.2