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.

Reply via email to