diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-struct-1.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-struct-1.c new file mode 100644 index 00000000000..37862507870 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-struct-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-forwprop1-details -fdump-tree-optimized" } */ +/* PR tree-optimization/121841 */ + +struct U2 { + int i[1024]; +}; + +struct U2 g_284[1] = {{0UL}}; +struct U2 g_283[1]; + +/* g_284[0] and g_283[0] are known not to + overlap so a copy prop can happen. */ +void func_1() { + struct U2 removeme; + removeme = g_284[0]; + g_283[0] = removeme; +} + +/* { dg-final { scan-tree-dump-times "after previous" 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-not "removeme " "optimized" } } */ diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc index f244b12b6d1..9c6f4b355d6 100644 --- a/gcc/tree-ssa-forwprop.cc +++ b/gcc/tree-ssa-forwprop.cc @@ -1467,11 +1467,17 @@ optimize_agr_copyprop_1 (gimple *stmt, gimple *use_stmt, tree base1 = get_addr_base_and_unit_offset (dest2, &offset1); tree base2 = get_addr_base_and_unit_offset (src, &offset2); poly_int64 size = tree_to_poly_int64 (len); + /* If the bases are 2 different decls, + then there can be no overlapping. */ + if (base1 && base2 + && DECL_P (base1) && DECL_P (base2) + && base1 != base2) + ; /* If we can't figure out the base or the bases are not equal then fall back to an alignment check. */ - if (!base1 - || !base2 - || !operand_equal_p (base1, base2)) + else if (!base1 + || !base2 + || !operand_equal_p (base1, base2)) { unsigned int align1 = get_object_alignment (src); unsigned int align2 = get_object_alignment (dest2);