Hello,

Le 18/10/2024 à 18:48, Richard Sandiford a écrit :
[+ranger folks, who I forgot to CC originally, sorry!]

This patch applies X /[ex] Y cmp Z -> X cmp (Y * Z) when Y * Z is
representable.
(...)

diff --git a/gcc/match.pd b/gcc/match.pd
index b952225b08c..1b1d38cf105 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2679,6 +2679,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        (le (minus (convert:etype @0) { lo; }) { hi; })
        (gt (minus (convert:etype @0) { lo; }) { hi; })))))))))
+#if GIMPLE
+/* X /[ex] Y cmp Z -> X cmp (Y * Z), if Y * Z is representable.  */
+(for cmp (simple_comparison)
+ (simplify
+  (cmp (exact_div:s @0 @1) @2)
+  (with { int_range_max r1, r2; }
+   (if (INTEGRAL_TYPE_P (type)
+       && get_range_query (cfun)->range_of_expr (r1, @1)
+       && get_range_query (cfun)->range_of_expr (r2, @2)
+       && range_op_handler (MULT_EXPR).fits_type_p (r1, r2))
+    (cmp @0 (mult @1 @2)))))
+ (simplify
+  (cmp @2 (exact_div:s @0 @1))
+  (with { int_range_max r1, r2; }
+   (if (INTEGRAL_TYPE_P (type)
+       && get_range_query (cfun)->range_of_expr (r1, @1)
+       && get_range_query (cfun)->range_of_expr (r2, @2)
+       && range_op_handler (MULT_EXPR).fits_type_p (r1, r2))
+    (cmp (mult @1 @2) @0)))))
+#endif
+

I think a condition is missing to make sure that Y is positive. Or for ordering comparisons with negative Y, the comparison should be inverted after the transformation (or the operands swapped).

Also note that there are existing cases of this transform around line 7300.

HTH

Reply via email to