[gcc r17-2217] tree-optimization/126159 - handle unions in data dependence analysis

Richard Biener via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:c31cb13628593fc57779419a806170b6ef2c3b81

commit r17-2217-gc31cb13628593fc57779419a806170b6ef2c3b81
Author: Richard Biener <[email protected]>
Date:   Wed Jul 8 10:06:40 2026 +0200

    tree-optimization/126159 - handle unions in data dependence analysis
    
    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.
    
            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.

Diff:
---
 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(-)

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 000000000000..d364d28d7d24
--- /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 000000000000..8ce4b4acf06d
--- /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 1114903784e5..8e9d78713482 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.