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