From: rsandifo Date: Tue, 29 Oct 2013 19:18:38 +0000 (+0000) Subject: Make ordered comparisons enforce the same type rules as equality comparisons. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cd9b55160a035e5bfe8a9a455c00b414846d7418;p=thirdparty%2Fgcc.git Make ordered comparisons enforce the same type rules as equality comparisons. Get rid of INT_CST_LT_UNSIGNED. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@204175 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index cbffd3370fa2..fe70d54c8ab3 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -4101,20 +4101,10 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr, maxval = convert (*restype_ptr, maxval); } - if (unsignedp && unsignedp0) - { - min_gt = INT_CST_LT_UNSIGNED (primop1, minval); - max_gt = INT_CST_LT_UNSIGNED (primop1, maxval); - min_lt = INT_CST_LT_UNSIGNED (minval, primop1); - max_lt = INT_CST_LT_UNSIGNED (maxval, primop1); - } - else - { - min_gt = INT_CST_LT (primop1, minval); - max_gt = INT_CST_LT (primop1, maxval); - min_lt = INT_CST_LT (minval, primop1); - max_lt = INT_CST_LT (maxval, primop1); - } + min_gt = INT_CST_LT (primop1, minval); + max_gt = INT_CST_LT (primop1, maxval); + min_lt = INT_CST_LT (minval, primop1); + max_lt = INT_CST_LT (maxval, primop1); val = 0; /* This used to be a switch, but Genix compiler can't handle that. */ diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c index 62f738d7beda..367bed635a16 100644 --- a/gcc/c-family/c-lex.c +++ b/gcc/c-family/c-lex.c @@ -48,9 +48,9 @@ static tree interpret_float (const cpp_token *, unsigned int, const char *, enum overflow_type *); static tree interpret_fixed (const cpp_token *, unsigned int); static enum integer_type_kind narrowest_unsigned_type - (const wide_int &, unsigned int); + (const widest_int &, unsigned int); static enum integer_type_kind narrowest_signed_type - (const wide_int &, unsigned int); + (const widest_int &, unsigned int); static enum cpp_ttype lex_string (const cpp_token *, tree *, bool, bool); static tree lex_charconst (const cpp_token *); static void update_header_times (const char *); @@ -526,7 +526,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags, there isn't one. */ static enum integer_type_kind -narrowest_unsigned_type (const wide_int &val, unsigned int flags) +narrowest_unsigned_type (const widest_int &val, unsigned int flags) { int itk; @@ -545,7 +545,7 @@ narrowest_unsigned_type (const wide_int &val, unsigned int flags) continue; upper = TYPE_MAX_VALUE (integer_types[itk]); - if (wi::geu_p (upper, val)) + if (wi::geu_p (wi::to_widest (upper), val)) return (enum integer_type_kind) itk; } @@ -554,7 +554,7 @@ narrowest_unsigned_type (const wide_int &val, unsigned int flags) /* Ditto, but narrowest signed type. */ static enum integer_type_kind -narrowest_signed_type (const wide_int &val, unsigned int flags) +narrowest_signed_type (const widest_int &val, unsigned int flags) { int itk; @@ -573,7 +573,7 @@ narrowest_signed_type (const wide_int &val, unsigned int flags) continue; upper = TYPE_MAX_VALUE (integer_types[itk]); - if (wi::geu_p (upper, val)) + if (wi::geu_p (wi::to_widest (upper), val)) return (enum integer_type_kind) itk; } @@ -588,20 +588,18 @@ interpret_integer (const cpp_token *token, unsigned int flags, tree value, type; enum integer_type_kind itk; cpp_num integer; - cpp_options *options = cpp_get_options (parse_in); - HOST_WIDE_INT ival[2]; - wide_int wval; + HOST_WIDE_INT ival[3]; *overflow = OT_NONE; integer = cpp_interpret_integer (parse_in, token, flags); - integer = cpp_num_sign_extend (integer, options->precision); if (integer.overflow) *overflow = OT_OVERFLOW; ival[0] = integer.low; ival[1] = integer.high; - wval = wide_int::from_array (ival, 2, HOST_BITS_PER_WIDE_INT * 2); + ival[2] = 0; + widest_int wval = widest_int::from_array (ival, 3); /* The type of a constant with a U suffix is straightforward. */ if (flags & CPP_N_UNSIGNED) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 8753923348f9..c0eb1d6b8249 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6493,8 +6493,7 @@ type_passed_as (tree type) else if (targetm.calls.promote_prototypes (type) && INTEGRAL_TYPE_P (type) && COMPLETE_TYPE_P (type) - && INT_CST_LT_UNSIGNED (TYPE_SIZE (type), - TYPE_SIZE (integer_type_node))) + && INT_CST_LT (TYPE_SIZE (type), TYPE_SIZE (integer_type_node))) type = integer_type_node; return type; @@ -6534,8 +6533,7 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain) else if (targetm.calls.promote_prototypes (type) && INTEGRAL_TYPE_P (type) && COMPLETE_TYPE_P (type) - && INT_CST_LT_UNSIGNED (TYPE_SIZE (type), - TYPE_SIZE (integer_type_node))) + && INT_CST_LT (TYPE_SIZE (type), TYPE_SIZE (integer_type_node))) val = cp_perform_integral_promotions (val, complain); if ((complain & tf_warning) && warn_suggest_attribute_format) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 0cc882c26004..b90ef3fb8ed8 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5790,7 +5790,7 @@ end_of_class (tree t, int include_virtuals_p) continue; offset = end_of_base (base_binfo); - if (INT_CST_LT_UNSIGNED (result, offset)) + if (INT_CST_LT (result, offset)) result = offset; } @@ -5800,7 +5800,7 @@ end_of_class (tree t, int include_virtuals_p) vec_safe_iterate (vbases, i, &base_binfo); i++) { offset = end_of_base (base_binfo); - if (INT_CST_LT_UNSIGNED (result, offset)) + if (INT_CST_LT (result, offset)) result = offset; } @@ -5880,7 +5880,7 @@ include_empty_classes (record_layout_info rli) CLASSTYPE_AS_BASE (rli->t) != NULL_TREE); rli_size = rli_size_unit_so_far (rli); if (TREE_CODE (rli_size) == INTEGER_CST - && INT_CST_LT_UNSIGNED (rli_size, eoc)) + && INT_CST_LT (rli_size, eoc)) { if (!abi_version_at_least (2)) /* In version 1 of the ABI, the size of a class that ends with diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 59a626ceb79a..17d320db072b 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2412,7 +2412,7 @@ build_new_1 (vec **placement, tree type, tree nelts, gcc_assert (TREE_CODE (size) == INTEGER_CST); cookie_size = targetm.cxx.get_cookie_size (elt_type); gcc_assert (TREE_CODE (cookie_size) == INTEGER_CST); - gcc_checking_assert (wi::ltu_p (cookie_size, max_size)); + gcc_checking_assert (wi::ltu_p (wi::to_offset (cookie_size), max_size)); /* Unconditionally subtract the cookie size. This decreases the maximum object size and is safe even if we choose not to use a cookie after all. */ diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 4be592bb7ac5..7cfc77d1e900 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -16448,8 +16448,6 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1) { if (code == EQ_EXPR) result = tree_int_cst_equal (op0, op1); - else if (TYPE_UNSIGNED (TREE_TYPE (op0))) - result = INT_CST_LT_UNSIGNED (op0, op1); else result = INT_CST_LT (op0, op1); } diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index f9f141808e56..36d993ca5a8e 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -2834,7 +2834,7 @@ fold_array_ctor_reference (tree type, tree ctor, be larger than size of array element. */ if (!TYPE_SIZE_UNIT (type) || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST - || wi::lts_p (elt_size, TYPE_SIZE_UNIT (type))) + || wi::lts_p (elt_size, wi::to_offset (TYPE_SIZE_UNIT (type)))) return NULL_TREE; /* Compute the array index we look for. */ diff --git a/gcc/java/expr.c b/gcc/java/expr.c index 068ac29a9fad..2e7ee9dde3f2 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -1716,7 +1716,7 @@ build_field_ref (tree self_value, tree self_class, tree name) tree field_offset = byte_position (field_decl); if (! page_size) page_size = size_int (4096); - check = ! INT_CST_LT_UNSIGNED (field_offset, page_size); + check = ! INT_CST_LT (field_offset, page_size); } if (base_type != TREE_TYPE (self_value)) diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c index 1299a5cce4ec..c15c2e39db87 100644 --- a/gcc/loop-doloop.c +++ b/gcc/loop-doloop.c @@ -462,8 +462,8 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, Note that the maximum value loaded is iterations_max - 1. */ if (get_max_loop_iterations (loop, &iterations) && wi::leu_p (iterations, - wi::set_bit_in_zero (GET_MODE_PRECISION (mode) - 1, - GET_MODE_PRECISION (mode)))) + wi::set_bit_in_zero + (GET_MODE_PRECISION (mode) - 1))) nonneg = 1; break; diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 3fbd7190e835..eb2e02f7c622 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -288,7 +288,7 @@ default_cxx_get_cookie_size (tree type) sizetype_size = size_in_bytes (sizetype); type_align = size_int (TYPE_ALIGN_UNIT (type)); - if (INT_CST_LT_UNSIGNED (type_align, sizetype_size)) + if (INT_CST_LT (type_align, sizetype_size)) cookie_size = sizetype_size; else cookie_size = type_align; diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index 6f765381c241..50ce3a8d2a68 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -546,7 +546,8 @@ remove_redundant_iv_tests (struct loop *loop) || !integer_zerop (niter.may_be_zero) || !niter.niter || TREE_CODE (niter.niter) != INTEGER_CST - || !wi::ltu_p (loop->nb_iterations_upper_bound, niter.niter)) + || !wi::ltu_p (loop->nb_iterations_upper_bound, + wi::to_widest (niter.niter))) continue; if (dump_file && (dump_flags & TDF_DETAILS)) diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index e926951967ce..d0cf228c59aa 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -2520,7 +2520,7 @@ do_warn_aggressive_loop_optimizations (struct loop *loop, || loop->warned_aggressive_loop_optimizations /* Only warn if undefined behavior gives us lower estimate than the known constant bound. */ - || wi::cmpu (i_bound, loop->nb_iterations) >= 0 + || wi::cmpu (i_bound, wi::to_widest (loop->nb_iterations)) >= 0 /* And undefined behavior happens unconditionally. */ || !dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (stmt))) return; diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index 0174ee1748a4..43ca5268c582 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -848,12 +848,11 @@ is_value_included_in (tree val, tree boundary, enum tree_code cmpc) if (cmpc == EQ_EXPR) result = tree_int_cst_equal (val, boundary); else if (cmpc == LT_EXPR) - result = INT_CST_LT_UNSIGNED (val, boundary); + result = INT_CST_LT (val, boundary); else { gcc_assert (cmpc == LE_EXPR); - result = (tree_int_cst_equal (val, boundary) - || INT_CST_LT_UNSIGNED (val, boundary)); + result = INT_CST_LE (val, boundary); } } else diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index b77c8b3bc976..8706f95f5d0a 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1422,7 +1422,7 @@ non_rewritable_mem_ref_base (tree ref) && useless_type_conversion_p (TREE_TYPE (base), TREE_TYPE (TREE_TYPE (decl))) && wi::fits_uhwi_p (mem_ref_offset (base)) - && wi::gtu_p (TYPE_SIZE_UNIT (TREE_TYPE (decl)), + && wi::gtu_p (wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))), mem_ref_offset (base)) && multiple_of_p (sizetype, TREE_OPERAND (base, 1), TYPE_SIZE_UNIT (TREE_TYPE (base)))) diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index b88c6e4949fc..0e5774936327 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1127,15 +1127,7 @@ operand_less_p (tree val, tree val2) { /* LT is folded faster than GE and others. Inline the common case. */ if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST) - { - if (TYPE_UNSIGNED (TREE_TYPE (val))) - return INT_CST_LT_UNSIGNED (val, val2); - else - { - if (INT_CST_LT (val, val2)) - return 1; - } - } + return INT_CST_LT (val, val2); else { tree tcmp; diff --git a/gcc/tree.c b/gcc/tree.c index dfb9fca1b05e..e25161a4f807 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -6899,26 +6899,7 @@ tree_int_cst_equal (const_tree t1, const_tree t2) int tree_int_cst_lt (const_tree t1, const_tree t2) { - if (t1 == t2) - return 0; - - if (TYPE_UNSIGNED (TREE_TYPE (t1)) != TYPE_UNSIGNED (TREE_TYPE (t2))) - { - int t1_sgn = tree_int_cst_sgn (t1); - int t2_sgn = tree_int_cst_sgn (t2); - - if (t1_sgn < t2_sgn) - return 1; - else if (t1_sgn > t2_sgn) - return 0; - /* Otherwise, both are non-negative, so we compare them as - unsigned just in case one of them would overflow a signed - type. */ - } - else if (!TYPE_UNSIGNED (TREE_TYPE (t1))) - return INT_CST_LT (t1, t2); - - return INT_CST_LT_UNSIGNED (t1, t2); + return INT_CST_LT (t1, t2); } /* Returns -1 if T1 < T2, 0 if T1 == T2, and 1 if T1 > T2. */ @@ -6926,12 +6907,7 @@ tree_int_cst_lt (const_tree t1, const_tree t2) int tree_int_cst_compare (const_tree t1, const_tree t2) { - if (tree_int_cst_lt (t1, t2)) - return -1; - else if (tree_int_cst_lt (t2, t1)) - return 1; - else - return 0; + return wi::cmps (wi::to_widest (t1), wi::to_widest (t2)); } /* Return the HOST_WIDE_INT least significant bits of T, a sizetype @@ -8667,18 +8643,7 @@ retry: /* Check if c >= type_low_bound. */ if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST) { - wd = type_low_bound; - if (sgn_c != TYPE_SIGN (TREE_TYPE (type_low_bound))) - { - int c_neg = (sgn_c == SIGNED && wi::neg_p (wc)); - int t_neg = (sgn_c == UNSIGNED && wi::neg_p (wd)); - - if (c_neg && !t_neg) - return false; - if ((c_neg || !t_neg) && wi::ltu_p (wc, wd)) - return false; - } - else if (wi::lt_p (wc, wd, sgn_c)) + if (INT_CST_LT (c, type_low_bound)) return false; ok_for_low_bound = true; } @@ -8688,18 +8653,7 @@ retry: /* Check if c <= type_high_bound. */ if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST) { - wd = type_high_bound; - if (sgn_c != TYPE_SIGN (TREE_TYPE (type_high_bound))) - { - int c_neg = (sgn_c == SIGNED && wi::neg_p (wc)); - int t_neg = (sgn_c == UNSIGNED && wi::neg_p (wd)); - - if (t_neg && !c_neg) - return false; - if ((t_neg || !c_neg) && wi::gtu_p (wc, wd)) - return false; - } - else if (wi::gt_p (wc, wd, sgn_c)) + if (INT_CST_LT (type_high_bound, c)) return false; ok_for_high_bound = true; } diff --git a/gcc/tree.h b/gcc/tree.h index 111ac1f560b3..909afd63f2ba 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -877,18 +877,15 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, /* Define additional fields and accessors for nodes representing constants. */ -#define INT_CST_LT(A, B) \ - (wi::lts_p (A, B)) - -#define INT_CST_LT_UNSIGNED(A, B) \ - (wi::ltu_p (A, B)) - #define TREE_INT_CST_NUNITS(NODE) \ (INTEGER_CST_CHECK (NODE)->base.u.int_length.unextended) #define TREE_INT_CST_EXT_NUNITS(NODE) \ (INTEGER_CST_CHECK (NODE)->base.u.int_length.extended) #define TREE_INT_CST_ELT(NODE, I) TREE_INT_CST_ELT_CHECK (NODE, I) +#define INT_CST_LT(A, B) (wi::lts_p (wi::to_widest (A), wi::to_widest (B))) +#define INT_CST_LE(A, B) (wi::les_p (wi::to_widest (A), wi::to_widest (B))) + #define TREE_REAL_CST_PTR(NODE) (REAL_CST_CHECK (NODE)->real_cst.real_cst_ptr) #define TREE_REAL_CST(NODE) (*TREE_REAL_CST_PTR (NODE)) diff --git a/gcc/wide-int.cc b/gcc/wide-int.cc index 9ef96e5cf540..a4c4d2468df8 100644 --- a/gcc/wide-int.cc +++ b/gcc/wide-int.cc @@ -416,22 +416,19 @@ wi::eq_p_large (const HOST_WIDE_INT *op0, unsigned int op0len, /* Return true if OP0 < OP1 using signed comparisons. */ bool wi::lts_p_large (const HOST_WIDE_INT *op0, unsigned int op0len, - unsigned int p0, - const HOST_WIDE_INT *op1, unsigned int op1len, - unsigned int p1) + unsigned int precision, + const HOST_WIDE_INT *op1, unsigned int op1len) { HOST_WIDE_INT s0, s1; unsigned HOST_WIDE_INT u0, u1; - unsigned int blocks_needed0 = BLOCKS_NEEDED (p0); - unsigned int blocks_needed1 = BLOCKS_NEEDED (p1); - unsigned int small_prec0 = p0 & (HOST_BITS_PER_WIDE_INT - 1); - unsigned int small_prec1 = p1 & (HOST_BITS_PER_WIDE_INT - 1); + unsigned int blocks_needed = BLOCKS_NEEDED (precision); + unsigned int small_prec = precision & (HOST_BITS_PER_WIDE_INT - 1); int l = MAX (op0len - 1, op1len - 1); /* Only the top block is compared as signed. The rest are unsigned comparisons. */ - s0 = selt (op0, op0len, blocks_needed0, small_prec0, l, SIGNED); - s1 = selt (op1, op1len, blocks_needed1, small_prec1, l, SIGNED); + s0 = selt (op0, op0len, blocks_needed, small_prec, l, SIGNED); + s1 = selt (op1, op1len, blocks_needed, small_prec, l, SIGNED); if (s0 < s1) return true; if (s0 > s1) @@ -440,8 +437,8 @@ wi::lts_p_large (const HOST_WIDE_INT *op0, unsigned int op0len, l--; while (l >= 0) { - u0 = selt (op0, op0len, blocks_needed0, small_prec0, l, SIGNED); - u1 = selt (op1, op1len, blocks_needed1, small_prec1, l, SIGNED); + u0 = selt (op0, op0len, blocks_needed, small_prec, l, SIGNED); + u1 = selt (op1, op1len, blocks_needed, small_prec, l, SIGNED); if (u0 < u1) return true; @@ -457,22 +454,19 @@ wi::lts_p_large (const HOST_WIDE_INT *op0, unsigned int op0len, signed compares. */ int wi::cmps_large (const HOST_WIDE_INT *op0, unsigned int op0len, - unsigned int p0, - const HOST_WIDE_INT *op1, unsigned int op1len, - unsigned int p1) + unsigned int precision, + const HOST_WIDE_INT *op1, unsigned int op1len) { HOST_WIDE_INT s0, s1; unsigned HOST_WIDE_INT u0, u1; - unsigned int blocks_needed0 = BLOCKS_NEEDED (p0); - unsigned int blocks_needed1 = BLOCKS_NEEDED (p1); - unsigned int small_prec0 = p0 & (HOST_BITS_PER_WIDE_INT - 1); - unsigned int small_prec1 = p1 & (HOST_BITS_PER_WIDE_INT - 1); + unsigned int blocks_needed = BLOCKS_NEEDED (precision); + unsigned int small_prec = precision & (HOST_BITS_PER_WIDE_INT - 1); int l = MAX (op0len - 1, op1len - 1); /* Only the top block is compared as signed. The rest are unsigned comparisons. */ - s0 = selt (op0, op0len, blocks_needed0, small_prec0, l, SIGNED); - s1 = selt (op1, op1len, blocks_needed1, small_prec1, l, SIGNED); + s0 = selt (op0, op0len, blocks_needed, small_prec, l, SIGNED); + s1 = selt (op1, op1len, blocks_needed, small_prec, l, SIGNED); if (s0 < s1) return -1; if (s0 > s1) @@ -481,8 +475,8 @@ wi::cmps_large (const HOST_WIDE_INT *op0, unsigned int op0len, l--; while (l >= 0) { - u0 = selt (op0, op0len, blocks_needed0, small_prec0, l, SIGNED); - u1 = selt (op1, op1len, blocks_needed1, small_prec1, l, SIGNED); + u0 = selt (op0, op0len, blocks_needed, small_prec, l, SIGNED); + u1 = selt (op1, op1len, blocks_needed, small_prec, l, SIGNED); if (u0 < u1) return -1; @@ -496,21 +490,20 @@ wi::cmps_large (const HOST_WIDE_INT *op0, unsigned int op0len, /* Return true if OP0 < OP1 using unsigned comparisons. */ bool -wi::ltu_p_large (const HOST_WIDE_INT *op0, unsigned int op0len, unsigned int p0, - const HOST_WIDE_INT *op1, unsigned int op1len, unsigned int p1) +wi::ltu_p_large (const HOST_WIDE_INT *op0, unsigned int op0len, + unsigned int precision, + const HOST_WIDE_INT *op1, unsigned int op1len) { unsigned HOST_WIDE_INT x0; unsigned HOST_WIDE_INT x1; - unsigned int blocks_needed0 = BLOCKS_NEEDED (p0); - unsigned int blocks_needed1 = BLOCKS_NEEDED (p1); - unsigned int small_prec0 = p0 & (HOST_BITS_PER_WIDE_INT - 1); - unsigned int small_prec1 = p1 & (HOST_BITS_PER_WIDE_INT - 1); + unsigned int blocks_needed = BLOCKS_NEEDED (precision); + unsigned int small_prec = precision & (HOST_BITS_PER_WIDE_INT - 1); int l = MAX (op0len - 1, op1len - 1); while (l >= 0) { - x0 = selt (op0, op0len, blocks_needed0, small_prec0, l, UNSIGNED); - x1 = selt (op1, op1len, blocks_needed1, small_prec1, l, UNSIGNED); + x0 = selt (op0, op0len, blocks_needed, small_prec, l, UNSIGNED); + x1 = selt (op1, op1len, blocks_needed, small_prec, l, UNSIGNED); if (x0 < x1) return true; if (x0 > x1) @@ -524,21 +517,20 @@ wi::ltu_p_large (const HOST_WIDE_INT *op0, unsigned int op0len, unsigned int p0, /* Returns -1 if OP0 < OP1, 0 if OP0 == OP1 and 1 if OP0 > OP1 using unsigned compares. */ int -wi::cmpu_large (const HOST_WIDE_INT *op0, unsigned int op0len, unsigned int p0, - const HOST_WIDE_INT *op1, unsigned int op1len, unsigned int p1) +wi::cmpu_large (const HOST_WIDE_INT *op0, unsigned int op0len, + unsigned int precision, + const HOST_WIDE_INT *op1, unsigned int op1len) { unsigned HOST_WIDE_INT x0; unsigned HOST_WIDE_INT x1; - unsigned int blocks_needed0 = BLOCKS_NEEDED (p0); - unsigned int blocks_needed1 = BLOCKS_NEEDED (p1); - unsigned int small_prec0 = p0 & (HOST_BITS_PER_WIDE_INT - 1); - unsigned int small_prec1 = p1 & (HOST_BITS_PER_WIDE_INT - 1); + unsigned int blocks_needed = BLOCKS_NEEDED (precision); + unsigned int small_prec = precision & (HOST_BITS_PER_WIDE_INT - 1); int l = MAX (op0len - 1, op1len - 1); while (l >= 0) { - x0 = selt (op0, op0len, blocks_needed0, small_prec0, l, UNSIGNED); - x1 = selt (op1, op1len, blocks_needed1, small_prec1, l, UNSIGNED); + x0 = selt (op0, op0len, blocks_needed, small_prec, l, UNSIGNED); + x1 = selt (op1, op1len, blocks_needed, small_prec, l, UNSIGNED); if (x0 < x1) return -1; if (x0 > x1) diff --git a/gcc/wide-int.h b/gcc/wide-int.h index 678ef2dd6c74..eea59d9f6517 100644 --- a/gcc/wide-int.h +++ b/gcc/wide-int.h @@ -1354,13 +1354,13 @@ namespace wi bool eq_p_large (const HOST_WIDE_INT *, unsigned int, const HOST_WIDE_INT *, unsigned int, unsigned int); bool lts_p_large (const HOST_WIDE_INT *, unsigned int, unsigned int, - const HOST_WIDE_INT *, unsigned int, unsigned int); + const HOST_WIDE_INT *, unsigned int); bool ltu_p_large (const HOST_WIDE_INT *, unsigned int, unsigned int, - const HOST_WIDE_INT *, unsigned int, unsigned int); + const HOST_WIDE_INT *, unsigned int); int cmps_large (const HOST_WIDE_INT *, unsigned int, unsigned int, - const HOST_WIDE_INT *, unsigned int, unsigned int); + const HOST_WIDE_INT *, unsigned int); int cmpu_large (const HOST_WIDE_INT *, unsigned int, unsigned int, - const HOST_WIDE_INT *, unsigned int, unsigned int); + const HOST_WIDE_INT *, unsigned int); unsigned int sext_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, unsigned int, unsigned int, unsigned int); @@ -1526,10 +1526,11 @@ template inline bool wi::lts_p (const T1 &x, const T2 &y) { - WIDE_INT_REF_FOR (T1) xi (x); - WIDE_INT_REF_FOR (T2) yi (y); + unsigned int precision = get_binary_precision (x, y); + WIDE_INT_REF_FOR (T1) xi (x, precision); + WIDE_INT_REF_FOR (T2) yi (y, precision); // We optimize x < y, where y is 64 or fewer bits. - if (yi.precision <= HOST_BITS_PER_WIDE_INT) + if (wi::fits_shwi_p (yi)) { // If x fits directly into a shwi, we can compare directly. if (wi::fits_shwi_p (xi)) @@ -1542,8 +1543,7 @@ wi::lts_p (const T1 &x, const T2 &y) // and hence greater than y. return false; } - return lts_p_large (xi.val, xi.len, xi.precision, yi.val, yi.len, - yi.precision); + return lts_p_large (xi.val, xi.len, precision, yi.val, yi.len); } /* Return true if X < Y when both are treated as unsigned values. */ @@ -1551,18 +1551,16 @@ template inline bool wi::ltu_p (const T1 &x, const T2 &y) { - WIDE_INT_REF_FOR (T1) xi (x); - WIDE_INT_REF_FOR (T2) yi (y); - if (xi.precision <= HOST_BITS_PER_WIDE_INT - && yi.precision <= HOST_BITS_PER_WIDE_INT) + unsigned int precision = get_binary_precision (x, y); + WIDE_INT_REF_FOR (T1) xi (x, precision); + WIDE_INT_REF_FOR (T2) yi (y, precision); + if (precision <= HOST_BITS_PER_WIDE_INT) { unsigned HOST_WIDE_INT xl = xi.to_uhwi (); unsigned HOST_WIDE_INT yl = yi.to_uhwi (); return xl < yl; } - else - return ltu_p_large (xi.val, xi.len, xi.precision, - yi.val, yi.len, yi.precision); + return ltu_p_large (xi.val, xi.len, precision, yi.val, yi.len); } /* Return true if X < Y. Signedness of X and Y is indicated by SGN. */ @@ -1663,10 +1661,10 @@ template inline int wi::cmps (const T1 &x, const T2 &y) { - WIDE_INT_REF_FOR (T1) xi (x); - WIDE_INT_REF_FOR (T2) yi (y); - if (xi.precision <= HOST_BITS_PER_WIDE_INT - && yi.precision <= HOST_BITS_PER_WIDE_INT) + unsigned int precision = get_binary_precision (x, y); + WIDE_INT_REF_FOR (T1) xi (x, precision); + WIDE_INT_REF_FOR (T2) yi (y, precision); + if (precision <= HOST_BITS_PER_WIDE_INT) { HOST_WIDE_INT xl = xi.to_shwi (); HOST_WIDE_INT yl = yi.to_shwi (); @@ -1677,8 +1675,7 @@ wi::cmps (const T1 &x, const T2 &y) else return 0; } - return cmps_large (xi.val, xi.len, xi.precision, yi.val, yi.len, - yi.precision); + return cmps_large (xi.val, xi.len, precision, yi.val, yi.len); } /* Return -1 if X < Y, 0 if X == Y and 1 if X > Y. Treat both X and Y @@ -1687,10 +1684,10 @@ template inline int wi::cmpu (const T1 &x, const T2 &y) { - WIDE_INT_REF_FOR (T1) xi (x); - WIDE_INT_REF_FOR (T2) yi (y); - if (xi.precision <= HOST_BITS_PER_WIDE_INT - && yi.precision <= HOST_BITS_PER_WIDE_INT) + unsigned int precision = get_binary_precision (x, y); + WIDE_INT_REF_FOR (T1) xi (x, precision); + WIDE_INT_REF_FOR (T2) yi (y, precision); + if (precision <= HOST_BITS_PER_WIDE_INT) { unsigned HOST_WIDE_INT xl = xi.to_uhwi (); unsigned HOST_WIDE_INT yl = yi.to_uhwi (); @@ -1701,8 +1698,7 @@ wi::cmpu (const T1 &x, const T2 &y) else return 1; } - return cmpu_large (xi.val, xi.len, xi.precision, yi.val, yi.len, - yi.precision); + return cmpu_large (xi.val, xi.len, precision, yi.val, yi.len); } /* Return -1 if X < Y, 0 if X == Y and 1 if X > Y. Signedness of