This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][18/n] Remove GENERIC stmt combining from SCCVN
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 24 Jul 2015 10:49:25 +0200 (CEST)
- Subject: [PATCH][18/n] Remove GENERIC stmt combining from SCCVN
- Authentication-results: sourceware.org; auth=none
I have to re-test the following because of an exposed bug in the C++
frontend which fed fold_binary with a signed long < sizetype compare
with mismatched types.
The patch moves canonicalization of comparison codes to minimize
an involved constant, like X <= 5 to X < 4, to match.pd.
The C++ part I consider obvious if testing doesn't show any issues.
Bootstrapped and tested on x86_64-unknown-linux-gnu with
g++.dg/cpp0x/bad_array_new2.C ICEing because of the mismatched operands
(formerly the fold-const.c variant of the canonicalization "fixed"
things up).
Richard.
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.
cp/
* init.c (build_vec_init): Build iterator bound in the same
type as the iterator.
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c (revision 226112)
+++ gcc/fold-const.c (working copy)
@@ -8092,26 +7970,21 @@ maybe_canonicalize_comparison_1 (locatio
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 +7994,25 @@ maybe_canonicalize_comparison_1 (locatio
/* 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 +8023,14 @@ maybe_canonicalize_comparison_1 (locatio
|| (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
Index: gcc/match.pd
===================================================================
--- gcc/match.pd (revision 226112)
+++ gcc/match.pd (working copy)
@@ -1356,6 +1396,23 @@ (define_operator_list CBRT BUILT_IN_CBRT
/* 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
Index: gcc/cp/init.c
===================================================================
--- gcc/cp/init.c (revision 226110)
+++ gcc/cp/init.c (working copy)
@@ -3599,7 +3599,8 @@ build_vec_init (tree base, tree maxindex
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)