diff options
author | Richard Biener <rguenther@suse.de> | 2021-10-25 09:33:15 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2021-10-25 10:28:00 +0200 |
commit | aa15952d646fd5dd569fce287b719a737ae66e4f (patch) | |
tree | f0b2f3add7c2e9297845e5b19a1dd971f4211791 /gcc/tree-ssa-sccvn.c | |
parent | 7c20a9b738a2257bed4e2b0593275336d1e2047a (diff) | |
download | gcc-aa15952d646fd5dd569fce287b719a737ae66e4f.zip gcc-aa15952d646fd5dd569fce287b719a737ae66e4f.tar.gz gcc-aa15952d646fd5dd569fce287b719a737ae66e4f.tar.bz2 |
tree-optimization/102920 - fix PHI VN with undefined args
This fixes a latent issue exposed by now allowing VN_TOP in PHI
arguments. We may only use optimistic equality when merging values on
different edges, not when merging values on the same edge - in particular
we may not choose the undef value on any edge when there's a not undef
value as well.
2021-10-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/102920
* tree-ssa-sccvn.h (expressions_equal_p): Add argument
controlling VN_TOP matching behavior.
* tree-ssa-sccvn.c (expressions_equal_p): Likewise.
(vn_phi_eq): Do not optimistically match VN_TOP.
* gcc.dg/torture/pr102920.c: New testcase.
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 893b1d0..d524259 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -4441,11 +4441,15 @@ vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2) if (inverted_p) std::swap (te2, fe2); - /* ??? Handle VN_TOP specially. */ + /* Since we do not know which edge will be executed we have + to be careful when matching VN_TOP. Be conservative and + only match VN_TOP == VN_TOP for now, we could allow + VN_TOP on the not prevailing PHI though. See for example + PR102920. */ if (! expressions_equal_p (vp1->phiargs[te1->dest_idx], - vp2->phiargs[te2->dest_idx]) + vp2->phiargs[te2->dest_idx], false) || ! expressions_equal_p (vp1->phiargs[fe1->dest_idx], - vp2->phiargs[fe2->dest_idx])) + vp2->phiargs[fe2->dest_idx], false)) return false; return true; @@ -4470,7 +4474,7 @@ vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2) tree phi2op = vp2->phiargs[i]; if (phi1op == phi2op) continue; - if (!expressions_equal_p (phi1op, phi2op)) + if (!expressions_equal_p (phi1op, phi2op, false)) return false; } @@ -5816,17 +5820,20 @@ get_next_constant_value_id (void) } -/* Compare two expressions E1 and E2 and return true if they are equal. */ +/* Compare two expressions E1 and E2 and return true if they are equal. + If match_vn_top_optimistically is true then VN_TOP is equal to anything, + otherwise VN_TOP only matches VN_TOP. */ bool -expressions_equal_p (tree e1, tree e2) +expressions_equal_p (tree e1, tree e2, bool match_vn_top_optimistically) { /* The obvious case. */ if (e1 == e2) return true; /* If either one is VN_TOP consider them equal. */ - if (e1 == VN_TOP || e2 == VN_TOP) + if (match_vn_top_optimistically + && (e1 == VN_TOP || e2 == VN_TOP)) return true; /* SSA_NAME compare pointer equal. */ |