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

--- Comment #10 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
One thing we should note is that VRP and forwprop go and forth between:
```
  # RANGE [irange] int [0, 1]
  _11 = 1 % _10;
  _3 = (unsigned int) _11;
  # RANGE [irange] unsigned int [0, 0][+INF, +INF]
  _14 = _3 + 4294967295;
```

and
```
  _11 = 1 % _10;
  _17 = _11 == 0;
  # RANGE [irange] unsigned int [0, 1] MASK 0x1 VALUE 0x0
  _16 = (unsigned int) _17;
  # RANGE [irange] unsigned int [0, 0][+INF, +INF]
  _14 = -_16;
```

Due to:
```
/* -(type)!A -> (type)A - 1.  */
(simplify
 (negate (convert?:s (logical_inverted_value:s @0)))
 (if (INTEGRAL_TYPE_P (type)
      && TREE_CODE (type) != BOOLEAN_TYPE
      && TYPE_PRECISION (type) > 1
      && TREE_CODE (@0) == SSA_NAME
      && ssa_name_has_boolean_range (@0))
  (plus (convert:type @0) { build_all_ones_cst (type); })))
```

And VRP changing `_3 + 4294967295` into `_3 == 0 ? -1 : 0` which then gets
match and simplified into:
gimple_simplified to _13 = (unsigned int) _11;
_5 = -_13;

The only thing stopping match and simplify from turning it back into what it 
was originally (before VRP) is due to the use of ssa_name_has_boolean_range
here as there is no range for _11 just yet. If we add `1 % _10` into `_10 !=
1`, then it won't go back and forth either.

Reply via email to