On Thu, Oct 15, 2015 at 3:28 PM, Richard Sandiford <richard.sandif...@arm.com> wrote: > This patch deletes fold_strip_sign_ops in favour of the tree-ssa-backprop.c > pass. > > Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi. > OK to install?
Ok once the pass goes in. Thanks, Richard. > Thanks, > Richard > > > gcc/ > * fold-const.h (fold_strip_sign_ops): Delete. > * fold-const.c (fold_strip_sign_ops): Likewise. > (fold_unary_loc, fold_binary_loc): Remove calls to it. > * builtins.c (fold_builtin_cos, fold_builtin_cosh) > (fold_builtin_ccos): Delete. > (fold_builtin_pow): Don't call fold_strip_sign_ops. > (fold_builtin_hypot, fold_builtin_copysign): Likewise. > Remove fndecl argument. > (fold_builtin_1): Update calls accordingly. Handle constant > cos, cosh, ccos and ccosh here. > > gcc/testsuite/ > * gcc.dg/builtins-86.c: XFAIL. > * gcc.dg/torture/builtin-symmetric-1.c: Don't run at -O0. > > diff --git a/gcc/builtins.c b/gcc/builtins.c > index b4ac535..1e4ec35 100644 > --- a/gcc/builtins.c > +++ b/gcc/builtins.c > @@ -160,8 +160,6 @@ static rtx expand_builtin_fabs (tree, rtx, rtx); > static rtx expand_builtin_signbit (tree, rtx); > static tree fold_builtin_pow (location_t, tree, tree, tree, tree); > static tree fold_builtin_powi (location_t, tree, tree, tree, tree); > -static tree fold_builtin_cos (location_t, tree, tree, tree); > -static tree fold_builtin_cosh (location_t, tree, tree, tree); > static tree fold_builtin_tan (tree, tree); > static tree fold_builtin_trunc (location_t, tree, tree); > static tree fold_builtin_floor (location_t, tree, tree); > @@ -7688,77 +7686,6 @@ fold_builtin_cproj (location_t loc, tree arg, tree > type) > return NULL_TREE; > } > > -/* Fold function call to builtin cos, cosf, or cosl with argument ARG. > - TYPE is the type of the return value. Return NULL_TREE if no > - simplification can be made. */ > - > -static tree > -fold_builtin_cos (location_t loc, > - tree arg, tree type, tree fndecl) > -{ > - tree res, narg; > - > - if (!validate_arg (arg, REAL_TYPE)) > - return NULL_TREE; > - > - /* Calculate the result when the argument is a constant. */ > - if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0))) > - return res; > - > - /* Optimize cos(-x) into cos (x). */ > - if ((narg = fold_strip_sign_ops (arg))) > - return build_call_expr_loc (loc, fndecl, 1, narg); > - > - return NULL_TREE; > -} > - > -/* Fold function call to builtin cosh, coshf, or coshl with argument ARG. > - Return NULL_TREE if no simplification can be made. */ > - > -static tree > -fold_builtin_cosh (location_t loc, tree arg, tree type, tree fndecl) > -{ > - if (validate_arg (arg, REAL_TYPE)) > - { > - tree res, narg; > - > - /* Calculate the result when the argument is a constant. */ > - if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0))) > - return res; > - > - /* Optimize cosh(-x) into cosh (x). */ > - if ((narg = fold_strip_sign_ops (arg))) > - return build_call_expr_loc (loc, fndecl, 1, narg); > - } > - > - return NULL_TREE; > -} > - > -/* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with > - argument ARG. TYPE is the type of the return value. Return > - NULL_TREE if no simplification can be made. */ > - > -static tree > -fold_builtin_ccos (location_t loc, tree arg, tree type, tree fndecl, > - bool hyper) > -{ > - if (validate_arg (arg, COMPLEX_TYPE) > - && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE) > - { > - tree tmp; > - > - /* Calculate the result when the argument is a constant. */ > - if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos)))) > - return tmp; > - > - /* Optimize fn(-x) into fn(x). */ > - if ((tmp = fold_strip_sign_ops (arg))) > - return build_call_expr_loc (loc, fndecl, 1, tmp); > - } > - > - return NULL_TREE; > -} > - > /* Fold function call to builtin tan, tanf, or tanl with argument ARG. > Return NULL_TREE if no simplification can be made. */ > > @@ -8174,10 +8101,9 @@ fold_builtin_bswap (tree fndecl, tree arg) > NULL_TREE if no simplification can be made. */ > > static tree > -fold_builtin_hypot (location_t loc, tree fndecl, > - tree arg0, tree arg1, tree type) > +fold_builtin_hypot (location_t loc, tree arg0, tree arg1, tree type) > { > - tree res, narg0, narg1; > + tree res; > > if (!validate_arg (arg0, REAL_TYPE) > || !validate_arg (arg1, REAL_TYPE)) > @@ -8187,16 +8113,6 @@ fold_builtin_hypot (location_t loc, tree fndecl, > if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot))) > return res; > > - /* If either argument to hypot has a negate or abs, strip that off. > - E.g. hypot(-x,fabs(y)) -> hypot(x,y). */ > - narg0 = fold_strip_sign_ops (arg0); > - narg1 = fold_strip_sign_ops (arg1); > - if (narg0 || narg1) > - { > - return build_call_expr_loc (loc, fndecl, 2, narg0 ? narg0 : arg0, > - narg1 ? narg1 : arg1); > - } > - > /* If either argument is zero, hypot is fabs of the other. */ > if (real_zerop (arg0)) > return fold_build1_loc (loc, ABS_EXPR, type, arg1); > @@ -8301,14 +8217,6 @@ fold_builtin_pow (location_t loc, tree fndecl, tree > arg0, tree arg1, tree type) > if (flag_unsafe_math_optimizations || !inexact) > return build_real (type, x); > } > - > - /* Strip sign ops from even integer powers. */ > - if ((n & 1) == 0 && flag_unsafe_math_optimizations) > - { > - tree narg0 = fold_strip_sign_ops (arg0); > - if (narg0) > - return build_call_expr_loc (loc, fndecl, 2, narg0, arg1); > - } > } > } > > @@ -8756,11 +8664,8 @@ fold_builtin_signbit (location_t loc, tree arg, tree > type) > be made. */ > > static tree > -fold_builtin_copysign (location_t loc, tree fndecl, > - tree arg1, tree arg2, tree type) > +fold_builtin_copysign (location_t loc, tree arg1, tree arg2, tree type) > { > - tree tem; > - > if (!validate_arg (arg1, REAL_TYPE) > || !validate_arg (arg2, REAL_TYPE)) > return NULL_TREE; > @@ -8791,11 +8696,6 @@ fold_builtin_copysign (location_t loc, tree fndecl, > fold_build1_loc (loc, ABS_EXPR, type, arg1), > arg2); > > - /* Strip sign changing operations for the first argument. */ > - tem = fold_strip_sign_ops (arg1); > - if (tem) > - return build_call_expr_loc (loc, fndecl, 2, tem, arg2); > - > return NULL_TREE; > } > > @@ -9696,10 +9596,16 @@ fold_builtin_1 (location_t loc, tree fndecl, tree > arg0) > break; > > CASE_FLT_FN (BUILT_IN_CCOS): > - return fold_builtin_ccos (loc, arg0, type, fndecl, /*hyper=*/ false); > + if (validate_arg (arg0, COMPLEX_TYPE) > + && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) > + return do_mpc_arg1 (arg0, type, mpc_cos); > + break; > > CASE_FLT_FN (BUILT_IN_CCOSH): > - return fold_builtin_ccos (loc, arg0, type, fndecl, /*hyper=*/ true); > + if (validate_arg (arg0, COMPLEX_TYPE) > + && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) > + return do_mpc_arg1 (arg0, type, mpc_cosh); > + break; > > CASE_FLT_FN (BUILT_IN_CPROJ): > return fold_builtin_cproj (loc, arg0, type); > @@ -9832,7 +9738,9 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0) > break; > > CASE_FLT_FN (BUILT_IN_COS): > - return fold_builtin_cos (loc, arg0, type, fndecl); > + if (validate_arg (arg0, REAL_TYPE)) > + return do_mpfr_arg1 (arg0, type, mpfr_cos, NULL, NULL, 0); > + break; > > CASE_FLT_FN (BUILT_IN_TAN): > return fold_builtin_tan (arg0, type); > @@ -9851,7 +9759,9 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0) > break; > > CASE_FLT_FN (BUILT_IN_COSH): > - return fold_builtin_cosh (loc, arg0, type, fndecl); > + if (validate_arg (arg0, REAL_TYPE)) > + return do_mpfr_arg1 (arg0, type, mpfr_cosh, NULL, NULL, 0); > + break; > > CASE_FLT_FN (BUILT_IN_TANH): > if (validate_arg (arg0, REAL_TYPE)) > @@ -10105,7 +10015,7 @@ fold_builtin_2 (location_t loc, tree fndecl, tree > arg0, tree arg1) > break; > > CASE_FLT_FN (BUILT_IN_HYPOT): > - return fold_builtin_hypot (loc, fndecl, arg0, arg1, type); > + return fold_builtin_hypot (loc, arg0, arg1, type); > > CASE_FLT_FN (BUILT_IN_CPOW): > if (validate_arg (arg0, COMPLEX_TYPE) > @@ -10161,7 +10071,7 @@ fold_builtin_2 (location_t loc, tree fndecl, tree > arg0, tree arg1) > return fold_builtin_powi (loc, fndecl, arg0, arg1, type); > > CASE_FLT_FN (BUILT_IN_COPYSIGN): > - return fold_builtin_copysign (loc, fndecl, arg0, arg1, type); > + return fold_builtin_copysign (loc, arg0, arg1, type); > > CASE_FLT_FN (BUILT_IN_FMIN): > return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false); > diff --git a/gcc/fold-const.c b/gcc/fold-const.c > index 7f00e72..5e945de 100644 > --- a/gcc/fold-const.c > +++ b/gcc/fold-const.c > @@ -7801,15 +7801,6 @@ fold_unary_loc (location_t loc, enum tree_code code, > tree type, tree op0) > TREE_TYPE (targ0), > targ0)); > } > - > - /* Strip sign ops from argument. */ > - if (TREE_CODE (type) == REAL_TYPE) > - { > - tem = fold_strip_sign_ops (arg0); > - if (tem) > - return fold_build1_loc (loc, ABS_EXPR, type, > - fold_convert_loc (loc, type, tem)); > - } > return NULL_TREE; > > case BIT_NOT_EXPR: > @@ -9896,17 +9887,6 @@ fold_binary_loc (location_t loc, > TREE_OPERAND (arg0, 1)); > } > > - /* Strip sign operations from X in X*X, i.e. -Y*-Y -> Y*Y. */ > - if (operand_equal_p (arg0, arg1, 0)) > - { > - tree tem = fold_strip_sign_ops (arg0); > - if (tem != NULL_TREE) > - { > - tem = fold_convert_loc (loc, type, tem); > - return fold_build2_loc (loc, MULT_EXPR, type, tem, tem); > - } > - } > - > /* Fold z * +-I to __complex__ (-+__imag z, +-__real z). > This is not the same for NaNs or if signed zeros are > involved. */ > @@ -14312,82 +14292,6 @@ ptr_difference_const (tree e1, tree e2, > HOST_WIDE_INT *diff) > return true; > } > > -/* Simplify the floating point expression EXP when the sign of the > - result is not significant. Return NULL_TREE if no simplification > - is possible. */ > - > -tree > -fold_strip_sign_ops (tree exp) > -{ > - tree arg0, arg1; > - location_t loc = EXPR_LOCATION (exp); > - > - switch (TREE_CODE (exp)) > - { > - case ABS_EXPR: > - case NEGATE_EXPR: > - arg0 = fold_strip_sign_ops (TREE_OPERAND (exp, 0)); > - return arg0 ? arg0 : TREE_OPERAND (exp, 0); > - > - case MULT_EXPR: > - case RDIV_EXPR: > - if (HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (exp))) > - return NULL_TREE; > - arg0 = fold_strip_sign_ops (TREE_OPERAND (exp, 0)); > - arg1 = fold_strip_sign_ops (TREE_OPERAND (exp, 1)); > - if (arg0 != NULL_TREE || arg1 != NULL_TREE) > - return fold_build2_loc (loc, TREE_CODE (exp), TREE_TYPE (exp), > - arg0 ? arg0 : TREE_OPERAND (exp, 0), > - arg1 ? arg1 : TREE_OPERAND (exp, 1)); > - break; > - > - case COMPOUND_EXPR: > - arg0 = TREE_OPERAND (exp, 0); > - arg1 = fold_strip_sign_ops (TREE_OPERAND (exp, 1)); > - if (arg1) > - return fold_build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (exp), arg0, > arg1); > - break; > - > - case COND_EXPR: > - arg0 = fold_strip_sign_ops (TREE_OPERAND (exp, 1)); > - arg1 = fold_strip_sign_ops (TREE_OPERAND (exp, 2)); > - if (arg0 || arg1) > - return fold_build3_loc (loc, > - COND_EXPR, TREE_TYPE (exp), TREE_OPERAND (exp, 0), > - arg0 ? arg0 : TREE_OPERAND (exp, 1), > - arg1 ? arg1 : TREE_OPERAND (exp, 2)); > - break; > - > - case CALL_EXPR: > - { > - const enum built_in_function fcode = builtin_mathfn_code (exp); > - switch (fcode) > - { > - CASE_FLT_FN (BUILT_IN_COPYSIGN): > - /* Strip copysign function call, return the 1st argument. */ > - arg0 = CALL_EXPR_ARG (exp, 0); > - arg1 = CALL_EXPR_ARG (exp, 1); > - return omit_one_operand_loc (loc, TREE_TYPE (exp), arg0, arg1); > - > - default: > - /* Strip sign ops from the argument of "odd" math functions. */ > - if (negate_mathfn_p (fcode)) > - { > - arg0 = fold_strip_sign_ops (CALL_EXPR_ARG (exp, 0)); > - if (arg0) > - return build_call_expr_loc (loc, get_callee_fndecl (exp), 1, > arg0); > - } > - break; > - } > - } > - break; > - > - default: > - break; > - } > - return NULL_TREE; > -} > - > /* Return OFF converted to a pointer offset type suitable as offset for > POINTER_PLUS_EXPR. Use location LOC for this conversion. */ > tree > diff --git a/gcc/fold-const.h b/gcc/fold-const.h > index 4d5b24b..1bb68e4 100644 > --- a/gcc/fold-const.h > +++ b/gcc/fold-const.h > @@ -107,7 +107,6 @@ extern tree build_fold_addr_expr_loc (location_t, tree); > build_fold_addr_expr_with_type_loc (UNKNOWN_LOCATION, (T), TYPE) > extern tree build_fold_addr_expr_with_type_loc (location_t, tree, tree); > extern tree fold_build_cleanup_point_expr (tree type, tree expr); > -extern tree fold_strip_sign_ops (tree); > #define build_fold_indirect_ref(T)\ > build_fold_indirect_ref_loc (UNKNOWN_LOCATION, T) > extern tree build_fold_indirect_ref_loc (location_t, tree); > diff --git a/gcc/testsuite/gcc.dg/builtins-86.c > b/gcc/testsuite/gcc.dg/builtins-86.c > index f405124..d0e5c70 100644 > --- a/gcc/testsuite/gcc.dg/builtins-86.c > +++ b/gcc/testsuite/gcc.dg/builtins-86.c > @@ -53,4 +53,5 @@ int main() > return 0; > } > > -/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" } } */ > +/* XFAILed because of PR 67975. */ > +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail > *-*-* } } } */ > diff --git a/gcc/testsuite/gcc.dg/torture/builtin-symmetric-1.c > b/gcc/testsuite/gcc.dg/torture/builtin-symmetric-1.c > index 4834d8e..61d8a80 100644 > --- a/gcc/testsuite/gcc.dg/torture/builtin-symmetric-1.c > +++ b/gcc/testsuite/gcc.dg/torture/builtin-symmetric-1.c > @@ -7,6 +7,7 @@ > > /* { dg-do link } */ > /* { dg-options "-ffast-math" } */ > +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ > > /* All references to link_error should go away at compile-time. */ > extern void link_error(int); >