aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2025-04-07 17:57:07 -0700
committerAndrew Pinski <quic_apinski@quicinc.com>2025-04-18 09:13:48 -0700
commit2d693c1ffd849e0c1df9cc6610a69a63ffcb2956 (patch)
tree05c9f976c91825e77ccf01f383bd1d3dcfee258c /gcc
parent800b3977031dd4f14d09ced975276e09457dfff7 (diff)
downloadgcc-2d693c1ffd849e0c1df9cc6610a69a63ffcb2956.zip
gcc-2d693c1ffd849e0c1df9cc6610a69a63ffcb2956.tar.gz
gcc-2d693c1ffd849e0c1df9cc6610a69a63ffcb2956.tar.bz2
DSE: Trim stores of 0 like triming stores of {} [PR87901]
This is the second part of the PR which comes from transformation of memset into either stores of 0 (via an integral type) or stores of {}. We already handle stores of `{}`, this just extends that to handle of the constant 0 and treat it similarly. PR tree-optimization/87901 gcc/ChangeLog: * tree-ssa-dse.cc (maybe_trim_constructor_store): Add was_integer_cst argument. Check for was_integer_cst instead of `{}` when was_integer_cst is true. (maybe_trim_partially_dead_store): Handle INTEGER_CST stores of 0 as stores of `{}`. Udpate call to maybe_trim_constructor_store for CONSTRUCTOR. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/ssa-dse-53.c: New test. * gcc.dg/tree-ssa/ssa-dse-54.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-53.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-54.c25
-rw-r--r--gcc/tree-ssa-dse.cc14
3 files changed, 61 insertions, 4 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-53.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-53.c
new file mode 100644
index 0000000..a2df591
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-53.c
@@ -0,0 +1,26 @@
+/* { dg-options "-O2 -fno-strict-aliasing -fdump-tree-dse-details -fno-tree-fre -fdump-tree-optimized" } */
+
+/* PR tree-optimization/87901 */
+
+
+int i;
+int foo ()
+{
+ i = 0;
+ *((short *)&i + 1) = 1;
+ return i;
+}
+
+/* we should get:
+ MEM <char[2]> [(int *)&i] = {};
+ MEM[(short int *)&i + 2B] = 1;
+ in DSE1.
+
+ Note later on the stores will be merged. */
+/* { dg-final { scan-tree-dump "return 65536;" "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump "return 1;" "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump "\\\[2\\\]" "dse1" } } */
+
+/* { dg-final { scan-tree-dump-times "Trimming statement " 1 "dse1" } } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-54.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-54.c
new file mode 100644
index 0000000..7e79a73
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-54.c
@@ -0,0 +1,25 @@
+/* { dg-options "-O2 -fdump-tree-dse-details -fno-tree-fre -fdump-tree-optimized" } */
+
+/* PR tree-optimization/87901 */
+
+int z[128];
+void foo1(void)
+{
+ int z1;
+ int z2[24/sizeof(int)];
+ __builtin_memset (&z1, 0, sizeof(int));
+ __builtin_memcpy (z, &z1, sizeof(int));
+ __builtin_memset (z2, 0, 24);
+ __builtin_memcpy (((char*)z)+1, z2, 24);
+}
+
+/* we should get:
+ MEM[(char * {ref-all})&z] = {};
+ __builtin_memset (&MEM <int[128]> [(void *)&z + 1B], 0, 24);
+ */
+
+/* { dg-final { scan-tree-dump-not "MEM <unsigned int>" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "MEM \\\[" "dse1" } } */
+/* { dg-final { scan-tree-dump-times "Trimming statement " 1 "dse1" } } */
+/* { dg-final { scan-tree-dump-times "Deleted dead call:" 1 "dse1" } } */
+
diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc
index 82ebc99..d1d58bf 100644
--- a/gcc/tree-ssa-dse.cc
+++ b/gcc/tree-ssa-dse.cc
@@ -566,16 +566,17 @@ maybe_trim_complex_store (ao_ref *ref, sbitmap live, gimple *stmt)
The most common case for getting here is a CONSTRUCTOR with no elements
being used to zero initialize an object. We do not try to handle other
cases as those would force us to fully cover the object with the
- CONSTRUCTOR node except for the components that are dead. */
+ CONSTRUCTOR node except for the components that are dead.
+ Also handles integer stores of 0 which can happen with memset/memcpy optimizations. */
static void
-maybe_trim_constructor_store (ao_ref *ref, sbitmap live, gimple *stmt)
+maybe_trim_constructor_store (ao_ref *ref, sbitmap live, gimple *stmt, bool was_integer_cst)
{
tree ctor = gimple_assign_rhs1 (stmt);
/* This is the only case we currently handle. It actually seems to
catch most cases of actual interest. */
- gcc_assert (CONSTRUCTOR_NELTS (ctor) == 0);
+ gcc_assert (was_integer_cst ? integer_zerop (ctor) : CONSTRUCTOR_NELTS (ctor) == 0);
int head_trim = 0;
int tail_trim = 0;
@@ -804,11 +805,16 @@ maybe_trim_partially_dead_store (ao_ref *ref, sbitmap live, gimple *stmt)
switch (gimple_assign_rhs_code (stmt))
{
case CONSTRUCTOR:
- maybe_trim_constructor_store (ref, live, stmt);
+ maybe_trim_constructor_store (ref, live, stmt, false);
break;
case COMPLEX_CST:
maybe_trim_complex_store (ref, live, stmt);
break;
+ case INTEGER_CST:
+ if (integer_zerop (gimple_assign_rhs1 (stmt))
+ && type_has_mode_precision_p (TREE_TYPE (gimple_assign_lhs (stmt))))
+ maybe_trim_constructor_store (ref, live, stmt, true);
+ break;
default:
break;
}