re PR tree-optimization/48702 (optimization regression with gcc-4.6 on x86_64-unknown...
authorRichard Guenther <rguenther@suse.de>
Thu, 26 May 2011 13:01:48 +0000 (13:01 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 26 May 2011 13:01:48 +0000 (13:01 +0000)
2011-05-26  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/48702
* tree-ssa-address.c (create_mem_ref_raw): Create MEM_REFs
only when we know the base address is within bounds.
* tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Do not
assume the base address of TARGET_MEM_REFs is in bounds.

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

From-SVN: r174282

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr48702.c [new file with mode: 0644]
gcc/tree-ssa-address.c
gcc/tree-ssa-alias.c

index f4047ef597ba985fca1bf0ea6dc8cb124a67e4c7..ed1dda3f56de4064a10af4ce6f055310f410ac69 100644 (file)
@@ -1,3 +1,11 @@
+2011-05-26  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/48702
+       * tree-ssa-address.c (create_mem_ref_raw): Create MEM_REFs
+       only when we know the base address is within bounds.
+       * tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Do not
+       assume the base address of TARGET_MEM_REFs is in bounds.
+
 2011-05-26  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        PR target/49099
index 5acf08e8c5c6bac273c21bef9ded3604537fbcf7..089406dec33889d7d28d6e6515c6231b9df93dca 100644 (file)
@@ -1,3 +1,8 @@
+2011-05-26  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/48702
+       * gcc.dg/torture/pr48702.c: New testcase.
+
 2011-05-26  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        PR gcov-profile/48845
diff --git a/gcc/testsuite/gcc.dg/torture/pr48702.c b/gcc/testsuite/gcc.dg/torture/pr48702.c
new file mode 100644 (file)
index 0000000..1ec371d
--- /dev/null
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+#define LEN 4
+
+static inline void unpack(int  array[LEN])
+{
+  int ii, val;
+  val = 1;
+  for (ii = 0; ii < LEN; ii++) {
+      array[ii] = val % 2;
+      val = val / 2;
+  }
+}
+
+static inline int  pack(int  array[LEN])
+{
+  int ans, ii;
+  ans = 0;
+  for (ii = LEN-1; ii >= 0; ii--) {
+      ans = 2 * ans + array[ii];
+  }
+  return ans;
+}
+
+int __attribute__((noinline))
+foo()
+{
+  int temp, ans;
+  int array[LEN];
+  unpack(array);
+  temp = array[0];
+  array[0] = array[2];
+  array[2] = temp;
+  ans = pack(array);
+  return ans;
+}
+
+int main(void)
+{
+  int val;
+  val = foo();
+  if (val != 4)
+    abort ();
+  return 0;
+}
index 07d1d4db43b6295b6ca0deed4fe272df3760b9ba..2e6eabc8ccbfa27a8fdf7b21b9224612de6d2668 100644 (file)
@@ -361,8 +361,11 @@ create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr,
       index2 = addr->base;
     }
 
-  /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF.  */
-  if (alias_ptr_type
+  /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF.
+     ???  As IVOPTs does not follow restrictions to where the base
+     pointer may point to create a MEM_REF only if we know that
+     base is valid.  */
+  if (TREE_CODE (base) == ADDR_EXPR
       && (!index2 || integer_zerop (index2))
       && (!addr->index || integer_zerop (addr->index)))
     return fold_build2 (MEM_REF, type, base, addr->offset);
index 3656b396d86afad107d7a34a9565239653f27aa0..02b3ca07e07b548e4c2e686b1fe4b71efb15d8ff 100644 (file)
@@ -745,11 +745,12 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
      the pointer access is beyond the extent of the variable access.
      (the pointer base cannot validly point to an offset less than zero
      of the variable).
-     They also cannot alias if the pointer may not point to the decl.  */
-  if ((TREE_CODE (base1) != TARGET_MEM_REF
-       || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
+     ???  IVOPTs creates bases that do not honor this restriction,
+     so do not apply this optimization for TARGET_MEM_REFs.  */
+  if (TREE_CODE (base1) != TARGET_MEM_REF
       && !ranges_overlap_p (MAX (0, offset1p), -1, offset2p, max_size2))
     return false;
+  /* They also cannot alias if the pointer may not point to the decl.  */
   if (!ptr_deref_may_alias_decl_p (ptr1, base2))
     return false;
 
@@ -799,7 +800,7 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
   if (!ref2)
     return true;
 
-  /* If the decl is accressed via a MEM_REF, reconstruct the base
+  /* If the decl is accessed via a MEM_REF, reconstruct the base
      we can use for TBAA and an appropriately adjusted offset.  */
   dbase2 = ref2;
   while (handled_component_p (dbase2))