The following patch restores proper CSE by FRE/PRE when doing optimistic value-numbering of stores/loads. In that case we may end up value-numbering a virtual operand to the only executable edge value of a PHI - but as the alias walker doesn't know this it fails to handle the PHI which results in inconsistent virtual operand being used for the entry in the hashtable. Since r173250 we refuse to value-number to sth non-VARYING in the 2nd iteration if the 1st iteration computed VARYING (which is correct).
The fix is to tell the alias walker about this optimistic handling. Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2014-12-09 Richard Biener <rguent...@suse.de> PR tree-optimization/64193 * tree-ssa-alias.c (walk_non_aliased_vuses): Add valueize parameter and valueize the VUSE before looking up the def stmt. * tree-ssa-alias.h (walk_non_aliased_vuses): Adjust prototype. * tree-ssa-sccvn.c (vn_reference_lookup_pieces): Pass vn_valueize to walk_non_aliased_vuses. (vn_reference_lookup): Likewise. * tree-ssa-dom.c (lookup_avail_expr): Pass NULL as valueize callback to walk_non_aliased_vuses. * gcc.dg/tree-ssa/ssa-fre-43.c: New testcase. Index: gcc/tree-ssa-alias.c =================================================================== --- gcc/tree-ssa-alias.c (revision 218479) +++ gcc/tree-ssa-alias.c (working copy) @@ -2632,12 +2632,18 @@ get_continuation_for_phi (gimple phi, ao If TRANSLATE returns NULL the walk continues and TRANSLATE is supposed to adjust REF and *DATA to make that valid. + VALUEIZE if non-NULL is called with the next VUSE that is considered + and return value is substituted for that. This can be used to + implement optimistic value-numbering for example. Note that the + VUSE argument is assumed to be valueized already. + TODO: Cache the vector of equivalent vuses per ref, vuse pair. */ void * walk_non_aliased_vuses (ao_ref *ref, tree vuse, void *(*walker)(ao_ref *, tree, unsigned int, void *), void *(*translate)(ao_ref *, tree, void *, bool), + tree (*valueize)(tree), void *data) { bitmap visited = NULL; @@ -2663,6 +2669,8 @@ walk_non_aliased_vuses (ao_ref *ref, tre else if (res != NULL) break; + if (valueize) + vuse = valueize (vuse); def_stmt = SSA_NAME_DEF_STMT (vuse); if (gimple_nop_p (def_stmt)) break; Index: gcc/tree-ssa-alias.h =================================================================== --- gcc/tree-ssa-alias.h (revision 218479) +++ gcc/tree-ssa-alias.h (working copy) @@ -124,6 +124,7 @@ extern void *walk_non_aliased_vuses (ao_ void *(*)(ao_ref *, tree, unsigned int, void *), void *(*)(ao_ref *, tree, void *, bool), + tree (*)(tree), void *); extern unsigned int walk_aliased_vdefs (ao_ref *, tree, bool (*)(ao_ref *, tree, void *), Index: gcc/tree-ssa-sccvn.c =================================================================== --- gcc/tree-ssa-sccvn.c (revision 218479) +++ gcc/tree-ssa-sccvn.c (working copy) @@ -2160,7 +2176,8 @@ vn_reference_lookup_pieces (tree vuse, a *vnresult = (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse, vn_reference_lookup_2, - vn_reference_lookup_3, &vr1); + vn_reference_lookup_3, + vn_valueize, &vr1); gcc_checking_assert (vr1.operands == shared_lookup_references); } @@ -2212,7 +2229,8 @@ vn_reference_lookup (tree op, tree vuse, wvnresult = (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse, vn_reference_lookup_2, - vn_reference_lookup_3, &vr1); + vn_reference_lookup_3, + vn_valueize, &vr1); gcc_checking_assert (vr1.operands == shared_lookup_references); if (wvnresult) { Index: gcc/tree-ssa-dom.c =================================================================== --- gcc/tree-ssa-dom.c (revision 218479) +++ gcc/tree-ssa-dom.c (working copy) @@ -2635,7 +2635,7 @@ lookup_avail_expr (gimple stmt, bool ins && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME && (ao_ref_init (&ref, gimple_assign_rhs1 (stmt)), true) && walk_non_aliased_vuses (&ref, vuse2, - vuse_eq, NULL, vuse1) != NULL)) + vuse_eq, NULL, NULL, vuse1) != NULL)) { struct expr_hash_elt *element2 = XNEW (struct expr_hash_elt); *element2 = element; Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c (revision 0) +++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c (working copy) @@ -0,0 +1,29 @@ +/* PR tree-optimization/64193 */ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-fre1-details" } */ + +double T,T2,E1[5]; +int J; + +void +PA(double E[]) +{ + J = 0; + +L10: + E[1] = ( E[1] + E[2] + E[3] - E[4]) * T; + E[2] = ( E[1] + E[2] - E[3] + E[4]) * T; + E[3] = ( E[1] - E[2] + E[3] + E[4]) * T; + E[4] = (-E[1] + E[2] + E[3] + E[4]) / T2; + J += 1; + + if (J < 6) + goto L10; +} + +/* We should remove 15 dead loads, fully propagating their replacements + with exactly 4 loads and 4 stores from/to E remaining. */ + +/* { dg-final { scan-tree-dump-times "Removing dead stmt" 15 "fre1" } } */ +/* { dg-final { scan-tree-dump-not "Not changing value number" "fre1" } } */ +/* { dg-final { cleanup-tree-dump "fre1" } } */