From 092404511f58ed2a7c11785fa5b2e69b32048fd3 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Tue, 18 Nov 2014 11:26:31 +0100 Subject: [PATCH] tree.c (element_mode, [...]): New functions. 2014-11-18 Marc Glisse * tree.c (element_mode, integer_truep): New functions. * tree.h (element_mode, integer_truep): Declare them. * fold-const.c (negate_expr_p, fold_negate_expr, combine_comparisons, fold_cond_expr_with_comparison, fold_real_zero_addition_p, fold_comparison, fold_ternary_loc, tree_call_nonnegative_warnv_p, fold_strip_sign_ops): Use element_mode. (fold_binary_loc): Use element_mode and element_precision. * match.pd: Use integer_truep, element_mode, element_precision, VECTOR_TYPE_P and build_one_cst. Extend some transformations to vectors. Simplify A/-A. From-SVN: r217702 --- gcc/ChangeLog | 13 ++++++ gcc/fold-const.c | 90 +++++++++++++++++++-------------------- gcc/match.pd | 107 +++++++++++++++++++++++------------------------ gcc/tree.c | 28 +++++++++++++ gcc/tree.h | 7 ++++ 5 files changed, 145 insertions(+), 100 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 52fa23be23b..78ed17c69e0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2014-11-18 Marc Glisse + + * tree.c (element_mode, integer_truep): New functions. + * tree.h (element_mode, integer_truep): Declare them. + * fold-const.c (negate_expr_p, fold_negate_expr, combine_comparisons, + fold_cond_expr_with_comparison, fold_real_zero_addition_p, + fold_comparison, fold_ternary_loc, tree_call_nonnegative_warnv_p, + fold_strip_sign_ops): Use element_mode. + (fold_binary_loc): Use element_mode and element_precision. + * match.pd: Use integer_truep, element_mode, element_precision, + VECTOR_TYPE_P and build_one_cst. Extend some transformations to + vectors. Simplify A/-A. + 2014-11-18 Kyrylo Tkachov * config/arm/arm.md (unaligned_loaddi): Use std::swap instead of diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 7dbbadd859b..f6fb8af8084 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -442,8 +442,8 @@ negate_expr_p (tree t) return negate_expr_p (TREE_OPERAND (t, 0)); case PLUS_EXPR: - if (HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type)) - || HONOR_SIGNED_ZEROS (TYPE_MODE (type))) + if (HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type)) + || HONOR_SIGNED_ZEROS (element_mode (type))) return false; /* -(A + B) -> (-B) - A. */ if (negate_expr_p (TREE_OPERAND (t, 1)) @@ -455,8 +455,8 @@ negate_expr_p (tree t) case MINUS_EXPR: /* We can't turn -(A-B) into B-A when we honor signed zeros. */ - return !HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type)) - && !HONOR_SIGNED_ZEROS (TYPE_MODE (type)) + return !HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type)) + && !HONOR_SIGNED_ZEROS (element_mode (type)) && reorder_operands_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)); @@ -467,7 +467,7 @@ negate_expr_p (tree t) /* Fall through. */ case RDIV_EXPR: - if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (t)))) + if (! HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (TREE_TYPE (t)))) return negate_expr_p (TREE_OPERAND (t, 1)) || negate_expr_p (TREE_OPERAND (t, 0)); break; @@ -617,8 +617,8 @@ fold_negate_expr (location_t loc, tree t) break; case PLUS_EXPR: - if (!HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type)) - && !HONOR_SIGNED_ZEROS (TYPE_MODE (type))) + if (!HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type)) + && !HONOR_SIGNED_ZEROS (element_mode (type))) { /* -(A + B) -> (-B) - A. */ if (negate_expr_p (TREE_OPERAND (t, 1)) @@ -642,8 +642,8 @@ fold_negate_expr (location_t loc, tree t) case MINUS_EXPR: /* - (A - B) -> B - A */ - if (!HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type)) - && !HONOR_SIGNED_ZEROS (TYPE_MODE (type)) + if (!HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type)) + && !HONOR_SIGNED_ZEROS (element_mode (type)) && reorder_operands_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1))) return fold_build2_loc (loc, MINUS_EXPR, type, TREE_OPERAND (t, 1), TREE_OPERAND (t, 0)); @@ -656,7 +656,7 @@ fold_negate_expr (location_t loc, tree t) /* Fall through. */ case RDIV_EXPR: - if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type))) + if (! HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))) { tem = TREE_OPERAND (t, 1); if (negate_expr_p (tem)) @@ -2315,7 +2315,7 @@ combine_comparisons (location_t loc, enum tree_code rcode, tree truth_type, tree ll_arg, tree lr_arg) { - bool honor_nans = HONOR_NANS (TYPE_MODE (TREE_TYPE (ll_arg))); + bool honor_nans = HONOR_NANS (element_mode (ll_arg)); enum comparison_code lcompcode = comparison_to_compcode (lcode); enum comparison_code rcompcode = comparison_to_compcode (rcode); int compcode; @@ -4581,7 +4581,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type, Note that all these transformations are correct if A is NaN, since the two alternatives (A and -A) are also NaNs. */ - if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)) + if (!HONOR_SIGNED_ZEROS (element_mode (type)) && (FLOAT_TYPE_P (TREE_TYPE (arg01)) ? real_zerop (arg01) : integer_zerop (arg01)) @@ -4639,7 +4639,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type, both transformations are correct when A is NaN: A != 0 is then true, and A == 0 is false. */ - if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)) + if (!HONOR_SIGNED_ZEROS (element_mode (type)) && integer_zerop (arg01) && integer_zerop (arg2)) { if (comp_code == NE_EXPR) @@ -4674,7 +4674,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type, a number and A is not. The conditions in the original expressions will be false, so all four give B. The min() and max() versions would give a NaN instead. */ - if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)) + if (!HONOR_SIGNED_ZEROS (element_mode (type)) && operand_equal_for_comparison_p (arg01, arg2, arg00) /* Avoid these transformations if the COND_EXPR may be used as an lvalue in the C++ front-end. PR c++/19199. */ @@ -4711,7 +4711,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type, operand which will be used if they are equal first so that we can convert this back to the corresponding COND_EXPR. */ - if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))) + if (!HONOR_NANS (element_mode (arg1))) { comp_op0 = fold_convert_loc (loc, comp_type, comp_op0); comp_op1 = fold_convert_loc (loc, comp_type, comp_op1); @@ -4727,7 +4727,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type, case GT_EXPR: case UNGE_EXPR: case UNGT_EXPR: - if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))) + if (!HONOR_NANS (element_mode (arg1))) { comp_op0 = fold_convert_loc (loc, comp_type, comp_op0); comp_op1 = fold_convert_loc (loc, comp_type, comp_op1); @@ -4740,12 +4740,12 @@ fold_cond_expr_with_comparison (location_t loc, tree type, } break; case UNEQ_EXPR: - if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))) + if (!HONOR_NANS (element_mode (arg1))) return pedantic_non_lvalue_loc (loc, fold_convert_loc (loc, type, arg2)); break; case LTGT_EXPR: - if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))) + if (!HONOR_NANS (element_mode (arg1))) return pedantic_non_lvalue_loc (loc, fold_convert_loc (loc, type, arg1)); break; @@ -6090,11 +6090,11 @@ fold_real_zero_addition_p (const_tree type, const_tree addend, int negate) return false; /* Don't allow the fold with -fsignaling-nans. */ - if (HONOR_SNANS (TYPE_MODE (type))) + if (HONOR_SNANS (element_mode (type))) return false; /* Allow the fold if zeros aren't signed, or their sign isn't important. */ - if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type))) + if (!HONOR_SIGNED_ZEROS (element_mode (type))) return true; /* In a vector or complex, we would need to check the sign of all zeros. */ @@ -6109,7 +6109,7 @@ fold_real_zero_addition_p (const_tree type, const_tree addend, int negate) In this situation, there is only one case we can return true for. X - 0 is the same as X unless rounding towards -infinity is supported. */ - return negate && !HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type)); + return negate && !HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type)); } /* Subroutine of fold() that checks comparisons of built-in math @@ -9080,14 +9080,14 @@ fold_comparison (location_t loc, enum tree_code code, tree type, { case EQ_EXPR: if (! FLOAT_TYPE_P (TREE_TYPE (arg0)) - || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))) + || ! HONOR_NANS (element_mode (arg0))) return constant_boolean_node (1, type); break; case GE_EXPR: case LE_EXPR: if (! FLOAT_TYPE_P (TREE_TYPE (arg0)) - || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))) + || ! HONOR_NANS (element_mode (arg0))) return constant_boolean_node (1, type); return fold_build2_loc (loc, EQ_EXPR, type, arg0, arg1); @@ -9095,7 +9095,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type, /* For NE, we can only do this simplification if integer or we don't honor IEEE floating point NaNs. */ if (FLOAT_TYPE_P (TREE_TYPE (arg0)) - && HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))) + && HONOR_NANS (element_mode (arg0))) break; /* ... fall through ... */ case GT_EXPR: @@ -9968,8 +9968,8 @@ fold_binary_loc (location_t loc, /* Fold __complex__ ( x, 0 ) + __complex__ ( 0, y ) to __complex__ ( x, y ). This is not the same for SNaNs or if signed zeros are involved. */ - if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0))) - && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0))) + if (!HONOR_SNANS (element_mode (arg0)) + && !HONOR_SIGNED_ZEROS (element_mode (arg0)) && COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0))) { tree rtype = TREE_TYPE (TREE_TYPE (arg0)); @@ -10405,8 +10405,8 @@ fold_binary_loc (location_t loc, /* Fold __complex__ ( x, 0 ) - __complex__ ( 0, y ) to __complex__ ( x, -y ). This is not the same for SNaNs or if signed zeros are involved. */ - if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0))) - && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0))) + if (!HONOR_SNANS (element_mode (arg0)) + && !HONOR_SIGNED_ZEROS (element_mode (arg0)) && COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0))) { tree rtype = TREE_TYPE (TREE_TYPE (arg0)); @@ -10609,8 +10609,8 @@ fold_binary_loc (location_t loc, /* Fold z * +-I to __complex__ (-+__imag z, +-__real z). This is not the same for NaNs or if signed zeros are involved. */ - if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) - && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0))) + if (!HONOR_NANS (element_mode (arg0)) + && !HONOR_SIGNED_ZEROS (element_mode (arg0)) && COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0)) && TREE_CODE (arg1) == COMPLEX_CST && real_zerop (TREE_REALPART (arg1))) @@ -10657,7 +10657,7 @@ fold_binary_loc (location_t loc, /* Optimize sqrt(x)*sqrt(x) as x. */ if (BUILTIN_SQRT_P (fcode0) && operand_equal_p (arg00, arg10, 0) - && ! HONOR_SNANS (TYPE_MODE (type))) + && ! HONOR_SNANS (element_mode (type))) return arg00; /* Optimize root(x)*root(y) as root(x*y). */ @@ -11305,7 +11305,7 @@ fold_binary_loc (location_t loc, if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0)))) { - prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0))); + prec = element_precision (TREE_TYPE (TREE_OPERAND (arg0, 0))); wide_int mask = wide_int::from (arg1, prec, UNSIGNED); if (mask == -1) @@ -11541,8 +11541,8 @@ fold_binary_loc (location_t loc, tree arg00 = CALL_EXPR_ARG (arg0, 0); tree arg01 = CALL_EXPR_ARG (arg1, 0); - if (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg00))) - && ! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg00))) + if (! HONOR_NANS (element_mode (arg00)) + && ! HONOR_INFINITIES (element_mode (arg00)) && operand_equal_p (arg00, arg01, 0)) { tree cosfn = mathfn_built_in (type, BUILT_IN_COS); @@ -11561,8 +11561,8 @@ fold_binary_loc (location_t loc, tree arg00 = CALL_EXPR_ARG (arg0, 0); tree arg01 = CALL_EXPR_ARG (arg1, 0); - if (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg00))) - && ! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg00))) + if (! HONOR_NANS (element_mode (arg00)) + && ! HONOR_INFINITIES (element_mode (arg00)) && operand_equal_p (arg00, arg01, 0)) { tree cosfn = mathfn_built_in (type, BUILT_IN_COS); @@ -12935,7 +12935,7 @@ fold_binary_loc (location_t loc, strict_overflow_p = false; if (code == GE_EXPR && (integer_zerop (arg1) - || (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) + || (! HONOR_NANS (element_mode (arg0)) && real_zerop (arg1))) && tree_expr_nonnegative_warnv_p (arg0, &strict_overflow_p)) { @@ -12987,11 +12987,11 @@ fold_binary_loc (location_t loc, && TYPE_UNSIGNED (TREE_TYPE (arg0)) && CONVERT_EXPR_P (arg1) && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR - && (TYPE_PRECISION (TREE_TYPE (arg1)) - >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)))) + && (element_precision (TREE_TYPE (arg1)) + >= element_precision (TREE_TYPE (TREE_OPERAND (arg1, 0)))) && (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg1, 0))) - || (TYPE_PRECISION (TREE_TYPE (arg1)) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0))))) + || (element_precision (TREE_TYPE (arg1)) + == element_precision (TREE_TYPE (TREE_OPERAND (arg1, 0))))) && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0))) { tem = build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0, @@ -13322,7 +13322,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, if (COMPARISON_CLASS_P (arg0) && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), arg1, TREE_OPERAND (arg0, 1)) - && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1)))) + && !HONOR_SIGNED_ZEROS (element_mode (arg1))) { tem = fold_cond_expr_with_comparison (loc, type, arg0, op1, op2); if (tem) @@ -13333,7 +13333,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), op2, TREE_OPERAND (arg0, 1)) - && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op2)))) + && !HONOR_SIGNED_ZEROS (element_mode (op2))) { location_t loc0 = expr_location_or (arg0, loc); tem = fold_invert_truthvalue (loc0, arg0); @@ -14834,7 +14834,7 @@ tree_call_nonnegative_warnv_p (tree type, tree fndecl, CASE_FLT_FN (BUILT_IN_SQRT): /* sqrt(-0.0) is -0.0. */ - if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type))) + if (!HONOR_SIGNED_ZEROS (element_mode (type))) return true; return tree_expr_nonnegative_warnv_p (arg0, strict_overflow_p); @@ -16100,7 +16100,7 @@ fold_strip_sign_ops (tree exp) case MULT_EXPR: case RDIV_EXPR: - if (HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (exp)))) + 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)); diff --git a/gcc/match.pd b/gcc/match.pd index da6599c750d..1f204716d1c 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see /* Generic tree predicates we inherit. */ (define_predicates integer_onep integer_zerop integer_all_onesp integer_minus_onep - integer_each_onep + integer_each_onep integer_truep real_zerop real_onep real_minus_onep CONSTANT_CLASS_P tree_expr_nonnegative_p) @@ -73,7 +73,7 @@ along with GCC; see the file COPYING3. If not see is volatile. */ (simplify (minus @0 @0) - (if (!FLOAT_TYPE_P (type) || !HONOR_NANS (TYPE_MODE (type))) + (if (!FLOAT_TYPE_P (type) || !HONOR_NANS (element_mode (type))) { build_zero_cst (type); })) (simplify @@ -86,24 +86,24 @@ along with GCC; see the file COPYING3. If not see negative value by 0 gives -0, not +0. */ (simplify (mult @0 real_zerop@1) - (if (!HONOR_NANS (TYPE_MODE (type)) - && !HONOR_SIGNED_ZEROS (TYPE_MODE (type))) + (if (!HONOR_NANS (element_mode (type)) + && !HONOR_SIGNED_ZEROS (element_mode (type))) @1)) /* In IEEE floating point, x*1 is not equivalent to x for snans. Likewise for complex arithmetic with signed zeros. */ (simplify (mult @0 real_onep) - (if (!HONOR_SNANS (TYPE_MODE (type)) - && (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)) + (if (!HONOR_SNANS (element_mode (type)) + && (!HONOR_SIGNED_ZEROS (element_mode (type)) || !COMPLEX_FLOAT_TYPE_P (type))) (non_lvalue @0))) /* Transform x * -1.0 into -x. */ (simplify (mult @0 real_minus_onep) - (if (!HONOR_SNANS (TYPE_MODE (type)) - && (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)) + (if (!HONOR_SNANS (element_mode (type)) + && (!HONOR_SIGNED_ZEROS (element_mode (type)) || !COMPLEX_FLOAT_TYPE_P (type))) (negate @0))) @@ -117,44 +117,46 @@ along with GCC; see the file COPYING3. If not see /* X / -1 is -X. */ (for div (trunc_div ceil_div floor_div round_div exact_div) (simplify - (div @0 INTEGER_CST@1) - (if (!TYPE_UNSIGNED (type) - && wi::eq_p (@1, -1)) + (div @0 integer_minus_onep@1) + (if (!TYPE_UNSIGNED (type)) (negate @0)))) /* For unsigned integral types, FLOOR_DIV_EXPR is the same as TRUNC_DIV_EXPR. Rewrite into the latter in this case. */ (simplify (floor_div @0 @1) - (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)) + (if ((INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type)) + && TYPE_UNSIGNED (type)) (trunc_div @0 @1))) /* Optimize A / A to 1.0 if we don't care about - NaNs or Infinities. Skip the transformation - for non-real operands. */ + NaNs or Infinities. */ (simplify (rdiv @0 @0) - (if (SCALAR_FLOAT_TYPE_P (type) - && ! HONOR_NANS (TYPE_MODE (type)) - && ! HONOR_INFINITIES (TYPE_MODE (type))) - { build_real (type, dconst1); }) - /* The complex version of the above A / A optimization. */ - (if (COMPLEX_FLOAT_TYPE_P (type) - && ! HONOR_NANS (TYPE_MODE (TREE_TYPE (type))) - && ! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (type)))) - { build_complex (type, build_real (TREE_TYPE (type), dconst1), - build_real (TREE_TYPE (type), dconst0)); })) + (if (FLOAT_TYPE_P (type) + && ! HONOR_NANS (element_mode (type)) + && ! HONOR_INFINITIES (element_mode (type))) + { build_one_cst (type); })) + +/* Optimize -A / A to -1.0 if we don't care about + NaNs or Infinities. */ +(simplify + (rdiv:c @0 (negate @0)) + (if (FLOAT_TYPE_P (type) + && ! HONOR_NANS (element_mode (type)) + && ! HONOR_INFINITIES (element_mode (type))) + { build_minus_one_cst (type); })) /* In IEEE floating point, x/1 is not equivalent to x for snans. */ (simplify (rdiv @0 real_onep) - (if (!HONOR_SNANS (TYPE_MODE (type))) + (if (!HONOR_SNANS (element_mode (type))) (non_lvalue @0))) /* In IEEE floating point, x/-1 is not equivalent to -x for snans. */ (simplify (rdiv @0 real_minus_onep) - (if (!HONOR_SNANS (TYPE_MODE (type))) + (if (!HONOR_SNANS (element_mode (type))) (negate @0))) /* If ARG1 is a constant, we can convert this to a multiply by the @@ -192,9 +194,8 @@ along with GCC; see the file COPYING3. If not see { build_zero_cst (type); }) /* X % -1 is zero. */ (simplify - (mod @0 INTEGER_CST@1) - (if (!TYPE_UNSIGNED (type) - && wi::eq_p (@1, -1)) + (mod @0 integer_minus_onep@1) + (if (!TYPE_UNSIGNED (type)) { build_zero_cst (type); }))) /* X % -C is the same as X % C. */ @@ -309,14 +310,11 @@ along with GCC; see the file COPYING3. If not see (match (logical_inverted_value @0) (bit_not truth_valued_p@0)) (match (logical_inverted_value @0) - (eq @0 integer_zerop) - (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))))) + (eq @0 integer_zerop)) (match (logical_inverted_value @0) - (ne truth_valued_p@0 integer_onep) - (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))))) + (ne truth_valued_p@0 integer_truep)) (match (logical_inverted_value @0) - (bit_xor truth_valued_p@0 integer_onep) - (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))))) + (bit_xor truth_valued_p@0 integer_truep)) /* X & !X -> 0. */ (simplify @@ -493,7 +491,7 @@ along with GCC; see the file COPYING3. If not see (simplify (minus (convert (add @0 @1)) (convert @0)) - (if (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (@1)) + (if (element_precision (type) <= element_precision (TREE_TYPE (@1)) /* For integer types, if A has a smaller type than T the result depends on the possible overflow in P + A. @@ -626,19 +624,19 @@ along with GCC; see the file COPYING3. If not see int inside_int = INTEGRAL_TYPE_P (inside_type); int inside_ptr = POINTER_TYPE_P (inside_type); int inside_float = FLOAT_TYPE_P (inside_type); - int inside_vec = TREE_CODE (inside_type) == VECTOR_TYPE; + int inside_vec = VECTOR_TYPE_P (inside_type); unsigned int inside_prec = TYPE_PRECISION (inside_type); int inside_unsignedp = TYPE_UNSIGNED (inside_type); int inter_int = INTEGRAL_TYPE_P (inter_type); int inter_ptr = POINTER_TYPE_P (inter_type); int inter_float = FLOAT_TYPE_P (inter_type); - int inter_vec = TREE_CODE (inter_type) == VECTOR_TYPE; + int inter_vec = VECTOR_TYPE_P (inter_type); unsigned int inter_prec = TYPE_PRECISION (inter_type); int inter_unsignedp = TYPE_UNSIGNED (inter_type); int final_int = INTEGRAL_TYPE_P (type); int final_ptr = POINTER_TYPE_P (type); int final_float = FLOAT_TYPE_P (type); - int final_vec = TREE_CODE (type) == VECTOR_TYPE; + int final_vec = VECTOR_TYPE_P (type); unsigned int final_prec = TYPE_PRECISION (type); int final_unsignedp = TYPE_UNSIGNED (type); } @@ -666,8 +664,8 @@ along with GCC; see the file COPYING3. If not see && inter_prec >= inside_prec && (inter_float || inter_vec || inter_unsignedp == inside_unsignedp) - && ! (final_prec != GET_MODE_PRECISION (TYPE_MODE (type)) - && TYPE_MODE (type) == TYPE_MODE (inter_type)) + && ! (final_prec != GET_MODE_PRECISION (element_mode (type)) + && element_mode (type) == element_mode (inter_type)) && ! final_ptr && (! final_vec || inter_prec == inside_prec)) (ocvt @0)) @@ -845,12 +843,12 @@ along with GCC; see the file COPYING3. If not see /* A ? B : B -> B. */ (simplify (cnd @0 @1 @1) - @1)) + @1) -/* !A ? B : C -> A ? C : B. */ -(simplify - (cond (logical_inverted_value truth_valued_p@0) @1 @2) - (cond @0 @2 @1)) + /* !A ? B : C -> A ? C : B. */ + (simplify + (cnd (logical_inverted_value truth_valued_p@0) @1 @2) + (cnd @0 @2 @1))) /* Simplifications of comparisons. */ @@ -876,17 +874,16 @@ along with GCC; see the file COPYING3. If not see a computed operator in the replacement tree thus we have to play the trick below. */ (with { enum tree_code ic = invert_tree_comparison - (cmp, HONOR_NANS (TYPE_MODE (TREE_TYPE (@0)))); } + (cmp, HONOR_NANS (element_mode (@0))); } (if (ic == icmp) (icmp @0 @1)) (if (ic == ncmp) (ncmp @0 @1))))) (simplify - (bit_xor (cmp @0 @1) integer_onep) - (if (INTEGRAL_TYPE_P (type)) - (with { enum tree_code ic = invert_tree_comparison - (cmp, HONOR_NANS (TYPE_MODE (TREE_TYPE (@0)))); } - (if (ic == icmp) - (icmp @0 @1)) - (if (ic == ncmp) - (ncmp @0 @1)))))) + (bit_xor (cmp @0 @1) integer_truep) + (with { enum tree_code ic = invert_tree_comparison + (cmp, HONOR_NANS (element_mode (@0))); } + (if (ic == icmp) + (icmp @0 @1)) + (if (ic == ncmp) + (ncmp @0 @1))))) diff --git a/gcc/tree.c b/gcc/tree.c index 3d1d6370fb0..3f801af5344 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -2275,6 +2275,20 @@ integer_nonzerop (const_tree expr) || integer_nonzerop (TREE_IMAGPART (expr))))); } +/* Return 1 if EXPR is the integer constant one. For vector, + return 1 if every piece is the integer constant minus one + (representing the value TRUE). */ + +int +integer_truep (const_tree expr) +{ + STRIP_NOPS (expr); + + if (TREE_CODE (expr) == VECTOR_CST) + return integer_all_onesp (expr); + return integer_onep (expr); +} + /* Return 1 if EXPR is the fixed-point constant zero. */ int @@ -12310,4 +12324,18 @@ get_base_address (tree t) return t; } +/* Return the machine mode of T. For vectors, returns the mode of the + inner type. The main use case is to feed the result to HONOR_NANS, + avoiding the BLKmode that a direct TYPE_MODE (T) might return. */ + +machine_mode +element_mode (const_tree t) +{ + if (!TYPE_P (t)) + t = TREE_TYPE (t); + if (VECTOR_TYPE_P (t) || TREE_CODE (t) == COMPLEX_TYPE) + t = TREE_TYPE (t); + return TYPE_MODE (t); +} + #include "gt-tree.h" diff --git a/gcc/tree.h b/gcc/tree.h index 108b52dcd68..ed8fecdd8e7 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1564,6 +1564,8 @@ extern void protected_set_expr_location (tree, location_t); #define SET_TYPE_MODE(NODE, MODE) \ (TYPE_CHECK (NODE)->type_common.mode = (MODE)) +extern machine_mode element_mode (const_tree t); + /* The "canonical" type for this type node, which is used by frontends to compare the type for equality with another type. If two types are equal (based on the semantics of the language), then they will have @@ -3999,6 +4001,11 @@ extern int integer_pow2p (const_tree); extern int integer_nonzerop (const_tree); +/* integer_truep (tree x) is nonzero if X is an integer constant of value 1 or + a vector where each element is an integer constant of value -1. */ + +extern int integer_truep (const_tree); + extern bool cst_and_fits_in_hwi (const_tree); extern tree num_ending_zeros (const_tree); -- 2.30.2