On 11/11/21 08:15, Richard Biener wrote:
If you look at simplify_using_entry_checks then this is really really simple,
so I'd try to abstract this, recording sth like a unswitch_predicate where
we store the condition we unswitch on plus maybe cache the constant
range of a VAR cmp CST variable condition on the true/false edge. We
can then try to simplify each gcond/gswitch based on such an unswitch_predicate
(when we ever scan the loop once to discover all opportunities we'd have a
set of unswitch_predicates to try simplifying against). As said the integer
range thing would be an improvement over the current state so even that
can be done as followup but I guess for gswitch support that's going to be
the thing to use.
I started working on the unswitch_predicate where I recond also true/false-edge
irange
of an expression we unswitch on.
I noticed one significant problem, let's consider:
for (int i = 0; i < size; i++)
{
double tmp;
if (order == 1)
tmp = -8 * a[i];
else
{
if (order == 2)
tmp = -4 * b[i];
else
tmp = a[i];
}
r[i] = 3.4f * tmp + d[i];
}
We can end up with first unswitching candidate being 'if (order == 2)' (I have
a real benchmark where it happens).
So I collect ranges and they are [2,2] for true edge and [-INF, 0], [3, INF]
(because we came to the condition through order != 1 cond).
Then the loop is cloned and we have
if (order == 2)
loop_version_1
else
loop_version_2
but in loop_version_2 we wrongly fold 'if (order == 1)' to false because it's
reflected in the range.
So the question is, can one iterate get_loop_body stmts in some dominator order?
Thanks,
Martin