This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Division Optimization in match and simplify
- From: "Hurugalawadi, Naveen" <Naveen dot Hurugalawadi at caviumnetworks dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: "marc dot glisse at inria dot fr" <marc dot glisse at inria dot fr>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 5 Nov 2015 05:30:15 +0000
- Subject: Re: Division Optimization in 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;
- References: <BLUPR0701MB10112FDAF6046909BE252FFB8E2A0 at BLUPR0701MB1011 dot namprd07 dot prod dot outlook dot com> <alpine dot DEB dot 2 dot 20 dot 1511040920400 dot 2317 at laptop-mg dot saclay dot inria dot fr> <BLUPR0701MB10110152D9B362818EB337668E2A0 at BLUPR0701MB1011 dot namprd07 dot prod dot outlook dot com> <alpine dot DEB dot 2 dot 20 dot 1511041155570 dot 2317 at laptop-mg dot saclay dot inria dot fr>,<CAFiYyc172oRzH6H8dNP0E5mbEcN5GVGF1ujoWtUvDUV0TBQkcw at mail dot gmail dot com>
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:23
Hi,
Please find attached the modified patch as per review comments.
>> use :s on both inner rdiv in both patterns. With that the two patterns are ok.
Done.
>> Omit the parens around REAL_CST@0
Done.
Regression tested on X86_64.
Thanks,
Naveen
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index ee9b349..88dbbdd 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -10163,54 +10163,9 @@ fold_binary_loc (location_t loc,
return fold_build2_loc (loc, RDIV_EXPR, type,
negate_expr (arg0),
TREE_OPERAND (arg1, 0));
-
- /* Convert A/B/C to A/(B*C). */
- if (flag_reciprocal_math
- && TREE_CODE (arg0) == RDIV_EXPR)
- return fold_build2_loc (loc, RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
- fold_build2_loc (loc, MULT_EXPR, type,
- TREE_OPERAND (arg0, 1), arg1));
-
- /* Convert A/(B/C) to (A/B)*C. */
- if (flag_reciprocal_math
- && TREE_CODE (arg1) == RDIV_EXPR)
- return fold_build2_loc (loc, MULT_EXPR, type,
- fold_build2_loc (loc, RDIV_EXPR, type, arg0,
- TREE_OPERAND (arg1, 0)),
- TREE_OPERAND (arg1, 1));
-
- /* Convert C1/(X*C2) into (C1/C2)/X. */
- if (flag_reciprocal_math
- && TREE_CODE (arg1) == MULT_EXPR
- && TREE_CODE (arg0) == REAL_CST
- && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
- {
- tree tem = const_binop (RDIV_EXPR, arg0,
- TREE_OPERAND (arg1, 1));
- if (tem)
- return fold_build2_loc (loc, RDIV_EXPR, type, tem,
- TREE_OPERAND (arg1, 0));
- }
-
return NULL_TREE;
case TRUNC_DIV_EXPR:
- /* Optimize (X & (-A)) / A where A is a power of 2,
- to X >> log2(A) */
- if (TREE_CODE (arg0) == BIT_AND_EXPR
- && !TYPE_UNSIGNED (type) && TREE_CODE (arg1) == INTEGER_CST
- && integer_pow2p (arg1) && tree_int_cst_sgn (arg1) > 0)
- {
- tree sum = fold_binary_loc (loc, PLUS_EXPR, TREE_TYPE (arg1),
- arg1, TREE_OPERAND (arg0, 1));
- if (sum && integer_zerop (sum)) {
- tree pow2 = build_int_cst (integer_type_node,
- wi::exact_log2 (arg1));
- return fold_build2_loc (loc, RSHIFT_EXPR, type,
- TREE_OPERAND (arg0, 0), pow2);
- }
- }
-
/* Fall through */
case FLOOR_DIV_EXPR:
diff --git a/gcc/match.pd b/gcc/match.pd
index f6c5c07..d11ad79 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -247,6 +247,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (!HONOR_SNANS (type))
(negate @0)))
+(if (flag_reciprocal_math)
+ /* Convert (A/B)/C to A/(B*C) */
+ (simplify
+ (rdiv (rdiv:s @0 @1) @2)
+ (rdiv @0 (mult @1 @2)))
+
+ /* Convert A/(B/C) to (A/B)*C */
+ (simplify
+ (rdiv @0 (rdiv:s @1 @2))
+ (mult (rdiv @0 @1) @2)))
+
+/* Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) */
+(for div (exact_div trunc_div)
+ (simplify
+ (div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2)
+ (if (integer_pow2p (@2)
+ && tree_int_cst_sign_bit (@2) == 0
+ && wi::add (@2, @1) == 0
+ && tree_nop_conversion_p (type, TREE_TYPE (@0)))
+ (rshift (convert @0) { build_int_cst (integer_type_node, wi::exact_log2 (@2)); }))))
+
/* 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
@@ -464,6 +485,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (tem)
(rdiv { tem; } @1)))))
+/* Convert C1/(X*C2) into (C1/C2)/X */
+(simplify
+ (rdiv REAL_CST@0 (mult @1 REAL_CST@2))
+ (if (flag_reciprocal_math)
+ (with
+ { tree tem = const_binop (RDIV_EXPR, type, @0, @2); }
+ (if (tem)
+ (rdiv { tem; } @1)))))
+
/* Simplify ~X & X as zero. */
(simplify
(bit_and:c (convert? @0) (convert? (bit_not @0)))