]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/53168 (ICE in find_or_generate_expression, at tree-ssa-pre...
authorRichard Guenther <rguenther@suse.de>
Fri, 4 May 2012 11:30:35 +0000 (11:30 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 4 May 2012 11:30:35 +0000 (11:30 +0000)
2012-05-04  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/53168
* tree-ssa-pre.c (phi_translate_1): Only handle type-punned
memory reads when the result is a constant we can pun.

* gcc.dg/torture/pr53168.c: New testcase.
* gcc.dg/tree-ssa/ssa-pre-30.c: Likewise.

From-SVN: r187153

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr53168.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c [new file with mode: 0644]
gcc/tree-ssa-pre.c

index 63ec602a300a356248eb0adee41d1694b4572d82..72e3264c345900cd35bc4d2b8e9ec9579ce0e7d6 100644 (file)
@@ -1,3 +1,9 @@
+2012-05-04  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/53168
+       * tree-ssa-pre.c (phi_translate_1): Only handle type-punned
+       memory reads when the result is a constant we can pun.
+
 2012-05-04  Richard Guenther  <rguenther@suse.de>
 
        * common.opt (flto-report): Do not mark as Optimization.
index 581b8b87287c48b1b7e16845e98b956496b118f8..e26d07258bb9be3495926baf45329078694e3388 100644 (file)
@@ -1,3 +1,9 @@
+2012-05-04  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/53168
+       * gcc.dg/torture/pr53168.c: New testcase.
+       * gcc.dg/tree-ssa/ssa-pre-30.c: Likewise.
+
 2012-05-04  Richard Guenther  <rguenther@suse.de>
 
        * gcc.dg/lto/pr53214_0.c: New testcase.
diff --git a/gcc/testsuite/gcc.dg/torture/pr53168.c b/gcc/testsuite/gcc.dg/torture/pr53168.c
new file mode 100644 (file)
index 0000000..0b9a8dc
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+
+int a, b, c;
+unsigned *d;
+int e[1];
+void fn1 ();
+int fn2 ();
+int
+fn3 ()
+{
+  int *f = &a;
+  if (fn2 ())
+    {
+      for (; c; c++)
+       {
+         e[a] && (b = 0);
+         fn1 ();
+         if (e[a])
+           return 0;
+       }
+      for (; c <= 0; c++)
+       for (;;)
+         ;
+    }
+  else
+    e[0] = 0 != (d = f);
+  return *d;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c
new file mode 100644 (file)
index 0000000..68a7a7f
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-pre-details" } */
+
+int f;
+int g;
+unsigned int
+foo (int b, int x)
+{
+  if (b)
+    x = *(int *)&f;
+  g = x;
+  return *(unsigned int*)&f;
+}
+float
+bar (int b, int x)
+{
+  if (b)
+    x = *(int *)&f;
+  g = x;
+  return *(float *)&f;
+}
+
+/* We should see the partial redundant loads of f even though they
+   are using different types (of the same size).  */
+
+/* { dg-final { scan-tree-dump-times "Replaced MEM" 2 "pre" } } */
+/* { dg-final { cleanup-tree-dump "pre" } } */
index 776a37cdcc6ea00dc969485a5713cda50e1adcd7..fcd7feeea1e6096c03a45700d9ee83aa35a66d5a 100644 (file)
@@ -1659,7 +1659,6 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
          {
            unsigned int new_val_id;
            pre_expr constant;
-           bool converted = false;
 
            tree result = vn_reference_lookup_pieces (newvuse, ref->set,
                                                      ref->type,
@@ -1668,12 +1667,29 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
            if (result)
              VEC_free (vn_reference_op_s, heap, newoperands);
 
-           if (result
-               && !useless_type_conversion_p (ref->type, TREE_TYPE (result)))
+           /* We can always insert constants, so if we have a partial
+              redundant constant load of another type try to translate it
+              to a constant of appropriate type.  */
+           if (result && is_gimple_min_invariant (result))
              {
-               result = fold_build1 (VIEW_CONVERT_EXPR, ref->type, result);
-               converted = true;
+               tree tem = result;
+               if (!useless_type_conversion_p (ref->type, TREE_TYPE (result)))
+                 {
+                   tem = fold_unary (VIEW_CONVERT_EXPR, ref->type, result);
+                   if (tem && !is_gimple_min_invariant (tem))
+                     tem = NULL_TREE;
+                 }
+               if (tem)
+                 return get_or_alloc_expr_for_constant (tem);
              }
+
+           /* If we'd have to convert things we would need to validate
+              if we can insert the translated expression.  So fail
+              here for now - we cannot insert an alias with a different
+              type in the VN tables either, as that would assert.  */
+           if (result
+               && !useless_type_conversion_p (ref->type, TREE_TYPE (result)))
+             return NULL;
            else if (!result && newref
                     && !useless_type_conversion_p (ref->type, newref->type))
              {
@@ -1681,61 +1697,11 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
                return NULL;
              }
 
-           if (result && is_gimple_min_invariant (result))
-             {
-               gcc_assert (!newoperands);
-               return get_or_alloc_expr_for_constant (result);
-             }
-
            expr = (pre_expr) pool_alloc (pre_expr_pool);
            expr->kind = REFERENCE;
            expr->id = 0;
 
-           if (converted)
-             {
-               vn_nary_op_t nary;
-               tree nresult;
-
-               gcc_assert (CONVERT_EXPR_P (result)
-                           || TREE_CODE (result) == VIEW_CONVERT_EXPR);
-
-               nresult = vn_nary_op_lookup_pieces (1, TREE_CODE (result),
-                                                   TREE_TYPE (result),
-                                                   &TREE_OPERAND (result, 0),
-                                                   &nary);
-               if (nresult && is_gimple_min_invariant (nresult))
-                 return get_or_alloc_expr_for_constant (nresult);
-
-               expr->kind = NARY;
-               if (nary)
-                 {
-                   PRE_EXPR_NARY (expr) = nary;
-                   constant = fully_constant_expression (expr);
-                   if (constant != expr)
-                     return constant;
-
-                   new_val_id = nary->value_id;
-                   get_or_alloc_expression_id (expr);
-                 }
-               else
-                 {
-                   new_val_id = get_next_value_id ();
-                   VEC_safe_grow_cleared (bitmap_set_t, heap,
-                                          value_expressions,
-                                          get_max_value_id() + 1);
-                   nary = vn_nary_op_insert_pieces (1, TREE_CODE (result),
-                                                    TREE_TYPE (result),
-                                                    &TREE_OPERAND (result, 0),
-                                                    NULL_TREE,
-                                                    new_val_id);
-                   PRE_EXPR_NARY (expr) = nary;
-                   constant = fully_constant_expression (expr);
-                   if (constant != expr)
-                     return constant;
-                   get_or_alloc_expression_id (expr);
-                 }
-             }
-           else if (newref)
+           if (newref)
              {
                PRE_EXPR_REFERENCE (expr) = newref;
                constant = fully_constant_expression (expr);