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.
This commit is contained in:
parent
7c20a9b738
commit
aa15952d64
|
@ -0,0 +1,25 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-additional-options "-funswitch-loops" } */
|
||||
|
||||
unsigned short a = 42;
|
||||
unsigned short b = 1;
|
||||
long int c = 1;
|
||||
unsigned char var_120;
|
||||
unsigned char var_123;
|
||||
|
||||
void __attribute__((noipa)) test(unsigned short a, unsigned short b, long c)
|
||||
{
|
||||
for (char i = 0; i < (char)c; i += 5)
|
||||
if (!b)
|
||||
var_120 = a;
|
||||
else
|
||||
var_123 = a;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test(a, b, c);
|
||||
if (var_123 != 42)
|
||||
__builtin_abort ();
|
||||
return 0;
|
||||
}
|
|
@ -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. */
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#define TREE_SSA_SCCVN_H
|
||||
|
||||
/* In tree-ssa-sccvn.c */
|
||||
bool expressions_equal_p (tree, tree);
|
||||
bool expressions_equal_p (tree, tree, bool = true);
|
||||
|
||||
|
||||
/* TOP of the VN lattice. */
|
||||
|
|
Loading…
Reference in New Issue