tree-optimization/126159 - handle unions in data dependence analysis

Message ID 2263o93p-88p6-6285-69p4-o7s0orn859rq@fhfr.qr
State Committed
Commit c31cb13628593fc57779419a806170b6ef2c3b81
Headers
Series tree-optimization/126159 - handle unions in data dependence analysis |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Richard Biener July 8, 2026, 9:39 a.m. UTC
  The following implements minimal handling of union accesses in
data reference analysis, namely accesses to non-aggregate fields,
in particular those we are not adding additional subsetting on.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

	PR tree-optimization/126159
	* tree-data-ref.cc (dr_analyze_indices): Handle non-aggregate
	union field accesses.
	(access_fn_component_p): Adjust.

	* gcc.dg/vect/vect-pr126159-1.c: New testcase.
	* gcc.dg/vect/vect-pr126159-2.c: Likewise.
---
 gcc/testsuite/gcc.dg/vect/vect-pr126159-1.c | 16 +++++++++++
 gcc/testsuite/gcc.dg/vect/vect-pr126159-2.c | 16 +++++++++++
 gcc/tree-data-ref.cc                        | 30 ++++++++++++++-------
 3 files changed, 53 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-pr126159-1.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-pr126159-2.c
  

Patch

diff --git a/gcc/testsuite/gcc.dg/vect/vect-pr126159-1.c b/gcc/testsuite/gcc.dg/vect/vect-pr126159-1.c
new file mode 100644
index 00000000000..d364d28d7d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-pr126159-1.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+
+typedef union { int i; float f; } RtreeCoord;
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
+void cellUnion_f(RtreeCoord *a1, RtreeCoord *a2, int n) {
+  int ii = 0;
+  do {
+    a1[ii].f   = MIN(a1[ii].f,   a2[ii].f);
+    a1[ii+1].f = MAX(a1[ii+1].f, a2[ii+1].f);
+    ii += 2;
+  } while (ii < n);
+}
+
+/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 1 "vect" { target { vect_float } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-pr126159-2.c b/gcc/testsuite/gcc.dg/vect/vect-pr126159-2.c
new file mode 100644
index 00000000000..8ce4b4acf06
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-pr126159-2.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+
+typedef union { int i; float f; } RtreeCoord;
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
+void cellUnion_i(RtreeCoord *a1, RtreeCoord *a2, int n) {
+  int ii = 0;
+  do {
+    a1[ii].i   = MIN(a1[ii].i,   a2[ii].i);
+    a1[ii+1].i = MAX(a1[ii+1].i, a2[ii+1].i);
+    ii += 2;
+  } while (ii < n);
+}
+
+/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 1 "vect" { target { vect_int && { ! vect_no_int_min_max } } } } } */
diff --git a/gcc/tree-data-ref.cc b/gcc/tree-data-ref.cc
index 1114903784e..8e9d7871348 100644
--- a/gcc/tree-data-ref.cc
+++ b/gcc/tree-data-ref.cc
@@ -1295,7 +1295,9 @@  access_fn_component_p (tree op)
       return true;
 
     case COMPONENT_REF:
-      return TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == RECORD_TYPE;
+      return (TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == RECORD_TYPE
+	      || (!AGGREGATE_TYPE_P (TREE_TYPE (op))
+		  && TREE_CODE (TREE_TYPE (op)) != COMPLEX_TYPE));
 
     default:
       return false;
@@ -1363,17 +1365,27 @@  dr_analyze_indices (struct indices *dri, tree ref, edge nest, loop_p loop)
 	  access_fns.safe_push (access_fn);
 	}
       else if (TREE_CODE (ref) == COMPONENT_REF
-	       && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
+	       && (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE
+		   || (!AGGREGATE_TYPE_P (TREE_TYPE (ref))
+		       && TREE_CODE (TREE_TYPE (ref)) != COMPLEX_TYPE)))
 	{
 	  /* For COMPONENT_REFs of records (but not unions!) use the
 	     FIELD_DECL offset as constant access function so we can
-	     disambiguate a[i].f1 and a[i].f2.  */
-	  tree off = component_ref_field_offset (ref);
-	  off = size_binop (PLUS_EXPR,
-			    size_binop (MULT_EXPR,
-					fold_convert (bitsizetype, off),
-					bitsize_int (BITS_PER_UNIT)),
-			    DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1)));
+	     disambiguate a[i].f1 and a[i].f2.  For unions and accesses
+	     we do not create further access functions for just use
+	     zero.  */
+	  tree off;
+	  if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
+	    {
+	      off = component_ref_field_offset (ref);
+	      off = size_binop (PLUS_EXPR,
+				size_binop (MULT_EXPR,
+					    fold_convert (bitsizetype, off),
+					    bitsize_int (BITS_PER_UNIT)),
+				DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1)));
+	    }
+	  else
+	    off = bitsize_zero_node;
 	  access_fns.safe_push (off);
 	}
       else