This is the mail archive of the
`gcc-patches@gcc.gnu.org`
mailing list for the GCC project.

Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|

Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |

Other format: | [Raw text] |

*From*: Marc Glisse <marc dot glisse at inria dot fr>*To*: gcc-patches at gcc dot gnu dot org*Date*: Sun, 24 May 2015 10:33:49 +0200 (CEST)*Subject*: Move ABS detection from fold-const.c to match.pd*Authentication-results*: sourceware.org; auth=none

Hello,

Regtested on ppc64le-redhat-linux. 2015-05-25 Marc Glisse <marc.glisse@inria.fr> * genmatch.c (write_predicate): Add ATTRIBUTE_UNUSED. * match.pd (A op 0 ? A : -A, A op 0 ? A : 0): New simplifications. * fold-const.c (fold_cond_expr_with_comparison): Remove corresponding code. -- Marc Glisse

Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 223630) +++ gcc/fold-const.c (working copy) @@ -4875,112 +4875,25 @@ merge_ranges (int *pin_p, tree *plow, tr Return a folded expression whose code is not a COND_EXPR anymore, or NULL_TREE if no folding opportunity is found. */ static tree fold_cond_expr_with_comparison (location_t loc, tree type, tree arg0, tree arg1, tree arg2) { enum tree_code comp_code = TREE_CODE (arg0); tree arg00 = TREE_OPERAND (arg0, 0); tree arg01 = TREE_OPERAND (arg0, 1); - tree arg1_type = TREE_TYPE (arg1); tree tem; STRIP_NOPS (arg1); STRIP_NOPS (arg2); - /* If we have A op 0 ? A : -A, consider applying the following - transformations: - - A == 0? A : -A same as -A - A != 0? A : -A same as A - A >= 0? A : -A same as abs (A) - A > 0? A : -A same as abs (A) - A <= 0? A : -A same as -abs (A) - A < 0? A : -A same as -abs (A) - - None of these transformations work for modes with signed - zeros. If A is +/-0, the first two transformations will - change the sign of the result (from +0 to -0, or vice - versa). The last four will fix the sign of the result, - even though the original expressions could be positive or - negative, depending on the sign of A. - - 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 (element_mode (type)) - && (FLOAT_TYPE_P (TREE_TYPE (arg01)) - ? real_zerop (arg01) - : integer_zerop (arg01)) - && ((TREE_CODE (arg2) == NEGATE_EXPR - && operand_equal_p (TREE_OPERAND (arg2, 0), arg1, 0)) - /* In the case that A is of the form X-Y, '-A' (arg2) may - have already been folded to Y-X, check for that. */ - || (TREE_CODE (arg1) == MINUS_EXPR - && TREE_CODE (arg2) == MINUS_EXPR - && operand_equal_p (TREE_OPERAND (arg1, 0), - TREE_OPERAND (arg2, 1), 0) - && operand_equal_p (TREE_OPERAND (arg1, 1), - TREE_OPERAND (arg2, 0), 0)))) - switch (comp_code) - { - case EQ_EXPR: - case UNEQ_EXPR: - tem = fold_convert_loc (loc, arg1_type, arg1); - return pedantic_non_lvalue_loc (loc, - fold_convert_loc (loc, type, - negate_expr (tem))); - case NE_EXPR: - case LTGT_EXPR: - return pedantic_non_lvalue_loc (loc, fold_convert_loc (loc, type, arg1)); - case UNGE_EXPR: - case UNGT_EXPR: - if (flag_trapping_math) - break; - /* Fall through. */ - case GE_EXPR: - case GT_EXPR: - if (TYPE_UNSIGNED (TREE_TYPE (arg1))) - arg1 = fold_convert_loc (loc, signed_type_for - (TREE_TYPE (arg1)), arg1); - tem = fold_build1_loc (loc, ABS_EXPR, TREE_TYPE (arg1), arg1); - return pedantic_non_lvalue_loc (loc, fold_convert_loc (loc, type, tem)); - case UNLE_EXPR: - case UNLT_EXPR: - if (flag_trapping_math) - break; - case LE_EXPR: - case LT_EXPR: - if (TYPE_UNSIGNED (TREE_TYPE (arg1))) - arg1 = fold_convert_loc (loc, signed_type_for - (TREE_TYPE (arg1)), arg1); - tem = fold_build1_loc (loc, ABS_EXPR, TREE_TYPE (arg1), arg1); - return negate_expr (fold_convert_loc (loc, type, tem)); - default: - gcc_assert (TREE_CODE_CLASS (comp_code) == tcc_comparison); - break; - } - - /* A != 0 ? A : 0 is simply A, unless A is -0. Likewise - A == 0 ? A : 0 is always 0 unless A is -0. Note that - both transformations are correct when A is NaN: A != 0 - is then true, and A == 0 is false. */ - - if (!HONOR_SIGNED_ZEROS (element_mode (type)) - && integer_zerop (arg01) && integer_zerop (arg2)) - { - if (comp_code == NE_EXPR) - return pedantic_non_lvalue_loc (loc, fold_convert_loc (loc, type, arg1)); - else if (comp_code == EQ_EXPR) - return build_zero_cst (type); - } - /* Try some transformations of A op B ? A : B. A == B? A : B same as B A != B? A : B same as A A >= B? A : B same as max (A, B) A > B? A : B same as max (B, A) A <= B? A : B same as min (A, B) A < B? A : B same as min (B, A) As above, these transformations don't work in the presence Index: gcc/genmatch.c =================================================================== --- gcc/genmatch.c (revision 223630) +++ gcc/genmatch.c (working copy) @@ -2657,21 +2657,21 @@ decision_tree::gen_generic (FILE *f) /* Output code to implement the predicate P from the decision tree DT. */ void write_predicate (FILE *f, predicate_id *p, decision_tree &dt, bool gimple) { fprintf (f, "\nbool\n" "%s%s (tree t%s%s)\n" "{\n", gimple ? "gimple_" : "tree_", p->id, p->nargs > 0 ? ", tree *res_ops" : "", - gimple ? ", tree (*valueize)(tree)" : ""); + gimple ? ", tree (*valueize)(tree) ATTRIBUTE_UNUSED" : ""); /* Conveniently make 'type' available. */ fprintf (f, "tree type = TREE_TYPE (t);\n"); if (!gimple) fprintf (f, "if (TREE_SIDE_EFFECTS (t)) return false;\n"); dt.root->gen_kids (f, gimple); fprintf (f, "return false;\n" "}\n"); } Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 223630) +++ gcc/match.pd (working copy) @@ -1131,10 +1131,106 @@ along with GCC; see the file COPYING3. && (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)) || tree_int_cst_sgn (@4) >= 0) && single_use (@5)) (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))) (with { tree ntype = TREE_TYPE (@0); } (convert (bit_and (op @0 @1) (convert:ntype @4))))) (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); } (convert (bit_and (op (convert:utype @0) (convert:utype @1)) (convert:utype @4))))))) + +(match zerop integer_zerop) +(match zerop real_zerop) + +/* If we have A op 0 ? A : -A, consider applying the following + transformations: + + A == 0? A : -A same as -A + A != 0? A : -A same as A + A >= 0? A : -A same as abs (A) + A > 0? A : -A same as abs (A) + A <= 0? A : -A same as -abs (A) + A < 0? A : -A same as -abs (A) + + None of these transformations work for modes with signed + zeros. If A is +/-0, the first two transformations will + change the sign of the result (from +0 to -0, or vice + versa). The last four will fix the sign of the result, + even though the original expressions could be positive or + negative, depending on the sign of A. + + 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)) + (for cnd (cond vec_cond) + (for cmp (tcc_comparison) + (simplify + (cnd (cmp @0 zerop) (convert?@2 @0) (negate@1 @2)) + (if (cmp == EQ_EXPR || cmp == UNEQ_EXPR) + @1) + (if (cmp == NE_EXPR || cmp == LTGT_EXPR) + (non_lvalue @2)) + (if (TYPE_SIGN (TREE_TYPE (@0)) == SIGNED /* implicit */ + && TYPE_SIGN (type) == SIGNED + && element_precision (type) >= element_precision (TREE_TYPE (@0))) + (if (cmp == GE_EXPR || cmp == GT_EXPR + || (!flag_trapping_math && (cmp == UNGE_EXPR || cmp == UNGT_EXPR))) + (abs @2)) + (if (cmp == LE_EXPR || cmp == LT_EXPR + || (!flag_trapping_math && (cmp == UNLE_EXPR || cmp == UNLT_EXPR))) + (negate (abs @2))))) + /* Now with the branches swapped. */ + (simplify + (cnd (cmp @0 zerop) (negate@1 (convert?@2 @0)) @2) + (if (cmp == EQ_EXPR || cmp == UNEQ_EXPR) + (non_lvalue @2)) + (if (cmp == NE_EXPR || cmp == LTGT_EXPR) + @1) + (if (TYPE_SIGN (TREE_TYPE (@0)) == SIGNED /* implicit */ + && TYPE_SIGN (type) == SIGNED + && element_precision (type) >= element_precision (TREE_TYPE (@0))) + (if (cmp == GE_EXPR || cmp == GT_EXPR + || (!flag_trapping_math && (cmp == UNGE_EXPR || cmp == UNGT_EXPR))) + (negate (abs @2))) + (if (cmp == LE_EXPR || cmp == LT_EXPR + || (!flag_trapping_math && (cmp == UNLE_EXPR || cmp == UNLT_EXPR))) + (abs @2)))) + + /* Same as above, but if A is X - Y, -A may be spelled Y - X. */ + (simplify + (cnd (cmp (minus@0 @2 @3) zerop) @0 (minus@1 @3 @2)) + (if (cmp == EQ_EXPR || cmp == UNEQ_EXPR) + @1) + (if (cmp == NE_EXPR || cmp == LTGT_EXPR) + @0) + (if (!HONOR_SIGN_DEPENDENT_ROUNDING (type)) + (if (cmp == GE_EXPR || cmp == GT_EXPR + || (!flag_trapping_math && (cmp == UNGE_EXPR || cmp == UNGT_EXPR))) + (abs @0)) + (if (cmp == LE_EXPR || cmp == LT_EXPR + || (!flag_trapping_math && (cmp == UNLE_EXPR || cmp == UNLT_EXPR))) + (negate (abs @0))))) + (simplify + (cnd (cmp (minus@0 @2 @3) zerop) (minus@1 @3 @2) @0) + (if (cmp == EQ_EXPR || cmp == UNEQ_EXPR) + @0) + (if (cmp == NE_EXPR || cmp == LTGT_EXPR) + @1) + (if (!HONOR_SIGN_DEPENDENT_ROUNDING (type)) + (if (cmp == GE_EXPR || cmp == GT_EXPR + || (!flag_trapping_math && (cmp == UNGE_EXPR || cmp == UNGT_EXPR))) + (negate (abs @0))) + (if (cmp == LE_EXPR || cmp == LT_EXPR + || (!flag_trapping_math && (cmp == UNLE_EXPR || cmp == UNLT_EXPR))) + (abs @0))))) + + /* A != 0 ? A : 0 is simply A, unless A is -0. Likewise + A == 0 ? A : 0 is always 0 unless A is -0. Note that + both transformations are correct when A is NaN: A != 0 + is then true, and A == 0 is false. */ + (simplify + (cnd (ne @0 zerop) (convert? @0) zerop) + (non_lvalue (convert @0))) + (simplify + (cnd (eq @0 zerop) (convert? @0) zerop@1) + (non_lvalue (convert @1)))))

**Follow-Ups**:**Re: Move ABS detection from fold-const.c to match.pd***From:*Marc Glisse

Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|

Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |