--- /dev/null
+/* { 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"} } */
+
--- /dev/null
+/* { 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"} } */
+
--- /dev/null
+/* { 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"} } */
+
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);