[PATCH] tree-optimization/98674 - improve dependence analysis

Richard Biener rguenther@suse.de
Thu Jan 14 13:38:32 GMT 2021


This improves dependence analysis on refs that access the same
array but with different typed but same sized accesses.  That's
obviously safe for the case of types that cannot have any
access function based off them.  For the testcase this is
signed short vs. unsigned short.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

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

	PR tree-optimization/98674
	* tree-data-ref.c (base_supports_access_fn_components_p): New.
	(initialize_data_dependence_relation): For two bases without
	possible access fns resort to type size equality when determining
	shape compatibility.

	* gcc.dg/vect/pr98674.c: New testcase.
---
 gcc/testsuite/gcc.dg/vect/pr98674.c | 16 ++++++++++++++++
 gcc/tree-data-ref.c                 | 26 ++++++++++++++++++++++++--
 2 files changed, 40 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/pr98674.c

diff --git a/gcc/testsuite/gcc.dg/vect/pr98674.c b/gcc/testsuite/gcc.dg/vect/pr98674.c
new file mode 100644
index 00000000000..0f1b6cb060b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr98674.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-msse2" { target sse2 } } */
+
+void swap(short *p, int cnt)
+{
+  while (cnt-- > 0)
+    {
+      *p = ((*p << 8) & 0xFF00) | ((*p >> 8) & 0x00FF);
+      ++p;
+    }
+}
+
+/* Dependence analysis should not fail.  */
+/* { dg-final { scan-tree-dump "dependence distance == 0" "vect" } } */
+/* On x86 with SSE2 we can vectorize this with psllw/psrlw.  */
+/* { dg-final { scan-tree-dump "loop vectorized" "vect" { target sse2 } } } */
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 394470af757..65fe6d5da91 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -1291,6 +1291,23 @@ access_fn_component_p (tree op)
     }
 }
 
+/* Returns whether BASE can have a access_fn_component_p with BASE
+   as base.  */
+
+static bool
+base_supports_access_fn_components_p (tree base)
+{
+  switch (TREE_CODE (TREE_TYPE (base)))
+    {
+    case COMPLEX_TYPE:
+    case ARRAY_TYPE:
+    case RECORD_TYPE:
+      return true;
+    default:
+      return false;
+    }
+}
+
 /* Determines the base object and the list of indices of memory reference
    DR, analyzed in LOOP and instantiated before NEST.  */
 
@@ -3272,8 +3289,13 @@ initialize_data_dependence_relation (struct data_reference *a,
 		      && full_seq.start_b + full_seq.length == num_dimensions_b
 		      && DR_UNCONSTRAINED_BASE (a) == DR_UNCONSTRAINED_BASE (b)
 		      && operand_equal_p (base_a, base_b, OEP_ADDRESS_OF)
-		      && types_compatible_p (TREE_TYPE (base_a),
-					     TREE_TYPE (base_b))
+		      && (types_compatible_p (TREE_TYPE (base_a),
+					      TREE_TYPE (base_b))
+			  || (!base_supports_access_fn_components_p (base_a)
+			      && !base_supports_access_fn_components_p (base_b)
+			      && operand_equal_p
+				   (TYPE_SIZE (TREE_TYPE (base_a)),
+				    TYPE_SIZE (TREE_TYPE (base_b)), 0)))
 		      && (!loop_nest.exists ()
 			  || (object_address_invariant_in_loop_p
 			      (loop_nest[0], base_a))));
-- 
2.26.2


More information about the Gcc-patches mailing list