re PR tree-optimization/79777 (ICE on -Os and above in on aarch64-linux-gnu (internal...
authorRichard Biener <rguenther@suse.de>
Thu, 2 Mar 2017 07:53:42 +0000 (07:53 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 2 Mar 2017 07:53:42 +0000 (07:53 +0000)
2017-03-02  Richard Biener  <rguenther@suse.de>

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
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr79777.c [new file with mode: 0644]
gcc/tree-ssa-pre.c

index 4f44086608112d384396eff95eac1691c0461f58..530acbb9ba31d66ad2eb1797a1b98699bb4bdea5 100644 (file)
@@ -1,3 +1,9 @@
+2017-03-02  Richard Biener  <rguenther@suse.de>
+
+       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  <msebor@redhat.com>
 
        PR middle-end/79692
index 59264c2d4ef8762bc1303e3df1d704676f695f91..8d926096459667447e58b973cfa6b8c09e83c102 100644 (file)
@@ -1,3 +1,8 @@
+2017-03-02  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/79777
+       * gcc.dg/torture/pr79777.c: New testcase.
+
 2017-03-01  Martin Sebor  <msebor@redhat.com>
 
        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 (file)
index 0000000..eb1bec7
--- /dev/null
@@ -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))));
+}
index bdf48ad7d8a1f8c0d92f3330a06689a739bbdc34..ff59d53667885bea3abc0bcc4cd9f44417b86e4c 100644 (file)
@@ -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))