From 5711ac884b3d7992b44aa848e980cebe5b4b93d0 Mon Sep 17 00:00:00 2001 From: "Naveen H.S" Date: Thu, 12 Nov 2015 05:34:54 +0000 Subject: [PATCH] fold-const.c (fold_binary_loc): Move Convert A/B/C to A/(B*C) to match.pd. 2015-11-12 Naveen H.S * fold-const.c (fold_binary_loc) : Move Convert A/B/C to A/(B*C) to match.pd. Move Convert A/(B/C) to (A/B)*C to match.pd. Move Convert C1/(X*C2) into (C1/C2)/X to match.pd. Move Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) to match.pd. * match.pd (rdiv (rdiv:s @0 @1) @2): New simplifier. (rdiv @0 (rdiv:s @1 @2)): New simplifier. (div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2): New simplifier. (rdiv REAL_CST@0 (mult @1 REAL_CST@2)): New simplifier. From-SVN: r230204 --- gcc/ChangeLog | 15 +++++++++++++++ gcc/fold-const.c | 45 --------------------------------------------- gcc/match.pd | 31 +++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 91ad0996d22..5c0d9f67ad8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2015-11-12 Naveen H.S + + * fold-const.c (fold_binary_loc) : Move Convert A/B/C to A/(B*C) + to match.pd. + Move Convert A/(B/C) to (A/B)*C to match.pd. + Move Convert C1/(X*C2) into (C1/C2)/X to match.pd. + Move Optimize (X & (-A)) / A where A is a power of 2, to + X >> log2(A) to match.pd. + + * match.pd (rdiv (rdiv:s @0 @1) @2): New simplifier. + (rdiv @0 (rdiv:s @1 @2)): New simplifier. + (div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2): + New simplifier. + (rdiv REAL_CST@0 (mult @1 REAL_CST@2)): New simplifier. + 2015-11-12 Charles Baylis * config/arm/neon.md: (neon_vld2_lane): Remove unused max diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 8dc849c3606..9114dec074a 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10195,54 +10195,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 f6c5c07b681..d552bebdafe 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -247,6 +247,28 @@ 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 (trunc_div ceil_div floor_div round_div exact_div) + (simplify + (div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2) + (if (integer_pow2p (@2) + && tree_int_cst_sgn (@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 +486,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))) -- 2.30.2