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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |aldyh at gcc dot gnu.org,
                   |                            |jakub at gcc dot gnu.org,
                   |                            |law at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, during evrp we have:
  <bb 2> :
  goto <bb 4>; [INV]

  <bb 3> :
  __builtin_snprintf (&temp, 4, "%%%02X", x_1);
  # RANGE [1, 256] NONZERO 511
  x_6 = x_1 + 1;

  <bb 4> :
  # RANGE [0, 256] NONZERO 511
  # x_1 = PHI <0(2), x_6(3)>
  if (x_1 != 256)
    goto <bb 3>; [INV]
  else
    goto <bb 5>; [INV]

and that is correct and maximum of what we can achieve, x_1 indeed has [0, 256]
range and only perhaps on-demand vrp analysis improvements can help there for
the use in bb 3.
During vrp1 it is still like that but we have additional assert_expr
  <bb 3> [local count: 1063004407]:
  x_7 = ASSERT_EXPR <x_1, x_1 != 256>;
  __builtin_snprintf (&temp, 4, "%%%02X", x_7);
  x_5 = x_7 + 1;

  <bb 4> [local count: 1073741824]:
  if (x_1 != 256)
    goto <bb 3>; [99.00%]
  else
    goto <bb 5>; [1.00%]
and determine:
x_1: unsigned int [0, 256]
x_5: unsigned int [1, 256]
x_7: unsigned int [0, 255]  EQUIVALENCES: { x_1 } (1 elements)
But the ASSERT_EXPR is removed and there was nothing to stick the [0, 255]
range on, so before jump threading in vrp1 we have:
  <bb 2> [local count: 10737418]:
  goto <bb 4>; [100.00%]

  <bb 3> [local count: 1063004407]:
  __builtin_snprintf (&temp, 4, "%%%02X", x_1);
  # RANGE [1, 256] NONZERO 511
  x_5 = x_1 + 1;

  <bb 4> [local count: 1073741824]:
  # RANGE [0, 256] NONZERO 511
  # x_1 = PHI <0(2), x_5(3)>
  if (x_1 != 256)
    goto <bb 3>; [99.00%]
  else
    goto <bb 5>; [1.00%]
Then the jump threading transforms this into:
  <bb 2> [local count: 10737418]:
  goto <bb 6>; [100.00%]

  <bb 3> [local count: 1063004407]:
  # RANGE [0, 256] NONZERO 511
  # x_10 = PHI <x_1(4), x_8(6)>
  __builtin_snprintf (&temp, 4, "%%%02X", x_10);
  # RANGE [1, 256] NONZERO 511
  x_5 = x_10 + 1;

  <bb 4> [local count: 1063004406]:
  # RANGE [0, 256] NONZERO 511
  # x_1 = PHI <x_5(3)>
  if (x_1 != 256)
    goto <bb 3>; [98.99%]
  else
    goto <bb 5>; [1.01%]

  <bb 6> [local count: 10737418]:
  # RANGE [0, 256] NONZERO 511
  # x_8 = PHI <0(2)>
  goto <bb 3>; [100.00%]

And that is already the case where the range info is only conservatively
correct, but we could perhaps do better, though it would mean jump threading
has to think about the value ranges of the SSA_NAMEs it creates.
In particular, x_8 could have range:
  # RANGE [0, 0] NONZERO 0
because the phi arg is constant 0, and x_10 could have:
  # RANGE [0, 255] NONZERO 255
because x_8 has [0, 0] range and while x_1 has [0, 256] range, the condition on
the 4 -> 3 edge is x_1 != 256.  Is that doable in the jump threading code at
least for the simple cases?  Or should some other pass figure this out?
Right now it is only vrp2 that adjusts the range, too late for the
printf-return-value2 pass that queries this info.

Reply via email to