Hello,if we compare for instance size() and capacity() for a std::vector, we get this kind of pattern. I started with just nop conversions and got a bit carried away handling all those cases.
Bootstrap+regtest on x86_64-pc-linux-gnu. 2019-06-11 Marc Glisse <marc.gli...@inria.fr> gcc/ * match.pd (X/[ex]4<Y/[ex]4): Handle conversions. gcc/testsuite/ * gcc.dg/tree-ssa/cmpexactdiv-5.c: New file. -- Marc Glisse
Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 272105) +++ gcc/match.pd (working copy) @@ -1496,25 +1496,40 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && TYPE_UNSIGNED (TREE_TYPE (@0)) && TYPE_PRECISION (TREE_TYPE (@0)) > 1 && (wi::to_wide (@2) == wi::max_value (TYPE_PRECISION (TREE_TYPE (@0)), SIGNED) - 1)) (with { tree stype = signed_type_for (TREE_TYPE (@0)); } (icmp (convert:stype @0) { build_int_cst (stype, 0); }))))) /* X / 4 < Y / 4 iff X < Y when the division is known to be exact. */ (for cmp (simple_comparison) (simplify - (cmp (exact_div @0 INTEGER_CST@2) (exact_div @1 @2)) - (if (wi::gt_p (wi::to_wide (@2), 0, TYPE_SIGN (TREE_TYPE (@2)))) - (cmp @0 @1) + (cmp (convert?@3 (exact_div @0 INTEGER_CST@2)) (convert? (exact_div @1 @2))) + (if (element_precision (TREE_TYPE (@3)) >= element_precision (TREE_TYPE (@0)) + && types_match (TREE_TYPE (@0), TREE_TYPE (@1))) (if (wi::lt_p (wi::to_wide (@2), 0, TYPE_SIGN (TREE_TYPE (@2)))) - (cmp @1 @0))))) + (if (!TYPE_UNSIGNED (TREE_TYPE (@3))) + (cmp @1 @0) + (if (tree_expr_nonzero_p (@0) && tree_expr_nonzero_p (@1)) + (with + { + tree utype = unsigned_type_for (TREE_TYPE (@0)); + } + (cmp (convert:utype @1) (convert:utype @0))))) + (if (wi::gt_p (wi::to_wide (@2), 1, TYPE_SIGN (TREE_TYPE (@2)))) + (if (TYPE_UNSIGNED (TREE_TYPE (@0)) || !TYPE_UNSIGNED (TREE_TYPE (@3))) + (cmp @0 @1) + (with + { + tree utype = unsigned_type_for (TREE_TYPE (@0)); + } + (cmp (convert:utype @0) (convert:utype @1))))))))) /* 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)) (with { tree lo, hi; bool neg_overflow; Index: gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv-5.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv-5.c (nonexistent) +++ gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv-5.c (working copy) @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized-raw" } */ + +int f(int *a, int *b, int *c){ + if(sizeof(__SIZE_TYPE__) != sizeof(__PTRDIFF_TYPE__)) return 2; + __SIZE_TYPE__ s = b - a; + __SIZE_TYPE__ t = c - a; + return s < t; +} + +/* { dg-final { scan-tree-dump-not "exact_div_expr" "optimized" } } */