diff mbox

Fix PR64365

Message ID alpine.LSU.2.11.1501141426130.12482@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Jan. 14, 2015, 1:29 p.m. UTC
This fixes an issue in dependence analysis and how we make pointer
dereferences visible to it.  Basically dependence analysis works
on indices (assuming we deal with arrays) and thus never needs
sth like an access size (because indices are non-sparse and
different index means a different memory area).  Dereferences
breaks this because we present dependence analysis with a
sparse index space.  Thus to rule out partially overlapping
accesses we have to make sure to separate bases (only equal
bases get treated this way).

The following ensures this by making the indices multiples of
the access size (and shifting the byte offset modulo the access
size to the base object).

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2015-01-14  Richard Biener  <rguenther@suse.de>

	PR middle-end/64365
	* tree-data-ref.c (dr_analyze_indices): Make sure that accesses
	for MEM_REF access functions with the same base can never partially
	overlap.

	* gcc.dg/torture/pr64365.c: New testcase.
diff mbox

Patch

Index: gcc/tree-data-ref.c
===================================================================
--- gcc/tree-data-ref.c	(revision 219592)
+++ gcc/tree-data-ref.c	(working copy)
@@ -970,7 +972,8 @@  dr_analyze_indices (struct data_referenc
 
   /* 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 (ref) == MEM_REF)
+  if (TREE_CODE (ref) == MEM_REF
+      && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (ref))) == INTEGER_CST)
     {
       op = TREE_OPERAND (ref, 0);
       access_fn = analyze_scalar_evolution (loop, op);
@@ -992,6 +995,15 @@  dr_analyze_indices (struct data_referenc
 				fold_convert (ssizetype, memoff));
 	      memoff = build_int_cst (TREE_TYPE (memoff), 0);
 	    }
+	  /* Adjust the offset so it is a multiple of the access type
+	     size and thus we separate bases that can possibly be used
+	     to produce partial overlaps (which the access_fn machinery
+	     cannot handle).  */
+	  wide_int rem
+	    = wi::mod_trunc (off, TYPE_SIZE_UNIT (TREE_TYPE (ref)), SIGNED);
+	  off = wide_int_to_tree (ssizetype, wi::sub (off, rem));
+	  memoff = wide_int_to_tree (TREE_TYPE (memoff), rem);
+	  /* And finally replace the initial condition.  */
 	  access_fn = chrec_replace_initial_condition
 	      (access_fn, fold_convert (orig_type, off));
 	  /* ???  This is still not a suitable base object for
Index: gcc/testsuite/gcc.dg/torture/pr64365.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr64365.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr64365.c	(working copy)
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+extern void abort (void);
+extern int memcmp (const void * , const void *, __SIZE_TYPE__);
+
+void __attribute__((noinline,noclone))
+foo(int *in)
+{
+  int i;
+  for (i = 62; i >= 10; i--)
+    {
+      in[i - 8] -= in[i];
+      in[i - 5] += in[i] * 2;
+      in[i - 4] += in[i];
+    }
+}
+
+int main()
+{
+  int x[64];
+  int y[64] = { 0, 1, -2380134, -1065336, -1026376, 3264240, 3113534, 2328130, 3632054, 3839634, 2380136, 1065339, 1026380, 1496037, 1397286, 789976, 386408, 450984, 597112, 497464, 262008, 149184, 194768, 231519, 173984, 87753, 60712, 82042, 87502, 60014, 30050, 25550, 33570, 32386, 20464, 10675, 10868, 13329, 11794, 6892, 3988, 4564, 5148, 4228, 2284, 1568, 1848, 1943, 1472, 741, 628, 702, 714, 474, 230, 234, 238, 242, 120, 59, 60, 61, 62, 63 };
+  int i;
+
+  for (i = 0; i < 64; ++i)
+    {
+      x[i] = i;
+      __asm__ volatile ("");
+    }
+
+  foo (x);
+
+  if (memcmp (x, y, sizeof (x)) != 0)
+    abort ();
+
+  return 0;
+}