mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
tree-optimization/109342 - wrong code with edge equivalences in VN
The following testcase shows a problem in how we query valitity for equivalences on edges when the edge is a backedge and thus refering to a block thats later in the iteration order we use for VN. That causes the dominated_by_p_w_unex helper to look at edge executable state that's not yet computed and thus still at optimistic not executable state. The following makes sure to use a plain dominance check in these cases. PR tree-optimization/109342 * tree-ssa-sccvn.cc (vn_nary_op_get_predicated_value): New overload for edge. When that edge is a backedge use dominated_by_p directly. * g++.dg/torture/pr109342.C: New testcase.
This commit is contained in:
parent
ee6ae8cb47
commit
1d0ba4467d
33
gcc/testsuite/g++.dg/torture/pr109342.C
Normal file
33
gcc/testsuite/g++.dg/torture/pr109342.C
Normal file
@ -0,0 +1,33 @@
|
||||
// { dg-do run }
|
||||
|
||||
unsigned long int var_4 = 42;
|
||||
unsigned long int var_14 = 10;
|
||||
unsigned char var_16 = 1;
|
||||
unsigned short var_18 = 0;
|
||||
short var_75;
|
||||
|
||||
inline const int &foo(const int &b, const int &c)
|
||||
{
|
||||
return b < c ? c : b;
|
||||
}
|
||||
inline unsigned long &bar(unsigned long &b, unsigned long &c)
|
||||
{
|
||||
return !c ? c : b;
|
||||
}
|
||||
|
||||
void __attribute__((noipa))
|
||||
test(unsigned long var_4, unsigned long var_14,
|
||||
unsigned char var_16, unsigned short var_18)
|
||||
{
|
||||
for (bool h = 0; h < (bool)foo(var_16 ? -7 : 4, var_4 ? var_4 : var_18);
|
||||
h = 2)
|
||||
var_75 = bar(var_4, var_14);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test(var_4, var_14, var_16, var_18);
|
||||
if (var_75 != 42)
|
||||
__builtin_abort();
|
||||
return 0;
|
||||
}
|
@ -4583,22 +4583,39 @@ static bool
|
||||
dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool);
|
||||
|
||||
static tree
|
||||
vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb)
|
||||
vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb,
|
||||
edge e = NULL)
|
||||
{
|
||||
if (! vno->predicated_values)
|
||||
return vno->u.result;
|
||||
for (vn_pval *val = vno->u.values; val; val = val->next)
|
||||
for (unsigned i = 0; i < val->n; ++i)
|
||||
/* Do not handle backedge executability optimistically since
|
||||
when figuring out whether to iterate we do not consider
|
||||
changed predication. */
|
||||
if (dominated_by_p_w_unex
|
||||
(bb, BASIC_BLOCK_FOR_FN (cfun, val->valid_dominated_by_p[i]),
|
||||
false))
|
||||
return val->result;
|
||||
{
|
||||
basic_block cand
|
||||
= BASIC_BLOCK_FOR_FN (cfun, val->valid_dominated_by_p[i]);
|
||||
/* Do not handle backedge executability optimistically since
|
||||
when figuring out whether to iterate we do not consider
|
||||
changed predication.
|
||||
When asking for predicated values on an edge avoid looking
|
||||
at edge executability for edges forward in our iteration
|
||||
as well. */
|
||||
if (e && (e->flags & EDGE_DFS_BACK))
|
||||
{
|
||||
if (dominated_by_p (CDI_DOMINATORS, bb, cand))
|
||||
return val->result;
|
||||
}
|
||||
else if (dominated_by_p_w_unex (bb, cand, false))
|
||||
return val->result;
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
static tree
|
||||
vn_nary_op_get_predicated_value (vn_nary_op_t vno, edge e)
|
||||
{
|
||||
return vn_nary_op_get_predicated_value (vno, e->src, e);
|
||||
}
|
||||
|
||||
/* Insert the rhs of STMT into the current hash table with a value number of
|
||||
RESULT. */
|
||||
|
||||
@ -5928,7 +5945,7 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
|
||||
ops, &vnresult);
|
||||
if (! val && vnresult && vnresult->predicated_values)
|
||||
{
|
||||
val = vn_nary_op_get_predicated_value (vnresult, e->src);
|
||||
val = vn_nary_op_get_predicated_value (vnresult, e);
|
||||
if (val && integer_truep (val)
|
||||
&& !(sameval_e && (sameval_e->flags & EDGE_DFS_BACK)))
|
||||
{
|
||||
@ -5947,7 +5964,7 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
|
||||
we can change sameval to def. */
|
||||
if (EDGE_COUNT (bb->preds) == 2
|
||||
&& (val = vn_nary_op_get_predicated_value
|
||||
(vnresult, EDGE_PRED (bb, 0)->src))
|
||||
(vnresult, EDGE_PRED (bb, 0)))
|
||||
&& integer_truep (val)
|
||||
&& !(e->flags & EDGE_DFS_BACK))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user