The second test on shared_lookup_references in the block:
/* We need to pre-pend vr->operands[0..i] to rhs. */
vec<vn_reference_op_s> old = vr->operands;
if (i + 1 + rhs.length () > vr->operands.length ())
{
vr->operands.safe_grow (i + 1 + rhs.length ());
if (old == shared_lookup_references)
shared_lookup_references = vr->operands;
}
else
vr->operands.truncate (i + 1 + rhs.length ());
FOR_EACH_VEC_ELT (rhs, j, vro)
vr->operands[i + 1 + j] = *vro;
vr->operands = valueize_refs (vr->operands);
if (old == shared_lookup_references)
shared_lookup_references = vr->operands;
is bypassed when the first test is true because "old" contains a stalled value
of shared_lookup_references. This may result in either memory corruption
(when checking is disabled) or in the failure of one of the assertions:
gcc_checking_assert (vr1.operands == shared_lookup_references);
in vn_reference_lookup_pieces or vn_reference_lookup. This was caught on a
big proprietary Ada application in LTO mode.
Tested on x86_64-suse-linux, approved privately by Richard B., applied on the
mainline and 6 branch.
2016-06-13 Eric Botcazou <ebotca...@adacore.com>
* tree-ssa-sccvn.c (vn_reference_lookup_3): Use a uniform test and
update shared_lookup_references only once after changing operands.
--
Eric Botcazou
Index: tree-ssa-sccvn.c
===================================================================
--- tree-ssa-sccvn.c (revision 237323)
+++ tree-ssa-sccvn.c (working copy)
@@ -2089,11 +2089,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree
/* We need to pre-pend vr->operands[0..i] to rhs. */
vec<vn_reference_op_s> old = vr->operands;
if (i + 1 + rhs.length () > vr->operands.length ())
- {
- vr->operands.safe_grow (i + 1 + rhs.length ());
- if (old == shared_lookup_references)
- shared_lookup_references = vr->operands;
- }
+ vr->operands.safe_grow (i + 1 + rhs.length ());
else
vr->operands.truncate (i + 1 + rhs.length ());
FOR_EACH_VEC_ELT (rhs, j, vro)
@@ -2244,8 +2240,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree
{
vec<vn_reference_op_s> old = vr->operands;
vr->operands.safe_grow_cleared (2);
- if (old == shared_lookup_references
- && vr->operands != old)
+ if (old == shared_lookup_references)
shared_lookup_references = vr->operands;
}
else