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

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #4)
> As for the original issue:
>   x.0_5 = (unsigned int) x_2(D);
>   _6 = -x.0_5;
>   _7 = _6 >> 31;
>   _8 = (int) _7;
> 
> We have a pattern for basically this:
> /* Fold (-x >> C) into -(x > 0) where C = precision(type) - 1.  */
> 
> But only for !TYPE_UNSIGNED here. we can do it for unsigned where we just
> get x > 0 instead.

I have a patch which gets us to:
  # RANGE [irange] int [-1, 0]
  _3 = x_2(D) >> 31;
  _5 = x_2(D) > 0;
  # RANGE [irange] int [0, 1] MASK 0x1 VALUE 0x0
  _6 = (intD.9) _5;
  # RANGE [irange] int [-1, 1]
  _7 = _3 | _6;
  _4 = _7 != 1;

(_3 | _6) != 1 means !((_3 == 0) && (_6 == 1)) since _3 can't be 1 at all.
(_3 == 0) is x >= 0 and _6 == 1 is `x > 0` and that combines to be just `x >=
0` .

I think the above only works if the two ranges in the _3|_6 is [-1,0] and [1,0]
.


(_3 | _6) == -1 just means _3 == -1 even which we don't handle either (and
would be simplier to handle than other cases).

Reply via email to