https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110503
--- Comment #11 from rguenther at suse dot de <rguenther at suse dot de> --- On Fri, 14 Feb 2025, pinskia at gcc dot gnu.org wrote: > 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. Note this means VRP fails to fold stmts it creates (even though it is one of the passes folding all stmts (but only following single-use defs).