https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110992
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> --- What we had before in GCC 13: # RANGE [irange] unsigned short [0, 1] NONZERO 0x1 d.3_19 = (unsigned short) _3; _21 = -d.3_19; _22 = (short intD.17) _21; _6 = (short intD.17) b.0_1; _7 = _6 & _22; Which then after r14-1654-g7ceed7e3e29 gives us: _t = (short intD.17) d.3_19 _7 = _6 * _t What we get after that match patch: _3 = c.1_2 != 0; _25 = (short intD.17) _3; _22 = -_25; _6 = (short intD.17) b.0_1; _7 = _6 & _22; That is we lose the range information. If I add this to match.pd: ``` diff --git a/gcc/match.pd b/gcc/match.pd index 97db0eb5f25..e68e2c57e25 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2181,6 +2181,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && (TYPE_UNSIGNED (type) || TYPE_PRECISION (type) > 1)))) +(match zero_one_valued_p + (convert@0 zero_one_valued_p@1)) + /* Transform { 0 or 1 } * { 0 or 1 } into { 0 or 1 } & { 0 or 1 }. */ (simplify (mult zero_one_valued_p@0 zero_one_valued_p@1) ``` Then this fails again. I am thinking about adding this anyways so I am going to keep this one open.