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);
