re PR tree-optimization/44831 (internal compiler error: verify_stmts failed when...
authorRichard Guenther <rguenther@suse.de>
Thu, 8 Jul 2010 11:38:43 +0000 (11:38 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 8 Jul 2010 11:38:43 +0000 (11:38 +0000)
2010-07-08  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/44831
* tree-ssa-phiprop.c (phiprop_insert_phi): Properly build
a MEM_REF preserving TBAA info of the original dereference.
Dereference the original pointer if the address is not
invariant.
(propagate_with_phi): Fixup type checks wrt MEM_REFs.  Require
at least one invariant address that we are going to dereference.

* gcc.c-torture/compile/pr44831.c: New testcase.
* gcc.dg/tree-ssa/pr21463.c: Adjust.

From-SVN: r161950

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr44831.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr21463.c
gcc/tree-ssa-phiprop.c

index 0d84f29d58795699c19c3a0c1a1a33cc2eba3298..db4f910397b9996f36cc2404a1317ede79787c1f 100644 (file)
@@ -1,3 +1,13 @@
+2010-07-08  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/44831
+       * tree-ssa-phiprop.c (phiprop_insert_phi): Properly build
+       a MEM_REF preserving TBAA info of the original dereference.
+       Dereference the original pointer if the address is not
+       invariant.
+       (propagate_with_phi): Fixup type checks wrt MEM_REFs.  Require
+       at least one invariant address that we are going to dereference.
+
 2010-07-08  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/44861
index d332dc4a9605fb40146f7019272877f15b1b03c5..eb8d5f1bc213dee7ad9011703dd910b17dc9c44d 100644 (file)
@@ -1,3 +1,9 @@
+2010-07-08  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/44831
+       * gcc.c-torture/compile/pr44831.c: New testcase.
+       * gcc.dg/tree-ssa/pr21463.c: Adjust.
+
 2010-07-08  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/44861
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr44831.c b/gcc/testsuite/gcc.c-torture/compile/pr44831.c
new file mode 100644 (file)
index 0000000..5539583
--- /dev/null
@@ -0,0 +1,15 @@
+typedef unsigned char UCHAR, *PUCHAR;
+typedef void *HANDLE;
+typedef struct _NCB {
+    UCHAR ncb_reserve[10];
+} NCB, *PNCB;
+struct NBCmdQueue {
+    PNCB head;
+};
+PNCB *NBCmdQueueFindNBC(struct NBCmdQueue *queue, PNCB ncb)
+{
+  PNCB *ret = &queue->head;
+  while (ret && *ret != ncb)
+    ret = (PNCB *)((*ret)->ncb_reserve + sizeof(HANDLE));
+}
+
index f490bf61e5aef8f746cf6293fea0e63a8acea92a..3f63cdd8e8c027120f229db8176234da40314a89 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-phiprop" } */
+/* { dg-options "-O -fdump-tree-phiprop-details" } */
 
 struct f
 {
@@ -16,5 +16,5 @@ int g(int i, int c, struct f *ff, int g)
   return *t;
 }
 
-/* { dg-final { scan-tree-dump-not "\\*t" "phiprop" } } */
+/* { dg-final { scan-tree-dump-times "Inserting PHI for result of load" 1 "phiprop" } } */
 /* { dg-final { cleanup-tree-dump "phiprop" } } */
index 6595515e1ada03196b37c21ff50a1707f86a9dd2..84f22b956edb04baa13ebec25e4d63c378f11480 100644 (file)
@@ -187,10 +187,17 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt,
        }
       else
        {
+         tree rhs = gimple_assign_rhs1 (use_stmt);
          gcc_assert (TREE_CODE (old_arg) == ADDR_EXPR);
-         old_arg = TREE_OPERAND (old_arg, 0);
-         new_var = create_tmp_reg (TREE_TYPE (old_arg), NULL);
-         tmp = gimple_build_assign (new_var, unshare_expr (old_arg));
+         new_var = create_tmp_reg (TREE_TYPE (rhs), NULL);
+         if (!is_gimple_min_invariant (old_arg))
+           old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
+         else
+           old_arg = unshare_expr (old_arg);
+         tmp = gimple_build_assign (new_var,
+                                    fold_build2 (MEM_REF, TREE_TYPE (rhs),
+                                                 old_arg,
+                                                 TREE_OPERAND (rhs, 1)));
          gcc_assert (is_gimple_reg (new_var));
          add_referenced_var (new_var);
          new_var = make_ssa_name (new_var, tmp);
@@ -246,6 +253,8 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
   use_operand_p arg_p, use;
   ssa_op_iter i;
   bool phi_inserted;
+  tree type = NULL_TREE;
+  bool one_invariant = false;
 
   if (!POINTER_TYPE_P (TREE_TYPE (ptr))
       || !is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr))))
@@ -268,16 +277,29 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
            return false;
          arg = gimple_assign_rhs1 (def_stmt);
        }
-      if ((TREE_CODE (arg) != ADDR_EXPR
-          /* Avoid to have to decay *&a to a[0] later.  */
-          || !is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (arg, 0))))
+      if (TREE_CODE (arg) != ADDR_EXPR
          && !(TREE_CODE (arg) == SSA_NAME
               && SSA_NAME_VERSION (arg) < n
               && phivn[SSA_NAME_VERSION (arg)].value != NULL_TREE
+              && (!type
+                  || types_compatible_p
+                      (type, TREE_TYPE (phivn[SSA_NAME_VERSION (arg)].value)))
               && phivn_valid_p (phivn, arg, bb)))
        return false;
+      if (!type
+         && TREE_CODE (arg) == SSA_NAME)
+       type = TREE_TYPE (phivn[SSA_NAME_VERSION (arg)].value);
+      if (TREE_CODE (arg) == ADDR_EXPR
+         && is_gimple_min_invariant (arg))
+       one_invariant = true;
     }
 
+  /* If we neither have an address of a decl nor can reuse a previously
+     inserted load, do not hoist anything.  */
+  if (!one_invariant
+      && !type)
+    return false;
+
   /* Find a dereferencing use.  First follow (single use) ssa
      copy chains for ptr.  */
   while (single_imm_use (ptr, &use, &use_stmt)
@@ -298,8 +320,9 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
            && gimple_assign_rhs_code (use_stmt) == MEM_REF
            && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == ptr
            && integer_zerop (TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 1))
-           && types_compatible_p (TREE_TYPE (gimple_assign_rhs1 (use_stmt)),
-                                  TREE_TYPE (TREE_TYPE (ptr)))
+           && (!type
+               || types_compatible_p
+                    (TREE_TYPE (gimple_assign_lhs (use_stmt)), type))
            /* We cannot replace a load that may throw or is volatile.  */
            && !stmt_can_throw_internal (use_stmt)))
        continue;
@@ -319,6 +342,7 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
       if (!phi_inserted)
        {
          res = phiprop_insert_phi (bb, phi, use_stmt, phivn, n);
+         type = TREE_TYPE (res);
 
          /* Remember the value we created for *ptr.  */
          phivn[SSA_NAME_VERSION (ptr)].value = res;