Hi, Please find attached the remaining part of patch.
Tested the patch on AArch64 and X86 without any regressions. Please review the patch and let me know if any modifications are required. Thanks, Naveen ChangeLog 2015-08-25 Naveen H.S <naveen.hurugalaw...@caviumnetworks.com> * fold-const.c (fold_binary_loc) : Move Optimize root(x)*root(y) as root(x*y) to match.pd. Move Optimize expN(x)*expN(y) as expN(x+y) to match.pd. Move Optimize pow(x,y)*pow(x,z) as pow(x,y+z) to match.pd. Move Optimize a/root(b/c) into a*root(c/b) to match.pd. Move Optimize x/expN(y) into x*expN(-y) to match.pd. * match.pd (mult (root:s @0) (root:s @1)): New simplifier. (mult (POW:s @0 @1) (POW:s @0 @2)) : New simplifier. (mult (exps:s @0) (exps:s @1)) : New simplifier. (rdiv @0 (root:s (rdiv:s @1 @2))) : New simplifier. (rdiv @0 (exps:s @1)) : New simplifier.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 1e01726..c826e67 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -9947,51 +9947,6 @@ fold_binary_loc (location_t loc, if (flag_unsafe_math_optimizations) { - enum built_in_function fcode0 = builtin_mathfn_code (arg0); - enum built_in_function fcode1 = builtin_mathfn_code (arg1); - - /* Optimizations of root(...)*root(...). */ - if (fcode0 == fcode1 && BUILTIN_ROOT_P (fcode0)) - { - tree rootfn, arg; - tree arg00 = CALL_EXPR_ARG (arg0, 0); - tree arg10 = CALL_EXPR_ARG (arg1, 0); - - /* Optimize root(x)*root(y) as root(x*y). */ - rootfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0); - arg = fold_build2_loc (loc, MULT_EXPR, type, arg00, arg10); - return build_call_expr_loc (loc, rootfn, 1, arg); - } - - /* Optimize expN(x)*expN(y) as expN(x+y). */ - if (fcode0 == fcode1 && BUILTIN_EXPONENT_P (fcode0)) - { - tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0); - tree arg = fold_build2_loc (loc, PLUS_EXPR, type, - CALL_EXPR_ARG (arg0, 0), - CALL_EXPR_ARG (arg1, 0)); - return build_call_expr_loc (loc, expfn, 1, arg); - } - - /* Optimizations of pow(...)*pow(...). */ - if ((fcode0 == BUILT_IN_POW && fcode1 == BUILT_IN_POW) - || (fcode0 == BUILT_IN_POWF && fcode1 == BUILT_IN_POWF) - || (fcode0 == BUILT_IN_POWL && fcode1 == BUILT_IN_POWL)) - { - tree arg00 = CALL_EXPR_ARG (arg0, 0); - tree arg01 = CALL_EXPR_ARG (arg0, 1); - tree arg10 = CALL_EXPR_ARG (arg1, 0); - tree arg11 = CALL_EXPR_ARG (arg1, 1); - - /* Optimize pow(x,y)*pow(x,z) as pow(x,y+z). */ - if (operand_equal_p (arg00, arg10, 0)) - { - tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0); - tree arg = fold_build2_loc (loc, PLUS_EXPR, type, - arg01, arg11); - return build_call_expr_loc (loc, powfn, 2, arg00, arg); - } - } /* Canonicalize x*x as pow(x,2.0), which is expanded as x*x. */ if (!in_gimple_form @@ -10403,40 +10358,6 @@ fold_binary_loc (location_t loc, TREE_OPERAND (arg1, 0)); } - if (flag_unsafe_math_optimizations) - { - enum built_in_function fcode1 = builtin_mathfn_code (arg1); - - /* Optimize a/root(b/c) into a*root(c/b). */ - if (BUILTIN_CBRT_P (fcode1)) - { - tree rootarg = CALL_EXPR_ARG (arg1, 0); - - if (TREE_CODE (rootarg) == RDIV_EXPR) - { - tree rootfn = TREE_OPERAND (CALL_EXPR_FN (arg1), 0); - tree b = TREE_OPERAND (rootarg, 0); - tree c = TREE_OPERAND (rootarg, 1); - - tree tmp = fold_build2_loc (loc, RDIV_EXPR, type, c, b); - - tmp = build_call_expr_loc (loc, rootfn, 1, tmp); - return fold_build2_loc (loc, MULT_EXPR, type, arg0, tmp); - } - } - - /* Optimize x/expN(y) into x*expN(-y). */ - if (BUILTIN_EXPONENT_P (fcode1)) - { - tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg1), 0); - tree arg = negate_expr (CALL_EXPR_ARG (arg1, 0)); - arg1 = build_call_expr_loc (loc, - expfn, 1, - fold_convert_loc (loc, type, arg)); - return fold_build2_loc (loc, MULT_EXPR, type, arg0, arg1); - } - - } return NULL_TREE; case TRUNC_DIV_EXPR: diff --git a/gcc/match.pd b/gcc/match.pd index eb0ba9d..289bc5c 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2014,11 +2014,28 @@ along with GCC; see the file COPYING3. If not see (if (!HONOR_SNANS (type)) @0)) + /* Simplify sqrt(x) * sqrt(y) -> sqrt(x*y). */ + (for root (SQRT CBRT) + (simplify + (mult (root:s @0) (root:s @1)) + (root (mult @0 @1)))) + + /* Simplify pow(x,y) * pow(x,z) -> pow(x,y+z). */ + (simplify + (mult (POW:s @0 @1) (POW:s @0 @2)) + (POW @0 (plus @1 @2))) + /* Simplify pow(x,y) * pow(z,y) -> pow(x*z,y). */ (simplify (mult (POW:s @0 @1) (POW:s @2 @1)) (POW (mult @0 @2) @1)) + /* Simplify expN(x) * expN(y) -> expN(x+y). */ + (for exps (EXP EXP2 EXP10 POW10) + (simplify + (mult (exps:s @0) (exps:s @1)) + (exps (plus @0 @1)))) + /* Simplify tan(x) * cos(x) -> sin(x). */ (simplify (mult:c (TAN:s @0) (COS:s @0)) @@ -2061,9 +2078,16 @@ along with GCC; see the file COPYING3. If not see (POW @0 (minus @1 { build_one_cst (type); })))) /* Simplify a/root(b/c) into a*root(c/b). */ - (simplify - (rdiv @0 (SQRT:s (rdiv:s @1 @2))) - (mult @0 (SQRT (rdiv @2 @1)))) + (for root (SQRT CBRT) + (simplify + (rdiv @0 (root:s (rdiv:s @1 @2))) + (mult @0 (root (rdiv @2 @1))))) + + /* Simplify x/expN(y) into x*expN(-y). */ + (for exps (EXP EXP2 EXP10 POW10) + (simplify + (rdiv @0 (exps:s @1)) + (mult @0 (exps (negate @1))))) /* Simplify x / pow (y,z) -> x * pow(y,-z). */ (simplify