From: Richard Biener Date: Thu, 16 Jul 2015 08:28:51 +0000 (+0000) Subject: fold-const.c (fold_widened_comparison): Remove. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=79d4f7c66e9c8462aee46a3488f589969851bd80;p=gcc.git fold-const.c (fold_widened_comparison): Remove. 2015-07-16 Richard Biener * fold-const.c (fold_widened_comparison): Remove. (fold_sign_changed_comparison): Likewise. (fold_comparison): Move widened and sign-changed comparison simplification ... * match.pd: ... to patterns here. * generic-match-head.c: Include target.h. * gimple-match-head.c: Likewise. * gcc.dg/tree-ssa/pr21031.c: Adjust. From-SVN: r225861 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 47c7c16f6b6..0287697ecb4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-07-16 Richard Biener + + * fold-const.c (fold_widened_comparison): Remove. + (fold_sign_changed_comparison): Likewise. + (fold_comparison): Move widened and sign-changed comparison + simplification ... + * match.pd: ... to patterns here. + * generic-match-head.c: Include target.h. + * gimple-match-head.c: Likewise. + 2015-07-16 Richard Biener * tree-ssa-dom.c (dom_valueize): New function. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index acccb3c6007..93dd29d6729 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -6685,148 +6685,6 @@ tree_swap_operands_p (const_tree arg0, const_tree arg1, bool reorder) return 0; } -/* Fold comparison ARG0 CODE ARG1 (with result in TYPE), where - ARG0 is extended to a wider type. */ - -static tree -fold_widened_comparison (location_t loc, enum tree_code code, - tree type, tree arg0, tree arg1) -{ - tree arg0_unw = get_unwidened (arg0, NULL_TREE); - tree arg1_unw; - tree shorter_type, outer_type; - tree min, max; - bool above, below; - - if (arg0_unw == arg0) - return NULL_TREE; - shorter_type = TREE_TYPE (arg0_unw); - - /* Disable this optimization if we're casting a function pointer - type on targets that require function pointer canonicalization. */ - if (targetm.have_canonicalize_funcptr_for_compare () - && TREE_CODE (shorter_type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (shorter_type)) == FUNCTION_TYPE) - return NULL_TREE; - - if (TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (shorter_type)) - return NULL_TREE; - - arg1_unw = get_unwidened (arg1, NULL_TREE); - - /* If possible, express the comparison in the shorter mode. */ - if ((code == EQ_EXPR || code == NE_EXPR - || TYPE_UNSIGNED (TREE_TYPE (arg0)) == TYPE_UNSIGNED (shorter_type)) - && (TREE_TYPE (arg1_unw) == shorter_type - || ((TYPE_PRECISION (shorter_type) - >= TYPE_PRECISION (TREE_TYPE (arg1_unw))) - && (TYPE_UNSIGNED (shorter_type) - == TYPE_UNSIGNED (TREE_TYPE (arg1_unw)))) - || (TREE_CODE (arg1_unw) == INTEGER_CST - && (TREE_CODE (shorter_type) == INTEGER_TYPE - || TREE_CODE (shorter_type) == BOOLEAN_TYPE) - && int_fits_type_p (arg1_unw, shorter_type)))) - return fold_build2_loc (loc, code, type, arg0_unw, - fold_convert_loc (loc, shorter_type, arg1_unw)); - - if (TREE_CODE (arg1_unw) != INTEGER_CST - || TREE_CODE (shorter_type) != INTEGER_TYPE - || int_fits_type_p (arg1_unw, shorter_type)) - return NULL_TREE; - - /* If we are comparing with the integer that does not fit into the range - of the shorter type, the result is known. */ - outer_type = TREE_TYPE (arg1_unw); - min = lower_bound_in_type (outer_type, shorter_type); - max = upper_bound_in_type (outer_type, shorter_type); - - above = integer_nonzerop (fold_relational_const (LT_EXPR, type, - max, arg1_unw)); - below = integer_nonzerop (fold_relational_const (LT_EXPR, type, - arg1_unw, min)); - - switch (code) - { - case EQ_EXPR: - if (above || below) - return omit_one_operand_loc (loc, type, integer_zero_node, arg0); - break; - - case NE_EXPR: - if (above || below) - return omit_one_operand_loc (loc, type, integer_one_node, arg0); - break; - - case LT_EXPR: - case LE_EXPR: - if (above) - return omit_one_operand_loc (loc, type, integer_one_node, arg0); - else if (below) - return omit_one_operand_loc (loc, type, integer_zero_node, arg0); - - case GT_EXPR: - case GE_EXPR: - if (above) - return omit_one_operand_loc (loc, type, integer_zero_node, arg0); - else if (below) - return omit_one_operand_loc (loc, type, integer_one_node, arg0); - - default: - break; - } - - return NULL_TREE; -} - -/* Fold comparison ARG0 CODE ARG1 (with result in TYPE), where for - ARG0 just the signedness is changed. */ - -static tree -fold_sign_changed_comparison (location_t loc, enum tree_code code, tree type, - tree arg0, tree arg1) -{ - tree arg0_inner; - tree inner_type, outer_type; - - if (!CONVERT_EXPR_P (arg0)) - return NULL_TREE; - - outer_type = TREE_TYPE (arg0); - arg0_inner = TREE_OPERAND (arg0, 0); - inner_type = TREE_TYPE (arg0_inner); - - /* Disable this optimization if we're casting a function pointer - type on targets that require function pointer canonicalization. */ - if (targetm.have_canonicalize_funcptr_for_compare () - && TREE_CODE (inner_type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE) - return NULL_TREE; - - if (TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type)) - return NULL_TREE; - - if (TREE_CODE (arg1) != INTEGER_CST - && !(CONVERT_EXPR_P (arg1) - && TREE_TYPE (TREE_OPERAND (arg1, 0)) == inner_type)) - return NULL_TREE; - - if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type) - && code != NE_EXPR - && code != EQ_EXPR) - return NULL_TREE; - - if (POINTER_TYPE_P (inner_type) != POINTER_TYPE_P (outer_type)) - return NULL_TREE; - - if (TREE_CODE (arg1) == INTEGER_CST) - arg1 = force_fit_type (inner_type, wi::to_widest (arg1), 0, - TREE_OVERFLOW (arg1)); - else - arg1 = fold_convert_loc (loc, inner_type, arg1); - - return fold_build2_loc (loc, code, type, arg0_inner, arg1); -} - /* Fold A < X && A + 1 > Y to A < X && A >= Y. Normally A + 1 > Y means A >= Y && A != MAX, but in this case we know that @@ -8813,22 +8671,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type, if (tem) return tem; - if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE - && CONVERT_EXPR_P (arg0)) - { - /* If we are widening one operand of an integer comparison, - see if the other operand is similarly being widened. Perhaps we - can do the comparison in the narrower type. */ - tem = fold_widened_comparison (loc, code, type, arg0, arg1); - if (tem) - return tem; - - /* Or if we are changing signedness. */ - tem = fold_sign_changed_comparison (loc, code, type, arg0, arg1); - if (tem) - return tem; - } - /* If this is comparing a constant with a MIN_EXPR or a MAX_EXPR of a constant, we can simplify it. */ if (TREE_CODE (arg1) == INTEGER_CST diff --git a/gcc/generic-match-head.c b/gcc/generic-match-head.c index 66615a4fab4..da7abc66964 100644 --- a/gcc/generic-match-head.c +++ b/gcc/generic-match-head.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-dfa.h" #include "builtins.h" #include "dumpfile.h" +#include "target.h" #include "generic-match.h" /* Routine to determine if the types T1 and T2 are effectively diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c index 875b7246575..2b1423806bc 100644 --- a/gcc/gimple-match-head.c +++ b/gcc/gimple-match-head.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-dfa.h" #include "builtins.h" #include "dumpfile.h" +#include "target.h" #include "gimple-match.h" diff --git a/gcc/match.pd b/gcc/match.pd index a3fba51969e..c335ada567e 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1664,6 +1664,62 @@ along with GCC; see the file COPYING3. If not see (if (tem && !TREE_OVERFLOW (tem)) (scmp @0 { tem; })))))) +/* From fold_sign_changed_comparison and fold_widened_comparison. */ +(for cmp (simple_comparison) + (simplify + (cmp (convert@0 @00) (convert?@1 @10)) + (if (TREE_CODE (TREE_TYPE (@0)) == INTEGER_TYPE + /* Disable this optimization if we're casting a function pointer + type on targets that require function pointer canonicalization. */ + && !(targetm.have_canonicalize_funcptr_for_compare () + && TREE_CODE (TREE_TYPE (@00)) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (TREE_TYPE (@00))) == FUNCTION_TYPE)) + (if (TYPE_PRECISION (TREE_TYPE (@00)) == TYPE_PRECISION (TREE_TYPE (@0)) + && (TREE_CODE (@10) == INTEGER_CST + || (@1 != @10 && types_match (TREE_TYPE (@10), TREE_TYPE (@00)))) + && (TYPE_UNSIGNED (TREE_TYPE (@00)) == TYPE_UNSIGNED (TREE_TYPE (@0)) + || cmp == NE_EXPR + || cmp == EQ_EXPR) + && (POINTER_TYPE_P (TREE_TYPE (@00)) == POINTER_TYPE_P (TREE_TYPE (@0)))) + /* ??? The special-casing of INTEGER_CST conversion was in the original + code and here to avoid a spurious overflow flag on the resulting + constant which fold_convert produces. */ + (if (TREE_CODE (@1) == INTEGER_CST) + (cmp @00 { force_fit_type (TREE_TYPE (@00), wi::to_widest (@1), 0, + TREE_OVERFLOW (@1)); }) + (cmp @00 (convert @1))) + + (if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (TREE_TYPE (@00))) + /* If possible, express the comparison in the shorter mode. */ + (if ((cmp == EQ_EXPR || cmp == NE_EXPR + || TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (TREE_TYPE (@00))) + && (types_match (TREE_TYPE (@10), TREE_TYPE (@00)) + || ((TYPE_PRECISION (TREE_TYPE (@00)) + >= TYPE_PRECISION (TREE_TYPE (@10))) + && (TYPE_UNSIGNED (TREE_TYPE (@00)) + == TYPE_UNSIGNED (TREE_TYPE (@10)))) + || (TREE_CODE (@10) == INTEGER_CST + && (TREE_CODE (TREE_TYPE (@00)) == INTEGER_TYPE + || TREE_CODE (TREE_TYPE (@00)) == BOOLEAN_TYPE) + && int_fits_type_p (@10, TREE_TYPE (@00))))) + (cmp @00 (convert @10)) + (if (TREE_CODE (@10) == INTEGER_CST + && TREE_CODE (TREE_TYPE (@00)) == INTEGER_TYPE + && !int_fits_type_p (@10, TREE_TYPE (@00))) + (with + { + tree min = lower_bound_in_type (TREE_TYPE (@10), TREE_TYPE (@00)); + tree max = upper_bound_in_type (TREE_TYPE (@10), TREE_TYPE (@00)); + bool above = integer_nonzerop (const_binop (LT_EXPR, type, max, @10)); + bool below = integer_nonzerop (const_binop (LT_EXPR, type, @10, min)); + } + (if (above || below) + (if (cmp == EQ_EXPR || cmp == NE_EXPR) + { constant_boolean_node (cmp == EQ_EXPR ? false : true, type); } + (if (cmp == LT_EXPR || cmp == LE_EXPR) + { constant_boolean_node (above ? true : false, type); } + (if (cmp == GT_EXPR || cmp == GE_EXPR) + { constant_boolean_node (above ? false : true, type); })))))))))))) /* Equality compare simplifications from fold_binary */ (for cmp (eq ne) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a3ae9d5b39c..8bc93412998 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-07-16 Richard Biener + + * gcc.dg/tree-ssa/pr21031.c: Adjust. + 2015-07-16 Uros Bizjak PR target/66866 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21031.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21031.c index f39c1276c7e..a6f5b6e8848 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr21031.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21031.c @@ -3,7 +3,7 @@ Make sure that a != 0 is propagated into the "if" statement. */ /* { dg-do compile } */ -/* { dg-options "-O1 -fdump-tree-forwprop1-details" } */ +/* { dg-options "-O1 -fdump-tree-forwprop1" } */ int foo (int a) @@ -16,4 +16,4 @@ foo (int a) return 0; } -/* { dg-final { scan-tree-dump-times "Replaced" 2 "forwprop1" } } */ +/* { dg-final { scan-tree-dump "if \\(a_\[0-9\]+\\(D\\) != 0\\)" "forwprop1" } } */