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

--- Comment #40 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The current state of #c0 testcase is that bar is actually optimized into return
1;
Folding statement: .ASSUME (_Z3bard._assume.0, x_1(D));
_Z3bard._assume.0 assume inferred range of x_1(D) (param x) = [frange] double
[-1.79769313486231570814527423731704356798070567525844996599e+308
(-0x0.fffffffffffff8p+1024), 1.7976931
3486231570814527423731704356798070567525844996599e+308
(0x0.fffffffffffff8p+1024)]
during vrp1 and
Folding statement: _4 = _3 u>
1.79769313486231570814527423731704356798070567525844996599e+308;
Queued stmt for removal.  Folds to: 0

It is correct to optimize the comparison even with -ftrapping-math -
comparisons only
emit exceptions on NaNs, the quiet ones like u> even just on sNaNs, and the
range proves that the non-constant operand is never a NAN and the other isn't
either (it is constant).

On the other side, foo isn't optimized.
  # RANGE [frange] double [0.0 (0x0.0p+0), +Inf] +NAN
  _6 = ABS_EXPR <x_3(D)>;
  _4 = _6 u> 1.79769313486231570814527423731704356798070567525844996599e+308;
  _8 = ~_4;
  if (_6 u> 1.79769313486231570814527423731704356798070567525844996599e+308)
    goto <bb 3>; [INV]
  else
    goto <bb 4>; [INV]

  <bb 3> :
  __builtin_unreachable ();

  <bb 4> :
  # RANGE [frange] double [0.0 (0x0.0p+0), +Inf] +NAN
  _9 = ABS_EXPR <x_3(D)>;
  _10 = _9 u> 1.79769313486231570814527423731704356798070567525844996599e+308;
  _11 = ~_10;
  return _11;
is turned by fre1 into:
  _6 = ABS_EXPR <x_3(D)>;
  _4 = _6 u> 1.79769313486231570814527423731704356798070567525844996599e+308;
  _8 = ~_4;
  if (_6 u> 1.79769313486231570814527423731704356798070567525844996599e+308)
    goto <bb 3>; [INV]
  else
    goto <bb 4>; [INV]

  <bb 3> :
  __builtin_unreachable ();

  <bb 4> :
  return _8;
and while e.g. evrp figures correctly out that
2->3  (T) _6 :  [frange] double [+Inf, +Inf] +NAN
2->4  (F) x_3(D) :      [frange] double
[-1.79769313486231570814527423731704356798070567525844996599e+308
(-0x0.fffffffffffff8p+1024), 1.797693134862315708145274237317043567980705675
25844996599e+308 (0x0.fffffffffffff8p+1024)]
2->4  (F) _4 :  [irange] bool [0, 0] NONZERO 0x0
2->4  (F) _6 :  [frange] double [0.0 (0x0.0p+0),
1.79769313486231570814527423731704356798070567525844996599e+308
(0x0.fffffffffffff8p+1024)]
it doesn't do the extra step of figuring out that when _4 on the 2->4 edge must
be 0,
then _8 on that edge must be 1.
And, the finite range say for _6 or x_3(D) isn't stored into global state (if
there would be say some possibly not returning call between _6 definition and
uses or
for x_3(D) between start of function and the uses, we obviously couldn't store
it as a global range; in this case we could if we proved that isn't possible,
i.e. that if the function is reached then return _8; is reached too).
And then during vrp1 the same problem and __builtin_unreachable () is removed
with nothing noted anywhere.
Andrew, any thoughts?

Reply via email to