https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120031
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- diff --git a/gcc/match.pd b/gcc/match.pd index 2a63e4c7ddb..6edd7deb6c2 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -11298,7 +11298,7 @@ and, in the top 5 or 6 bits. This is then indexed into a table which maps it to the number of trailing zeroes. */ (match (ctz_table_index @1 @2 @3) - (rshift (mult (bit_and:c (negate @1) @1) INTEGER_CST@2) INTEGER_CST@3)) + (rshift (mult (bit_and:c (nop_convert? (negate (nop_convert? @1))) @1) INTEGER_CST@2) INTEGER_CST@3)) (match (cond_expr_convert_p @0 @2 @3 @6) (cond (simple_comparison@6 @0 @1) (convert@4 @2) (convert@5 @3)) fixes this case but I wonder whether we should simply transform (unsigned)-(signed)x to -x? Yes, we lose the fact that x is not (unsigned)INT_MIN, but so what.