https://gcc.gnu.org/g:9e80bae85515a764c795db9610810b943c23b07c

commit r16-9268-g9e80bae85515a764c795db9610810b943c23b07c
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.
    
    (cherry picked from commit 17ce6875a08253fb02580bd365a4528e9225efb9)

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 a753aa708d28..47f897a9e1ad 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