OSDN Git Service

2011-10-24 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 24 Oct 2011 12:31:01 +0000 (12:31 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 24 Oct 2011 12:31:01 +0000 (12:31 +0000)
PR tree-optimization/50838
* tree-data-ref.c (dr_analyze_indices): Properly canonicalize
a MEM_REF base if we change it.

* gcc.dg/torture/pr50838.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180381 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr50838.c [new file with mode: 0644]
gcc/tree-data-ref.c

index d91e39f..69450bb 100644 (file)
@@ -1,3 +1,9 @@
+2011-10-24  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/50838
+       * tree-data-ref.c (dr_analyze_indices): Properly canonicalize
+       a MEM_REF base if we change it.
+
 2011-10-24  Bernd Schmidt  <bernds@codesourcery.com>
 
        PR bootstrap/50836
index af10398..bd252aa 100644 (file)
@@ -1,3 +1,8 @@
+2011-10-24  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/50838
+       * gcc.dg/torture/pr50838.c: New testcase.
+
 2011-10-24  Ira Rosen  <ira.rosen@linaro.org>
 
        PR tree-optimization/50730
diff --git a/gcc/testsuite/gcc.dg/torture/pr50838.c b/gcc/testsuite/gcc.dg/torture/pr50838.c
new file mode 100644 (file)
index 0000000..a3911c9
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+
+typedef void * gcv_object_t;
+typedef gcv_object_t object;
+typedef const void * Pseudofun;
+extern struct pseudocode_tab_ {
+    Pseudofun pseudo_eql;
+    Pseudofun pseudo_iconv_wcslen;
+    Pseudofun pseudo_iconv_wcstombs;
+    Pseudofun pseudo_iconv_range;
+}
+pseudocode_tab;
+extern struct symbol_tab_ {
+    object pointer[1024];
+} pseudofun_tab;
+int
+init_memory (void)
+{
+  object* ptr2 = &pseudofun_tab.pointer[0];
+  const Pseudofun* ptr1 = (const Pseudofun*)&pseudocode_tab;
+  unsigned int count = (sizeof(pseudocode_tab)/sizeof(Pseudofun));
+  while (count--)
+    {
+      *ptr2++ = (gcv_object_t)(((unsigned char *)((*ptr1))));
+      ptr1++;
+    }
+}
index 053ffea..4e0de05 100644 (file)
@@ -855,7 +855,7 @@ static void
 dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
 {
   VEC (tree, heap) *access_fns = NULL;
-  tree ref, aref, op;
+  tree ref, *aref, op;
   tree base, off, access_fn;
   basic_block before_loop;
 
@@ -886,50 +886,58 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
     }
 
   /* Analyze access functions of dimensions we know to be independent.  */
-  aref = ref;
-  while (handled_component_p (aref))
+  aref = &ref;
+  while (handled_component_p (*aref))
     {
-      if (TREE_CODE (aref) == ARRAY_REF)
+      if (TREE_CODE (*aref) == ARRAY_REF)
        {
-         op = TREE_OPERAND (aref, 1);
+         op = TREE_OPERAND (*aref, 1);
          access_fn = analyze_scalar_evolution (loop, op);
          access_fn = instantiate_scev (before_loop, loop, access_fn);
          VEC_safe_push (tree, heap, access_fns, access_fn);
          /* For ARRAY_REFs the base is the reference with the index replaced
             by zero if we can not strip it as the outermost component.  */
-         if (aref == ref)
-           ref = TREE_OPERAND (ref, 0);
+         if (*aref == ref)
+           {
+             *aref = TREE_OPERAND (*aref, 0);
+             continue;
+           }
          else
-           TREE_OPERAND (aref, 1) = build_int_cst (TREE_TYPE (op), 0);
+           TREE_OPERAND (*aref, 1) = build_int_cst (TREE_TYPE (op), 0);
        }
 
-      aref = TREE_OPERAND (aref, 0);
+      aref = &TREE_OPERAND (*aref, 0);
     }
 
   /* If the address operand of a MEM_REF base has an evolution in the
      analyzed nest, add it as an additional independent access-function.  */
-  if (TREE_CODE (aref) == MEM_REF)
+  if (TREE_CODE (*aref) == MEM_REF)
     {
-      op = TREE_OPERAND (aref, 0);
+      op = TREE_OPERAND (*aref, 0);
       access_fn = analyze_scalar_evolution (loop, op);
       access_fn = instantiate_scev (before_loop, loop, access_fn);
       if (TREE_CODE (access_fn) == POLYNOMIAL_CHREC)
        {
+         tree orig_type;
          base = initial_condition (access_fn);
+         orig_type = TREE_TYPE (base);
+         STRIP_USELESS_TYPE_CONVERSION (base);
          split_constant_offset (base, &base, &off);
          /* Fold the MEM_REF offset into the evolutions initial
             value to make more bases comparable.  */
-         if (!integer_zerop (TREE_OPERAND (aref, 1)))
+         if (!integer_zerop (TREE_OPERAND (*aref, 1)))
            {
              off = size_binop (PLUS_EXPR, off,
                                fold_convert (ssizetype,
-                                             TREE_OPERAND (aref, 1)));
-             TREE_OPERAND (aref, 1)
-               = build_int_cst (TREE_TYPE (TREE_OPERAND (aref, 1)), 0);
+                                             TREE_OPERAND (*aref, 1)));
+             TREE_OPERAND (*aref, 1)
+               = build_int_cst (TREE_TYPE (TREE_OPERAND (*aref, 1)), 0);
            }
          access_fn = chrec_replace_initial_condition
-             (access_fn, fold_convert (TREE_TYPE (base), off));
-         TREE_OPERAND (aref, 0) = base;
+             (access_fn, fold_convert (orig_type, off));
+         *aref = fold_build2_loc (EXPR_LOCATION (*aref),
+                                  MEM_REF, TREE_TYPE (*aref),
+                                  base, TREE_OPERAND (*aref, 1));
          VEC_safe_push (tree, heap, access_fns, access_fn);
        }
     }