https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125641
--- Comment #5 from Drea Pinski <pinskia at gcc dot gnu.org> --- Comment on attachment 64664 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64664 Untested patch >diff --git a/gcc/match.pd b/gcc/match.pd >index 14567d8a1f1..10e57dcafc4 100644 >--- a/gcc/match.pd >+++ b/gcc/match.pd >@@ -5028,6 +5028,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (op @0 { build_int_cst (TREE_TYPE (@1), prec - 1); }))) > (op @0 { build_int_cst (TREE_TYPE (@1), low); }))))))) > >+/* Fold x | (~ (x >> (TYPE_PRECISION (type) - 1))) to max (x, -1) >+ Fold x | (x >> (TYPE_PRECISION (type) - 1)) to max (x, -1) >+ Fold x & (~ (x >> (TYPE_PRECISION (type) - 1))) to max (x, 0) >+ Fold x & (x >> (TYPE_PRECISION (type) - 1)) to max (x, 0) Typo in comments, the first and the last should be min. >+*/ >+#ifdef GIMPLE >+(simplify >+ (bit_ior:c @0 (bit_not (rshift @0 INTEGER_CST@1))) >+ (if (INTEGRAL_TYPE_P (type) >+ && !TYPE_UNSIGNED (type) >+ && wi::eq_p (wi::to_wide (@1), TYPE_PRECISION (type) - 1)) >+ (min @0 { build_int_cst (type, -1); }))) >+(simplify >+ (bit_ior:c @0 (rshift @0 INTEGER_CST@1)) >+ (if (INTEGRAL_TYPE_P (type) >+ && !TYPE_UNSIGNED (type) >+ && wi::eq_p (wi::to_wide (@1), TYPE_PRECISION (type) - 1)) >+ (max @0 { build_int_cst (type, -1); }))) >+(simplify >+ (bit_and:c @0 (bit_not (rshift @0 INTEGER_CST@1))) >+ (if (INTEGRAL_TYPE_P (type) >+ && !TYPE_UNSIGNED (type) >+ && wi::eq_p (wi::to_wide (@1), TYPE_PRECISION (type) - 1)) >+ (max @0 { build_zero_cst (type); }))) >+(simplify >+ (bit_and:c @0 (rshift @0 INTEGER_CST@1)) >+ (if (INTEGRAL_TYPE_P (type) >+ && !TYPE_UNSIGNED (type) >+ && wi::eq_p (wi::to_wide (@1), TYPE_PRECISION (type) - 1)) >+ (min @0 { build_zero_cst (type); }))) You can combine the set into 2 patterns using the following for loop. (for bitop (bit_ior bit_and) result (max min) rresult (min max) >+#endif >+ > /* Fold `1 >> a` into `a == 0` for scalar integral types. */ > (simplify > (rshift integer_onep @2)
