On Tue, 18 Jul 2017, Jakub Jelinek wrote:

+/* X / C1 op C2 into a simple range test.  */
+(for cmp (simple_comparison)
+ (simplify
+  (cmp (trunc_div:s @0 INTEGER_CST@1) INTEGER_CST@2)
+  (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && integer_nonzerop (@1)
+       && !TREE_OVERFLOW (@1)
+       && !TREE_OVERFLOW (@2))

(not specific to this patch)
I wonder if we should check TREE_OVERFLOW for the input that way in many
more transformations in match.pd, or never, or how to decide in which
cases to do it...

+   (with { tree lo, hi; bool neg_overflow;
+          enum tree_code code = fold_div_compare (cmp, @1, @2, &lo, &hi,
+                                                  &neg_overflow); }
+    (switch
+     (if (code == LT_EXPR || code == GE_EXPR)
+       (if (TREE_OVERFLOW (lo))
+       { build_int_cst (type, (code == LT_EXPR) ^ neg_overflow); }
+       (if (code == LT_EXPR)
+        (lt @0 { lo; })
+        (ge @0 { lo; }))))
+     (if (code == LE_EXPR || code == GT_EXPR)
+       (if (TREE_OVERFLOW (hi))
+       { build_int_cst (type, (code == LE_EXPR) ^ neg_overflow); }
+       (if (code == LE_EXPR)
+        (le @0 { hi; })
+        (gt @0 { hi; }))))
+     (if (!lo && !hi)
+      { build_int_cst (type, code == NE_EXPR); })
+     (if (code == EQ_EXPR && !hi)
+      (ge @0 { lo; }))
+     (if (code == EQ_EXPR && !lo)
+      (le @0 { hi; }))
+     (if (code == NE_EXPR && !hi)
+      (lt @0 { lo; }))
+     (if (code == NE_EXPR && !lo)
+      (gt @0 { hi; }))
+     (if (GENERIC)
+      { build_range_check (UNKNOWN_LOCATION, type, @0, code == EQ_EXPR,
+                          lo, hi); })
+     (with
+      {
+       tree etype = range_check_type (TREE_TYPE (@0));
+       if (etype)
+         {
+           if (! TYPE_UNSIGNED (etype))
+             etype = unsigned_type_for (etype);

Now that you enforce unsignedness, can you think of cases where going
through range_check_type is useful compared to
  tree etype = unsigned_type_for (TREE_TYPE (@0));
? I can propose that trivial patch as a follow-up if you like.

+           hi = fold_convert (etype, hi);
+           lo = fold_convert (etype, lo);
+           hi = const_binop (MINUS_EXPR, etype, hi, lo);
+         }
+      }
+      (if (etype && hi && !TREE_OVERFLOW (hi))

I don't think you can have an overflow here anymore, now that etype is
always unsigned and since you check the input (doesn't hurt though).

+       (if (code == EQ_EXPR)
+       (le (minus (convert:etype @0) { lo; }) { hi; })
+       (gt (minus (convert:etype @0) { lo; }) { hi; })))))))))

--
Marc Glisse

Reply via email to