Like the already approved patch at
https://inbox.sourceware.org/gcc-patches/[email protected]/
but reworked to fit into the new simplified code and
also fixed a bug noticed for aggregates.
Aggregates include a store when doing phiprop so we need to
check if there are also loads between the original store/load
and the clobber we are skipping. Like the skipping of the
store case, I didn't see this happening enough to add the
extra checks. I did add a testcase (phiprop-5.C) which checks
this.
changes since v2:
* v3: treat aggregates special earlier and don't duplicate code.
* v2: adapt to can_handle_load instead of inline.
PR tree-optimization/116823
gcc/ChangeLog:
* tree-ssa-phiprop.cc (can_handle_load): Skip past
clobbers for !aggregate.
gcc/testsuite/ChangeLog:
* g++.dg/tree-ssa/phiprop-2.C: New test.
* g++.dg/tree-ssa/phiprop-4.C: New test.
* g++.dg/tree-ssa/phiprop-5.C: New test.
Signed-off-by: Andrew Pinski <[email protected]>
---
gcc/testsuite/g++.dg/tree-ssa/phiprop-2.C | 23 +++++++++++
gcc/testsuite/g++.dg/tree-ssa/phiprop-4.C | 30 ++++++++++++++
gcc/testsuite/g++.dg/tree-ssa/phiprop-5.C | 36 +++++++++++++++++
gcc/tree-ssa-phiprop.cc | 49 +++++++++++++++++++----
4 files changed, 131 insertions(+), 7 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/tree-ssa/phiprop-2.C
create mode 100644 gcc/testsuite/g++.dg/tree-ssa/phiprop-4.C
create mode 100644 gcc/testsuite/g++.dg/tree-ssa/phiprop-5.C
diff --git a/gcc/testsuite/g++.dg/tree-ssa/phiprop-2.C
b/gcc/testsuite/g++.dg/tree-ssa/phiprop-2.C
new file mode 100644
index 00000000000..e3388d1d157
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/phiprop-2.C
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-phiprop1-details -fdump-tree-release_ssa" } */
+
+/* PR tree-optimization/116823 */
+/* The clobber on a should not get in the way of phiprop here even if
+ this is undefined code. */
+/* We should have MIN_EXPR early on then too. */
+
+static inline
+const int &c(const int &d, const int &e) {
+ if (d < e)
+ return d;
+ return e;
+}
+
+int g(int i, struct f *ff)
+{
+ const int &a = c(i, 10);
+ return a;
+}
+/* { dg-final { scan-tree-dump-times "Inserting PHI for result of load" 1
"phiprop1"} } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "release_ssa"} } */
+
diff --git a/gcc/testsuite/g++.dg/tree-ssa/phiprop-4.C
b/gcc/testsuite/g++.dg/tree-ssa/phiprop-4.C
new file mode 100644
index 00000000000..b630148faa5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/phiprop-4.C
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-sra -fdump-tree-phiprop-details" } */
+/* PR tree-optimization/123120 */
+/* Make sure the store to *e conflicts with the store to *d */
+
+
+struct s1
+{
+ int a;
+};
+
+void f(int *);
+
+void g(struct s1 i, struct s1 *d, struct s1 *e)
+{
+ const struct s1 t = {10};
+ const struct s1 *a;
+ struct s1 t1 = {2};
+ if (t.a < i.a)
+ a = &t;
+ else
+ a = &i;
+ *e = t1;
+ t1 = *a;
+ *d = t1;
+}
+
+/* { dg-final { scan-tree-dump-not "Inserting PHI for result of load"
"phiprop1"} } */
+/* { dg-final { scan-tree-dump-not "Inserting PHI for result of load"
"phiprop2"} } */
+
diff --git a/gcc/testsuite/g++.dg/tree-ssa/phiprop-5.C
b/gcc/testsuite/g++.dg/tree-ssa/phiprop-5.C
new file mode 100644
index 00000000000..5a3a04dfaa4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/phiprop-5.C
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-phiprop-details" } */
+/* PR tree-optimization/116823 */
+/* Make sure the store to *d conflicts with the load from d->a; */
+
+
+struct s1
+{
+ int a;
+};
+
+void f(int *);
+
+int g(struct s1 i, struct s1 *d, struct s1 *e)
+{
+ int t3;
+ struct s1 t1 = {2};
+ const struct s1 t = {10};
+ const struct s1 *a;
+ {
+ int t67;
+ f(&t67);
+ if (t.a < i.a)
+ a = &t;
+ else
+ a = &i;
+ }
+ t3 = d->a;
+ *d = *a;
+ return t3;
+}
+
+
+/* { dg-final { scan-tree-dump-not "Inserting PHI for result of load"
"phiprop1"} } */
+/* { dg-final { scan-tree-dump-not "Inserting PHI for result of load"
"phiprop2"} } */
+
diff --git a/gcc/tree-ssa-phiprop.cc b/gcc/tree-ssa-phiprop.cc
index 5985beae26a..54f3ad8d9f8 100644
--- a/gcc/tree-ssa-phiprop.cc
+++ b/gcc/tree-ssa-phiprop.cc
@@ -274,22 +274,57 @@ can_handle_load (gimple *load_stmt,
expected_vuse = gimple_phi_result (vphi);
else if (up_vuse)
expected_vuse = up_vuse;
+ /* Try to see if the store does not effect the load. */
+ gimple *other_store = SSA_NAME_DEF_STMT (vuse);
+ /* For aggregates, skipping the store is too
+ hard to handle as you need to check for loads
+ and it is not worth the extra checks so just handle expected vuse
+ and the dominated by case. */
+ if (aggregate)
+ {
+ /* If the vuse on the load is the same as the expected vuse,
+ there are no stores inbetween. */
+ if (vuse == expected_vuse)
+ return vuse;
+ if (expected_vuse)
+ return NULL_TREE;
+ if (gimple_bb (other_store) != bb
+ && dominated_by_p (CDI_DOMINATORS,
+ bb, gimple_bb (other_store)))
+ return vuse;
+ return NULL_TREE;
+ }
+
+ /* Skip over clobbers in the same bb as the use
+ as they don't interfere with loads. */
+ while (!SSA_NAME_IS_DEFAULT_DEF (vuse)
+ && gimple_clobber_p (other_store)
+ && gimple_bb (other_store) == bb)
+ {
+ vuse = gimple_vuse (other_store);
+ other_store = SSA_NAME_DEF_STMT (vuse);
+ }
+ /* If the load does not have a store beforehand,
+ then we can do the load in conditional. */
+ if (SSA_NAME_IS_DEFAULT_DEF (vuse))
+ {
+ /* For loads that have no stores before, there should be no
+ vphi. */
+ gcc_checking_assert (!vphi);
+ /* The common vuse is the same as the default or there is none. */
+ gcc_checking_assert (!up_vuse || up_vuse == vuse);
+ return vuse;
+ }
/* If the vuse on the load is the same as the expected vuse,
there are no stores inbetween. */
if (vuse == expected_vuse)
return vuse;
- /* Try to see if the store does not effect the load. */
- gimple *other_store = SSA_NAME_DEF_STMT (vuse);
+
/* Only handling the case where the store is in the same
bb as the phi. */
if (gimple_bb (other_store) == bb)
{
- /* For aggregates, skipping the store is too
- hard to handle as you need to check for loads
- and it is not worth the extra checks. */
- if (aggregate)
- return NULL_TREE;
tree src = gimple_assign_rhs1 (load_stmt);
ao_ref read;
ao_ref_init (&read, src);
--
2.43.0