This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
More Division optimization using match and simplify
- From: "Hurugalawadi, Naveen" <Naveen dot Hurugalawadi at caviumnetworks dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 17 Nov 2015 06:22:24 +0000
- Subject: More Division optimization using match and simplify
- Authentication-results: sourceware.org; auth=none
- Authentication-results: spf=none (sender IP is ) smtp dot mailfrom=Naveen dot Hurugalawadi at caviumnetworks dot com;
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:23
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.Hurugalawadi@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