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