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