Hi, Please find attached the patch that moves some more division optimizations from fold-const using match and simplify.
Please review the patch and let me know if any modifications are required. Hopefully got the converts right this time :-) Regression tested the patch on X86 without any issues. Thanks, Naveen ChangeLog 2015-11-17 Naveen H.S <naveen.hurugalaw...@caviumnetworks.com> * fold-const.c (fold_binary_loc) : Move Simplify A / (B << N) where A and B are positive and B is a power of 2, to A >> (N + log2(B)) to match.pd. Move If arg0 is a multiple of arg1, then rewrite to the fastest div operation, EXACT_DIV_EXPR to match.pd. * match.pd (floor_div (convert? @0) (lshift @1 INTEGER_CST@2)): New simplifier. (div (convert? @0) (convert? @1)): New simplifier.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index ce59c48..0c72a75 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10220,32 +10220,6 @@ fold_binary_loc (location_t loc, /* Fall through */ case FLOOR_DIV_EXPR: - /* Simplify A / (B << N) where A and B are positive and B is - a power of 2, to A >> (N + log2(B)). */ - strict_overflow_p = false; - if (TREE_CODE (arg1) == LSHIFT_EXPR - && (TYPE_UNSIGNED (type) - || tree_expr_nonnegative_warnv_p (op0, &strict_overflow_p))) - { - tree sval = TREE_OPERAND (arg1, 0); - if (integer_pow2p (sval) && tree_int_cst_sgn (sval) > 0) - { - tree sh_cnt = TREE_OPERAND (arg1, 1); - tree pow2 = build_int_cst (TREE_TYPE (sh_cnt), - wi::exact_log2 (sval)); - - if (strict_overflow_p) - fold_overflow_warning (("assuming signed overflow does not " - "occur when simplifying A / (B << N)"), - WARN_STRICT_OVERFLOW_MISC); - - sh_cnt = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (sh_cnt), - sh_cnt, pow2); - return fold_build2_loc (loc, RSHIFT_EXPR, type, - fold_convert_loc (loc, type, arg0), sh_cnt); - } - } - /* Fall through */ case ROUND_DIV_EXPR: @@ -10287,18 +10261,6 @@ fold_binary_loc (location_t loc, TREE_OPERAND (arg1, 0))); } - /* If arg0 is a multiple of arg1, then rewrite to the fastest div - operation, EXACT_DIV_EXPR. - - Note that only CEIL_DIV_EXPR and FLOOR_DIV_EXPR are rewritten now. - At one time others generated faster code, it's not clear if they do - after the last round to changes to the DIV code in expmed.c. */ - if ((code == CEIL_DIV_EXPR || code == FLOOR_DIV_EXPR) - && multiple_of_p (type, arg0, arg1)) - return fold_build2_loc (loc, EXACT_DIV_EXPR, type, - fold_convert (type, arg0), - fold_convert (type, arg1)); - strict_overflow_p = false; if (TREE_CODE (arg1) == INTEGER_CST && 0 != (tem = extract_muldiv (op0, arg1, code, NULL_TREE, diff --git a/gcc/match.pd b/gcc/match.pd index d552beb..5ca2778 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -269,6 +269,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (rshift (convert @0) { build_int_cst (integer_type_node, wi::exact_log2 (@2)); })))) +/* Simplify A / (B << N) where A and B are positive and B is a power of 2, + to A >> (N + log2(B)). */ +(simplify + (floor_div (convert? @0) (lshift @1 INTEGER_CST@2)) + (if ((TYPE_UNSIGNED (type) + || tree_expr_nonnegative_warnv_p (@0, NULL)) + && integer_pow2p (@1) + && tree_int_cst_sgn (@1) > 0 + && tree_nop_conversion_p (type, TREE_TYPE (@0))) + (with + { tree pow2 = build_int_cst (TREE_TYPE (@2), wi::exact_log2 (@1)); + tree temp = const_binop (PLUS_EXPR, TREE_TYPE (@2), @2, pow2); } + (rshift (convert @0) { temp; })))) + +/* Convert A/B to A/B */ +(for div (CEIL_DIV_EXPR FLOOR_DIV_EXPR) + (simplify + (div (convert? @0) (convert? @1)) + (if (wi::multiple_of_p (@0, @1, TYPE_SIGN (type))) + (exact_div (convert @0) (convert @1))))) + /* If ARG1 is a constant, we can convert this to a multiply by the reciprocal. This does not have the same rounding properties, so only do this if -freciprocal-math. We can actually