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


Reply via email to