diff options
author | Andrew Pinski <andrew.pinski@oss.qualcomm.com> | 2025-09-07 09:33:07 -0700 |
---|---|---|
committer | Andrew Pinski <andrew.pinski@oss.qualcomm.com> | 2025-09-07 13:46:39 -0700 |
commit | 7e1143abd32cd40d24479d4c536b610ea9aad2db (patch) | |
tree | d414572df40a4ba007d124d39a11170d20d0231f /gcc | |
parent | 1b9c218d1429d596a33b13e450da0bdc1643e984 (diff) | |
download | gcc-7e1143abd32cd40d24479d4c536b610ea9aad2db.zip gcc-7e1143abd32cd40d24479d4c536b610ea9aad2db.tar.gz gcc-7e1143abd32cd40d24479d4c536b610ea9aad2db.tar.bz2 |
forwprop: Improve rejection of overlapping for copyprop of aggregates [PR121841]
Here we have:
tmp = src1[0];
dest1[0] = tmp;
where src1 and dest1 are decls.
We currently reject this as the bases are different but since the bases
are decls we know they won't overlap.
This adds the extra check to allow this.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/121841
gcc/ChangeLog:
* tree-ssa-forwprop.cc (optimize_agr_copyprop_1): Allow
two different decls as bases as non-overlapping bases.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/copy-prop-aggregate-struct-1.c: New test.
Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-struct-1.c | 21 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.cc | 12 |
2 files changed, 30 insertions, 3 deletions
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 0000000..3786250 --- /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 f244b12..9c6f4b3 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); |