]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/125296 - preserve alignment of access with address forwarding
authorRichard Biener <rguenther@suse.de>
Wed, 13 May 2026 12:59:31 +0000 (14:59 +0200)
committerRichard Biener <rguenther@suse.de>
Fri, 15 May 2026 08:50:28 +0000 (10:50 +0200)
The following makes sure to preserve the alignment of the access
and not pick up that of parts of the address we forward.

PR tree-optimization/125296
* tree-ssa-forwprop.cc (forward_propagate_addr_expr_1):
Preserve alignment of the original access.

* gcc.dg/pr125206.c: New testcase.

gcc/testsuite/gcc.dg/pr125206.c [new file with mode: 0644]
gcc/tree-ssa-forwprop.cc

diff --git a/gcc/testsuite/gcc.dg/pr125206.c b/gcc/testsuite/gcc.dg/pr125206.c
new file mode 100644 (file)
index 0000000..81db1f6
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fgimple -fdump-tree-forwprop1-gimple" } */
+
+struct S {
+  struct S *next;
+  int vals[5];
+};
+
+int __GIMPLE foo (struct S * s, int idx)
+{
+  int D_2968;
+  int *_1;
+
+  /* In GIMPLE '*s' does not have to be aligned according to its type
+     so we have to preserve the alignment of the access when forwarding
+     the address.  */
+  _1 = &s->vals[idx];
+  D_2968 = __MEM <volatile int> ((volatile int *)_1);
+  return D_2968;
+}
+
+/* { dg-final { scan-tree-dump "__MEM <struct S, 32>" "forwprop1" { target lp64 } } } */
index 0d76f85e2acff61ab9c6d427898b8525d38e191e..1587fa7bd14285686d4dba93d95e51a84fa7ee19 100644 (file)
@@ -856,8 +856,10 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
              new_base = build_fold_addr_expr (*def_rhs_basep);
              new_offset = TREE_OPERAND (rhs, 1);
            }
-         *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep),
-                                  new_base, new_offset);
+         tree atype = TREE_TYPE (*def_rhs_basep);
+         if (TYPE_ALIGN (TREE_TYPE (rhs)) < TYPE_ALIGN (atype))
+           atype = build_aligned_type (atype, TYPE_ALIGN (TREE_TYPE (rhs)));
+         *def_rhs_basep = build2 (MEM_REF, atype, new_base, new_offset);
          TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (rhs);
          TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (rhs);
          TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (rhs);