diff options
author | Richard Guenther <rguenther@suse.de> | 2011-05-04 09:04:53 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2011-05-04 09:04:53 +0000 |
commit | d35936ab70051f5bb7e3e7b9d069cc648f5dac6c (patch) | |
tree | 5c3cd9ce515aaedc793b4255fad9d3b6f6f3f621 /gcc/fold-const.c | |
parent | 8992c063a6de3bce68f41c42147e829bf0fd671f (diff) | |
download | gcc-d35936ab70051f5bb7e3e7b9d069cc648f5dac6c.zip gcc-d35936ab70051f5bb7e3e7b9d069cc648f5dac6c.tar.gz gcc-d35936ab70051f5bb7e3e7b9d069cc648f5dac6c.tar.bz2 |
tree.h (int_const_binop): Remove notrunc argument.
2011-05-04 Richard Guenther <rguenther@suse.de>
* tree.h (int_const_binop): Remove notrunc argument.
* fold-const.c (int_const_binop): Remove notrunc argument. Always
create integer constants that are properly truncated.
(extract_muldiv_1): Expand one notrunc int_const_binop caller.
(const_binop): Remove zero notrunc argument to int_const_binop.
(size_binop_loc): Likewise.
(fold_div_compare): Likewise.
(maybe_canonicalize_comparison_1): Likewise.
(fold_comparison): Likewise.
(fold_binary_loc): Likewise.
(multiple_of_p): Likewise.
* expr.c (store_constructor): Likewise.
* gimple-fold.c (maybe_fold_offset_to_array_ref): Likewise.
(maybe_fold_stmt_addition): Likewise.
* ipa-prop.c (ipa_modify_call_arguments): Likewise.
* stor-layout.c (layout_type): Likewise.
* tree-data-ref.c (tree_fold_divides_p): Likewise.
* tree-sra.c (build_ref_for_offset): Likewise.
(build_user_friendly_ref_for_offset): Likewise.
* tree-ssa-address.c (maybe_fold_tmr): Likewise.
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Likewise.
* tree-ssa-loop-niter.c (inverse): Likewise.
* tree-ssa-pre.c (create_component_ref_by_pieces_1): Likewise.
* tree-ssa.c (maybe_rewrite_mem_ref_base): Likewise.
* tree-switch-conversion.c (check_range): Likewise.
(build_constructors): Likewise.
* tree-vect-generic.c (expand_vector_piecewise): Likewise.
* tree-vrp.c (set_and_canonicalize_value_range): Likewise.
(extract_range_from_assert): Likewise.
(vrp_int_const_binop): Likewise.
(extract_range_from_binary_expr): Likewise.
(extract_range_from_unary_expr): Likewise.
(check_array_ref): Likewise.
(find_case_label_range): Likewise.
(simplify_div_or_mod_using_ranges): Likewise.
* tree-cfg.c (group_case_labels_stmt): Use double-ints for
comparing case labels for merging.
ada/
* gcc-interface/trans.c (gnat_to_gnu): Remove zero notrunc argument to
int_const_binop.
(pos_to_constructor): Likewise.
fortran/
* trans-types.c (gfc_get_array_type_bounds): Remove zero notrunc
argument to int_const_binop.
From-SVN: r173356
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 98 |
1 files changed, 50 insertions, 48 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 1daebbd..f7d4e5f 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -936,12 +936,10 @@ int_binop_types_match_p (enum tree_code code, const_tree type1, const_tree type2 /* Combine two integer constants ARG1 and ARG2 under operation CODE to produce a new constant. Return NULL_TREE if we don't know how - to evaluate CODE at compile-time. - - If NOTRUNC is nonzero, do not truncate the result to fit the data type. */ + to evaluate CODE at compile-time. */ tree -int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2, int notrunc) +int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2) { double_int op1, op2, res, tmp; tree t; @@ -1083,22 +1081,9 @@ int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2, int notr return NULL_TREE; } - if (notrunc) - { - t = build_int_cst_wide (TREE_TYPE (arg1), res.low, res.high); - - /* Propagate overflow flags ourselves. */ - if (((!uns || is_sizetype) && overflow) - | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2)) - { - t = copy_node (t); - TREE_OVERFLOW (t) = 1; - } - } - else - t = force_fit_type_double (TREE_TYPE (arg1), res, 1, - ((!uns || is_sizetype) && overflow) - | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2)); + t = force_fit_type_double (TREE_TYPE (arg1), res, 1, + ((!uns || is_sizetype) && overflow) + | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2)); return t; } @@ -1119,7 +1104,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2) STRIP_NOPS (arg2); if (TREE_CODE (arg1) == INTEGER_CST) - return int_const_binop (code, arg1, arg2, 0); + return int_const_binop (code, arg1, arg2); if (TREE_CODE (arg1) == REAL_CST) { @@ -1464,7 +1449,7 @@ size_binop_loc (location_t loc, enum tree_code code, tree arg0, tree arg1) } /* Handle general case of two integer constants. */ - return int_const_binop (code, arg0, arg1, 0); + return int_const_binop (code, arg0, arg1); } return fold_build2_loc (loc, code, type, arg0, arg1); @@ -5873,16 +5858,33 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type, /* If these are the same operation types, we can associate them assuming no overflow. */ - if (tcode == code - && 0 != (t1 = int_const_binop (MULT_EXPR, - fold_convert (ctype, op1), - fold_convert (ctype, c), 1)) - && 0 != (t1 = force_fit_type_double (ctype, tree_to_double_int (t1), - (TYPE_UNSIGNED (ctype) - && tcode != MULT_EXPR) ? -1 : 1, - TREE_OVERFLOW (t1))) - && !TREE_OVERFLOW (t1)) - return fold_build2 (tcode, ctype, fold_convert (ctype, op0), t1); + if (tcode == code) + { + double_int mul; + int overflow_p; + mul = double_int_mul_with_sign + (double_int_ext + (tree_to_double_int (op1), + TYPE_PRECISION (ctype), TYPE_UNSIGNED (ctype)), + double_int_ext + (tree_to_double_int (c), + TYPE_PRECISION (ctype), TYPE_UNSIGNED (ctype)), + false, &overflow_p); + overflow_p = (((!TYPE_UNSIGNED (ctype) + || (TREE_CODE (ctype) == INTEGER_TYPE + && TYPE_IS_SIZETYPE (ctype))) + && overflow_p) + | TREE_OVERFLOW (c) | TREE_OVERFLOW (op1)); + if (!double_int_fits_to_tree_p (ctype, mul) + && ((TYPE_UNSIGNED (ctype) && tcode != MULT_EXPR) + || !TYPE_UNSIGNED (ctype) + || (TREE_CODE (ctype) == INTEGER_TYPE + && TYPE_IS_SIZETYPE (ctype)))) + overflow_p = 1; + if (!overflow_p) + return fold_build2 (tcode, ctype, fold_convert (ctype, op0), + double_int_to_tree (ctype, mul)); + } /* If these operations "cancel" each other, we have the main optimizations of this pass, which occur when either constant is a @@ -6287,7 +6289,7 @@ fold_div_compare (location_t loc, int overflow; /* We have to do this the hard way to detect unsigned overflow. - prod = int_const_binop (MULT_EXPR, arg01, arg1, 0); */ + prod = int_const_binop (MULT_EXPR, arg01, arg1); */ overflow = mul_double_with_sign (TREE_INT_CST_LOW (arg01), TREE_INT_CST_HIGH (arg01), TREE_INT_CST_LOW (arg1), @@ -6299,10 +6301,10 @@ fold_div_compare (location_t loc, if (unsigned_p) { tmp = int_const_binop (MINUS_EXPR, arg01, - build_int_cst (TREE_TYPE (arg01), 1), 0); + build_int_cst (TREE_TYPE (arg01), 1)); lo = prod; - /* Likewise hi = int_const_binop (PLUS_EXPR, prod, tmp, 0). */ + /* Likewise hi = int_const_binop (PLUS_EXPR, prod, tmp). */ overflow = add_double_with_sign (TREE_INT_CST_LOW (prod), TREE_INT_CST_HIGH (prod), TREE_INT_CST_LOW (tmp), @@ -6314,12 +6316,12 @@ fold_div_compare (location_t loc, else if (tree_int_cst_sgn (arg01) >= 0) { tmp = int_const_binop (MINUS_EXPR, arg01, - build_int_cst (TREE_TYPE (arg01), 1), 0); + build_int_cst (TREE_TYPE (arg01), 1)); switch (tree_int_cst_sgn (arg1)) { case -1: neg_overflow = true; - lo = int_const_binop (MINUS_EXPR, prod, tmp, 0); + lo = int_const_binop (MINUS_EXPR, prod, tmp); hi = prod; break; @@ -6329,7 +6331,7 @@ fold_div_compare (location_t loc, break; case 1: - hi = int_const_binop (PLUS_EXPR, prod, tmp, 0); + hi = int_const_binop (PLUS_EXPR, prod, tmp); lo = prod; break; @@ -6343,11 +6345,11 @@ fold_div_compare (location_t loc, code = swap_tree_comparison (code); tmp = int_const_binop (PLUS_EXPR, arg01, - build_int_cst (TREE_TYPE (arg01), 1), 0); + build_int_cst (TREE_TYPE (arg01), 1)); switch (tree_int_cst_sgn (arg1)) { case -1: - hi = int_const_binop (MINUS_EXPR, prod, tmp, 0); + hi = int_const_binop (MINUS_EXPR, prod, tmp); lo = prod; break; @@ -6358,7 +6360,7 @@ fold_div_compare (location_t loc, case 1: neg_overflow = true; - lo = int_const_binop (PLUS_EXPR, prod, tmp, 0); + lo = int_const_binop (PLUS_EXPR, prod, tmp); hi = prod; break; @@ -8368,7 +8370,7 @@ maybe_canonicalize_comparison_1 (location_t loc, enum tree_code code, tree type, return NULL_TREE; t = int_const_binop (sgn0 == -1 ? PLUS_EXPR : MINUS_EXPR, - cst0, build_int_cst (TREE_TYPE (cst0), 1), 0); + 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); @@ -8803,7 +8805,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type, of lower absolute value than before. */ cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1) ? MINUS_EXPR : PLUS_EXPR, - const2, const1, 0); + const2, const1); if (!TREE_OVERFLOW (cst) && tree_int_cst_compare (const2, cst) == tree_int_cst_sgn (const2)) { @@ -8817,7 +8819,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type, cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1) ? MINUS_EXPR : PLUS_EXPR, - const1, const2, 0); + const1, const2); if (!TREE_OVERFLOW (cst) && tree_int_cst_compare (const1, cst) == tree_int_cst_sgn (const1)) { @@ -9458,7 +9460,7 @@ fold_binary_loc (location_t loc, return fold_build2 (MEM_REF, type, TREE_OPERAND (iref, 0), int_const_binop (PLUS_EXPR, arg1, - TREE_OPERAND (iref, 1), 0)); + TREE_OPERAND (iref, 1))); } /* MEM[&a.b, CST2] -> MEM[&a, offsetof (a, b) + CST2]. */ @@ -9474,7 +9476,7 @@ fold_binary_loc (location_t loc, return fold_build2 (MEM_REF, type, build_fold_addr_expr (base), int_const_binop (PLUS_EXPR, arg1, - size_int (coffset), 0)); + size_int (coffset))); } return NULL_TREE; @@ -11815,7 +11817,7 @@ fold_binary_loc (location_t loc, arg00 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); lshift = build_int_cst (type, -1); - lshift = int_const_binop (code, lshift, arg1, 0); + lshift = int_const_binop (code, lshift, arg1); return fold_build2_loc (loc, BIT_AND_EXPR, type, arg00, lshift); } @@ -14371,7 +14373,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom) || tree_int_cst_sgn (bottom) < 0))) return 0; return integer_zerop (int_const_binop (TRUNC_MOD_EXPR, - top, bottom, 0)); + top, bottom)); default: return 0; |