https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98513

--- Comment #4 from Martin Liška <marxin at gcc dot gnu.org> ---
One last version:

$ cat combined.cc
unsigned var;
unsigned array[2];
int zero = 0, minus_2 = -2;

const int &max(const int &a, const int &b) { return a > b ? a : b; }

void test(int minus_1)
{
  for (unsigned i_0 = 0; i_0 < 2; i_0++)
    {
      for (int i_1 = 0; i_1 < zero; i_1++)
        for (int i_2 = 0; i_2 < 2; i_2++)
          var = max(minus_1, 0);

      for (int i_3 = minus_2 + 2; i_3 < minus_1 + 3; i_3++)
        array[i_3] = zero;
    }
}

int main() { test(-1); }

Apparently, the unswitching is not responsible for the problem, it triggers one
more loop invariant motion
and end with:

175.lim4:

  <bb 8> [local count: 29489562]:
  _26 = (unsigned int) pretmp_1;
  array[_8] = _26;
  if (_3 >= i_3_14)
    goto <bb 9>; [66.67%]
  else
    goto <bb 7>; [33.33%]

  <bb 9> [local count: 19660691]:
  array[i_3_14] = _26;
  i_3_21 = i_3_14 + 1;
  goto <bb 7>; [100.00%]

while without the option we have:

  <bb 8> [local count: 29489562]:
  _26 = (unsigned int) pretmp_1;
  array[_8] = _26;
  i_3_11 = _8 + 1;
  if (_3 >= i_3_11)
    goto <bb 9>; [66.67%]
  else
    goto <bb 19>; [33.33%]

  <bb 9> [local count: 19660691]:
  array[i_3_11] = _26;
  i_3_21 = i_3_11 + 1;

Anyway I think the problem happens in 189.dom3 where we replace:

Optimizing statement array[i_3_14] = _26;
  Replaced 'i_3_14' with constant '-2147483648'

which is bogus (the replace is about the second iteration of the loop i_3).

Can please somebody familiar with VRP explain the transformation:

Visiting controlling predicate if (_3 >= i_3_14)
Adding assert for _3 from _3 >= i_3_14
Adding assert for i_3_14 from i_3_14 <= _3
Intersecting
  int [i_3_14, +INF]  EQUIVALENCES: { _3 } (1 elements)
and
  int [minus_1_29(D) + 2, minus_1_29(D) + 2]
to
  int [i_3_14, +INF]  EQUIVALENCES: { _3 } (1 elements)
Intersecting
  int [-INF, minus_1_29(D) + 2]  EQUIVALENCES: { i_3_14 } (1 elements)
and
  int ~[-2147483647, -2147483646]
to
  int [-INF, -INF]  EQUIVALENCES: { i_3_14 } (1 elements)
Intersecting
  int [minus_1_29(D) + 2, minus_1_29(D) + 2]
and
  int [i_3_14, +INF]
to
  int [minus_1_29(D) + 2, minus_1_29(D) + 2]
Intersecting
  int ~[-2147483647, -2147483646]
and
  int [-INF, -INF]
to
  int [-INF, -INF]
pushing new range for i_3_14: int [-INF, -INF]  EQUIVALENCES: { i_3_14 } (1
elements)
1>>> STMT 1 = _3 ge_expr i_3_14
1>>> STMT 0 = _3 lt_expr i_3_14
Optimizing statement array[i_3_14] = _26;
  Replaced 'i_3_14' with constant '-2147483648'

Reply via email to