diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/init.c | 3 | ||||
-rw-r--r-- | gcc/fold-const.c | 98 | ||||
-rw-r--r-- | gcc/match.pd | 17 |
5 files changed, 62 insertions, 67 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 75530ae..2f8ec69 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-07-24 Richard Biener <rguenther@suse.de> + + * fold-const.c (maybe_canonicalize_comparison_1): Move + A code CST canonicalization ... + * match.pd: ... to a pattern here. + 2015-07-24 Jiong Wang <jiong.wang@arm.com> Revert: diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 51766ea..df805e6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2015-07-24 Richard Biener <rguenther@suse.de> + + * init.c (build_vec_init): Build iterator bound in the same + type as the iterator. + 2015-07-23 Marek Polacek <polacek@redhat.com> PR c++/66572 diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 01194d6..dbbe7d5 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3599,7 +3599,8 @@ build_vec_init (tree base, tree maxindex, tree init, if (length_check) { - tree nelts = size_int (CONSTRUCTOR_NELTS (init) - 1); + tree nelts = build_int_cst (ptrdiff_type_node, + CONSTRUCTOR_NELTS (init) - 1); if (TREE_CODE (atype) != ARRAY_TYPE) { if (flag_exceptions) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 54a6b13..c404857 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8092,26 +8092,21 @@ maybe_canonicalize_comparison_1 (location_t loc, enum tree_code code, tree type, enum tree_code code0 = TREE_CODE (arg0); tree t, cst0 = NULL_TREE; int sgn0; - bool swap = false; - - /* Match A +- CST code arg1 and CST code arg1. We can change the - first form only if overflow is undefined. */ - if (!(((ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0)) - && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))) - /* In principle pointers also have undefined overflow behavior, - but that causes problems elsewhere. */ - && !POINTER_TYPE_P (TREE_TYPE (arg0)) - && (code0 == MINUS_EXPR - || code0 == PLUS_EXPR) - && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) - || code0 == INTEGER_CST)) + + /* Match A +- CST code arg1. We can change this only if overflow + is undefined. */ + if (!((ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0)) + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))) + /* In principle pointers also have undefined overflow behavior, + but that causes problems elsewhere. */ + && !POINTER_TYPE_P (TREE_TYPE (arg0)) + && (code0 == MINUS_EXPR + || code0 == PLUS_EXPR) + && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)) return NULL_TREE; /* Identify the constant in arg0 and its sign. */ - if (code0 == INTEGER_CST) - cst0 = arg0; - else - cst0 = TREE_OPERAND (arg0, 1); + cst0 = TREE_OPERAND (arg0, 1); sgn0 = tree_int_cst_sgn (cst0); /* Overflowed constants and zero will cause problems. */ @@ -8121,47 +8116,25 @@ maybe_canonicalize_comparison_1 (location_t loc, enum tree_code code, tree type, /* See if we can reduce the magnitude of the constant in arg0 by changing the comparison code. */ - if (code0 == INTEGER_CST) - { - /* CST <= arg1 -> CST-1 < arg1. */ - if (code == LE_EXPR && sgn0 == 1) - code = LT_EXPR; - /* -CST < arg1 -> -CST-1 <= arg1. */ - else if (code == LT_EXPR && sgn0 == -1) - code = LE_EXPR; - /* CST > arg1 -> CST-1 >= arg1. */ - else if (code == GT_EXPR && sgn0 == 1) - code = GE_EXPR; - /* -CST >= arg1 -> -CST-1 > arg1. */ - else if (code == GE_EXPR && sgn0 == -1) - code = GT_EXPR; - else - return NULL_TREE; - /* arg1 code' CST' might be more canonical. */ - swap = true; - } + /* A - CST < arg1 -> A - CST-1 <= arg1. */ + if (code == LT_EXPR + && code0 == ((sgn0 == -1) ? PLUS_EXPR : MINUS_EXPR)) + code = LE_EXPR; + /* A + CST > arg1 -> A + CST-1 >= arg1. */ + else if (code == GT_EXPR + && code0 == ((sgn0 == -1) ? MINUS_EXPR : PLUS_EXPR)) + code = GE_EXPR; + /* A + CST <= arg1 -> A + CST-1 < arg1. */ + else if (code == LE_EXPR + && code0 == ((sgn0 == -1) ? MINUS_EXPR : PLUS_EXPR)) + code = LT_EXPR; + /* A - CST >= arg1 -> A - CST-1 > arg1. */ + else if (code == GE_EXPR + && code0 == ((sgn0 == -1) ? PLUS_EXPR : MINUS_EXPR)) + code = GT_EXPR; else - { - /* A - CST < arg1 -> A - CST-1 <= arg1. */ - if (code == LT_EXPR - && code0 == ((sgn0 == -1) ? PLUS_EXPR : MINUS_EXPR)) - code = LE_EXPR; - /* A + CST > arg1 -> A + CST-1 >= arg1. */ - else if (code == GT_EXPR - && code0 == ((sgn0 == -1) ? MINUS_EXPR : PLUS_EXPR)) - code = GE_EXPR; - /* A + CST <= arg1 -> A + CST-1 < arg1. */ - else if (code == LE_EXPR - && code0 == ((sgn0 == -1) ? MINUS_EXPR : PLUS_EXPR)) - code = LT_EXPR; - /* A - CST >= arg1 -> A - CST-1 > arg1. */ - else if (code == GE_EXPR - && code0 == ((sgn0 == -1) ? PLUS_EXPR : MINUS_EXPR)) - code = GT_EXPR; - else - return NULL_TREE; - *strict_overflow_p = true; - } + return NULL_TREE; + *strict_overflow_p = true; /* Now build the constant reduced in magnitude. But not if that would produce one outside of its types range. */ @@ -8172,21 +8145,14 @@ maybe_canonicalize_comparison_1 (location_t loc, enum tree_code code, tree type, || (sgn0 == -1 && TYPE_MAX_VALUE (TREE_TYPE (cst0)) && tree_int_cst_equal (cst0, TYPE_MAX_VALUE (TREE_TYPE (cst0)))))) - /* We cannot swap the comparison here as that would cause us to - endlessly recurse. */ return NULL_TREE; t = int_const_binop (sgn0 == -1 ? PLUS_EXPR : MINUS_EXPR, cst0, build_int_cst (TREE_TYPE (cst0), 1)); - if (code0 != INTEGER_CST) - t = fold_build2_loc (loc, code0, TREE_TYPE (arg0), TREE_OPERAND (arg0, 0), t); + t = fold_build2_loc (loc, code0, TREE_TYPE (arg0), TREE_OPERAND (arg0, 0), t); t = fold_convert (TREE_TYPE (arg1), t); - /* If swapping might yield to a more canonical form, do so. */ - if (swap) - return fold_build2_loc (loc, swap_tree_comparison (code), type, arg1, t); - else - return fold_build2_loc (loc, code, type, t, arg1); + return fold_build2_loc (loc, code, type, t, arg1); } /* Canonicalize the comparison ARG0 CODE ARG1 with type TYPE with undefined diff --git a/gcc/match.pd b/gcc/match.pd index ccc5165..398378d 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1371,6 +1371,23 @@ along with GCC; see the file COPYING3. If not see /* Simplifications of comparisons. */ +/* See if we can reduce the magnitude of a constant involved in a + comparison by changing the comparison code. This is a canonicalization + formerly done by maybe_canonicalize_comparison_1. */ +(for cmp (le gt) + acmp (lt ge) + (simplify + (cmp @0 INTEGER_CST@1) + (if (tree_int_cst_sgn (@1) == -1) + (acmp @0 { wide_int_to_tree (TREE_TYPE (@1), wi::add (@1, 1)); })))) +(for cmp (ge lt) + acmp (gt le) + (simplify + (cmp @0 INTEGER_CST@1) + (if (tree_int_cst_sgn (@1) == 1) + (acmp @0 { wide_int_to_tree (TREE_TYPE (@1), wi::sub (@1, 1)); })))) + + /* We can simplify a logical negation of a comparison to the inverted comparison. As we cannot compute an expression operator using invert_tree_comparison we have to simulate |