https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95424
--- Comment #3 from Zhao Wei Liew <zhaoweiliew at gmail dot com> --- Comment on attachment 52097 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52097 Optimization for both unsigned and signed integer X diff --git a/gcc/match.pd b/gcc/match.pd index 0d7b8dd1334..6fbf1071a97 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -349,6 +349,23 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (op @0 integer_onep) (non_lvalue @0))) +/* 1 / X -> X == 1 for unsigned integer X + 1 / X -> X >= -1 && X <= 1 ? X : 0 for signed integer X */ +(for div (trunc_div ceil_div floor_div round_div exact_div) + (simplify + (div integer_onep@0 @1) + (switch + /* 1 / X -> X == 1 for unsigned integer X */ + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@1)) + && TYPE_UNSIGNED (TREE_TYPE (@1))) + (eq @0 @1)) + /* 1 / X -> X >= -1 && X <= 1 ? X : 0 for signed integer X */ + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@1)) + && !TYPE_UNSIGNED (TREE_TYPE (@1))) + (cond (bit_and (ge @1 { build_minus_one_cst (integer_type_node); }) + (le @1 { build_one_cst (integer_type_node); })) + @1 { build_zero_cst (type); }))))) + /* (A / (1 << B)) -> (A >> B). Only for unsigned A. For signed A, this would not preserve rounding toward zero.