https://gcc.gnu.org/g:17ce6875a08253fb02580bd365a4528e9225efb9

commit r17-525-g17ce6875a08253fb02580bd365a4528e9225efb9
Author: Richard Biener <[email protected]>
Date:   Wed May 13 14:59:31 2026 +0200

    tree-optimization/125296 - preserve alignment of access with address 
forwarding
    
    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.

Diff:
---
 gcc/testsuite/gcc.dg/pr125206.c | 22 ++++++++++++++++++++++
 gcc/tree-ssa-forwprop.cc        |  6 ++++--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/pr125206.c b/gcc/testsuite/gcc.dg/pr125206.c
new file mode 100644
index 000000000000..81db1f6d45db
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr125206.c
@@ -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 } } } */
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 0d76f85e2acf..1587fa7bd142 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -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);

Reply via email to