+2017-11-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/23094
+ * tree-ssa-sccvn.c (vuse_ssa_val): Handle VN_TOP when we
+ come here from walking over backedges in the first iteration.
+ (vn_reference_lookup_3): Skip clobbers that store the same value.
+
2017-11-23 Richard Biener <rguenther@suse.de>
PR tree-optimization/81403
--- /dev/null
+/* { dg-do link } */
+/* { dg-options "-O -fdump-tree-fre1-details" } */
+
+void link_error (void);
+
+void test1 (int *p, int *q)
+{
+ *p = 1;
+ *q = 1;
+ if (*p != 1)
+ link_error ();
+}
+
+void test2 (int *p, int *q, int t)
+{
+ *p = t;
+ *q = t;
+ if (*p != t)
+ link_error ();
+}
+
+void test3 (int *q, int *p)
+{
+ int tem = *p;
+ *q = tem;
+ if (*p != tem)
+ link_error ();
+}
+
+char a[4];
+struct A { char a[4]; };
+void test4 (struct A *p)
+{
+ a[0] = p->a[0];
+ a[0] = p->a[0];
+ a[0] = p->a[0];
+}
+
+int main() { return 0; }
+
+/* { dg-final { scan-tree-dump-times "Replaced \\\*p" 3 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "Replaced p_.\\(D\\)->" 2 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "Deleted redundant store a\\\[0\\\]" 2 "fre1" } } */
do
{
- x = SSA_VAL (x);
+ tree tem = SSA_VAL (x);
+ /* stmt walking can walk over a backedge and reach code we didn't
+ value-number yet. */
+ if (tem == VN_TOP)
+ return x;
+ x = tem;
}
while (SSA_NAME_IN_FREE_LIST (x));
ao_ref_init (&lhs_ref, lhs);
lhs_ref_ok = true;
}
+
+ /* If we reach a clobbering statement try to skip it and see if
+ we find a VN result with exactly the same value as the
+ possible clobber. In this case we can ignore the clobber
+ and return the found value.
+ Note that we don't need to worry about partial overlapping
+ accesses as we then can use TBAA to disambiguate against the
+ clobbering statement when looking up a load (thus the
+ VN_WALKREWRITE guard). */
+ if (vn_walk_kind == VN_WALKREWRITE
+ && is_gimple_reg_type (TREE_TYPE (lhs))
+ && types_compatible_p (TREE_TYPE (lhs), vr->type))
+ {
+ tree *saved_last_vuse_ptr = last_vuse_ptr;
+ /* Do not update last_vuse_ptr in vn_reference_lookup_2. */
+ last_vuse_ptr = NULL;
+ tree saved_vuse = vr->vuse;
+ hashval_t saved_hashcode = vr->hashcode;
+ void *res = vn_reference_lookup_2 (ref,
+ gimple_vuse (def_stmt), 0, vr);
+ /* Need to restore vr->vuse and vr->hashcode. */
+ vr->vuse = saved_vuse;
+ vr->hashcode = saved_hashcode;
+ last_vuse_ptr = saved_last_vuse_ptr;
+ if (res && res != (void *)-1)
+ {
+ vn_reference_t vnresult = (vn_reference_t) res;
+ if (vnresult->result
+ && operand_equal_p (vnresult->result,
+ gimple_assign_rhs1 (def_stmt), 0))
+ return res;
+ }
+ }
}
else if (gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL)
&& gimple_call_num_args (def_stmt) <= 4)