tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Fix type-based offset disambiguation...
authorRichard Guenther <rguenther@suse.de>
Wed, 25 May 2011 15:20:36 +0000 (15:20 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 25 May 2011 15:20:36 +0000 (15:20 +0000)
2011-05-25  Richard Guenther  <rguenther@suse.de>

* tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Fix
type-based offset disambiguation, streamline MEM_REF and
TARGET_MEM_REF handling.

From-SVN: r174206

gcc/ChangeLog
gcc/tree-ssa-alias.c

index aee6a1349fd7fee7e8759f442f024c6c3a6920ee..a22c5d5357528af0aee8768c4538a14676495e78 100644 (file)
@@ -1,3 +1,9 @@
+2011-05-25  Richard Guenther  <rguenther@suse.de>
+
+       * tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Fix
+       type-based offset disambiguation, streamline MEM_REF and
+       TARGET_MEM_REF handling.
+
 2011-05-25  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/i386/i386.c (ix86_builtins): Add IX86_BUILTIN_PAUSE.
index ba76ae10ab1214448bdb29537fa3d9ba5be1da5f..3656b396d86afad107d7a34a9565239653f27aa0 100644 (file)
@@ -718,8 +718,9 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
                               alias_set_type base2_alias_set, bool tbaa_p)
 {
   tree ptr1;
-  tree ptrtype1;
+  tree ptrtype1, dbase2;
   HOST_WIDE_INT offset1p = offset1, offset2p = offset2;
+  HOST_WIDE_INT doffset1, doffset2;
   double_int moff;
 
   gcc_checking_assert ((TREE_CODE (base1) == MEM_REF
@@ -766,20 +767,6 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
   if (base2_alias_set == -1)
     base2_alias_set = get_alias_set (base2);
 
-  /* If both references are through the same type, they do not alias
-     if the accesses do not overlap.  This does extra disambiguation
-     for mixed/pointer accesses but requires strict aliasing.
-     For MEM_REFs we require that the component-ref offset we computed
-     is relative to the start of the type which we ensure by
-     comparing rvalue and access type and disregarding the constant
-     pointer offset.  */
-  if ((TREE_CODE (base1) != TARGET_MEM_REF
-       || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
-      && (TREE_CODE (base1) != MEM_REF
-         || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1)
-      && same_type_for_tbaa (TREE_TYPE (ptrtype1), TREE_TYPE (base2)) == 1)
-    return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
-
   /* When we are trying to disambiguate an access with a pointer dereference
      as base versus one with a decl as base we can use both the size
      of the decl and its dynamic type for extra disambiguation.
@@ -809,13 +796,51 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
       && tree_int_cst_lt (DECL_SIZE (base2), TYPE_SIZE (TREE_TYPE (ptrtype1))))
     return false;
 
+  if (!ref2)
+    return true;
+
+  /* If the decl is accressed via a MEM_REF, reconstruct the base
+     we can use for TBAA and an appropriately adjusted offset.  */
+  dbase2 = ref2;
+  while (handled_component_p (dbase2))
+    dbase2 = TREE_OPERAND (dbase2, 0);
+  doffset1 = offset1;
+  doffset2 = offset2;
+  if (TREE_CODE (dbase2) == MEM_REF
+      || TREE_CODE (dbase2) == TARGET_MEM_REF)
+    {
+      double_int moff = mem_ref_offset (dbase2);
+      moff = double_int_lshift (moff,
+                               BITS_PER_UNIT == 8
+                               ? 3 : exact_log2 (BITS_PER_UNIT),
+                               HOST_BITS_PER_DOUBLE_INT, true);
+      if (double_int_negative_p (moff))
+       doffset1 -= double_int_neg (moff).low;
+      else
+       doffset2 -= moff.low;
+    }
+
+  /* If either reference is view-converted, give up now.  */
+  if (same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) != 1
+      || same_type_for_tbaa (TREE_TYPE (dbase2),
+                            TREE_TYPE (reference_alias_ptr_type (dbase2))) != 1)
+    return true;
+
+  /* If both references are through the same type, they do not alias
+     if the accesses do not overlap.  This does extra disambiguation
+     for mixed/pointer accesses but requires strict aliasing.
+     For MEM_REFs we require that the component-ref offset we computed
+     is relative to the start of the type which we ensure by
+     comparing rvalue and access type and disregarding the constant
+     pointer offset.  */
+  if ((TREE_CODE (base1) != TARGET_MEM_REF
+       || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
+      && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (dbase2)) == 1)
+    return ranges_overlap_p (doffset1, max_size1, doffset2, max_size2);
+
   /* Do access-path based disambiguation.  */
   if (ref1 && ref2
-      && handled_component_p (ref1)
-      && handled_component_p (ref2)
-      && TREE_CODE (base1) != TARGET_MEM_REF
-      && (TREE_CODE (base1) != MEM_REF
-         || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1))
+      && (handled_component_p (ref1) || handled_component_p (ref2)))
     return aliasing_component_refs_p (ref1,
                                      ref1_alias_set, base1_alias_set,
                                      offset1, max_size1,