From 0cadbfaa89805ce4d1b93bed04c10d7c7bf1f6e2 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sat, 24 Aug 2013 00:16:08 +0200 Subject: [PATCH] re PR other/57324 (Undefined behavior issues found with clang's -fsanitize=undefined) 2013-08-24 Marc Glisse PR other/57324 * hwint.h (HOST_WIDE_INT_UC, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1, HOST_WIDE_INT_M1U): New macros. * fold-const.c (sign_bit_p, build_range_check, fold_unary_loc, fold_binary_loc, fold_ternary_loc): Use the new macros. Use an unsigned -1 for lshift. * cse.c (cse_insn): Likewise. * double-int.c (rshift_double, lshift_double): Likewise. * builtins.c (fold_builtin_bitop): Likewise. * combine.c (force_to_mode): Likewise. * tree.c (integer_pow2p, tree_log2, tree_floor_log2): Likewise. * simplify-rtx.c (simplify_const_unary_operation, simplify_const_binary_operation): Likewise. * tree-stdarg.c (va_list_counter_bump, va_list_ptr_read, check_va_list_escapes): Likewise. * rtlanal.c (nonzero_bits1): Likewise. * expmed.c (expand_smod_pow2): Likewise. * tree-ssa-structalias.c (UNKNOWN_OFFSET): Use HOST_WIDE_INT_MIN. From-SVN: r201953 --- gcc/ChangeLog | 21 +++++++++++++++++++++ gcc/builtins.c | 9 ++++----- gcc/combine.c | 8 ++++---- gcc/cse.c | 2 +- gcc/double-int.c | 8 ++++---- gcc/expmed.c | 6 +++--- gcc/fold-const.c | 28 +++++++++++++--------------- gcc/hwint.h | 4 ++++ gcc/rtlanal.c | 2 +- gcc/simplify-rtx.c | 7 +++---- gcc/tree-ssa-structalias.c | 2 +- gcc/tree-stdarg.c | 16 ++++++++-------- gcc/tree.c | 12 ++++++------ 13 files changed, 73 insertions(+), 52 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f270ec9095f..a659a860124 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2013-08-24 Marc Glisse + + PR other/57324 + * hwint.h (HOST_WIDE_INT_UC, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1, + HOST_WIDE_INT_M1U): New macros. + * fold-const.c (sign_bit_p, build_range_check, fold_unary_loc, + fold_binary_loc, fold_ternary_loc): Use the new macros. Use an + unsigned -1 for lshift. + * cse.c (cse_insn): Likewise. + * double-int.c (rshift_double, lshift_double): Likewise. + * builtins.c (fold_builtin_bitop): Likewise. + * combine.c (force_to_mode): Likewise. + * tree.c (integer_pow2p, tree_log2, tree_floor_log2): Likewise. + * simplify-rtx.c (simplify_const_unary_operation, + simplify_const_binary_operation): Likewise. + * tree-stdarg.c (va_list_counter_bump, va_list_ptr_read, + check_va_list_escapes): Likewise. + * rtlanal.c (nonzero_bits1): Likewise. + * expmed.c (expand_smod_pow2): Likewise. + * tree-ssa-structalias.c (UNKNOWN_OFFSET): Use HOST_WIDE_INT_MIN. + 2013-08-23 Jan Hubicka * cgraph.c (cgraph_turn_edge_to_speculative): Mark target node diff --git a/gcc/builtins.c b/gcc/builtins.c index f6f61c75018..d8baad15e8e 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -8133,14 +8133,13 @@ fold_builtin_bitop (tree fndecl, tree arg) { hi = TREE_INT_CST_HIGH (arg); if (width < HOST_BITS_PER_DOUBLE_INT) - hi &= ~((unsigned HOST_WIDE_INT) (-1) - << (width - HOST_BITS_PER_WIDE_INT)); + hi &= ~(HOST_WIDE_INT_M1U << (width - HOST_BITS_PER_WIDE_INT)); } else { hi = 0; if (width < HOST_BITS_PER_WIDE_INT) - lo &= ~((unsigned HOST_WIDE_INT) (-1) << width); + lo &= ~(HOST_WIDE_INT_M1U << width); } switch (DECL_FUNCTION_CODE (fndecl)) @@ -8179,13 +8178,13 @@ fold_builtin_bitop (tree fndecl, tree arg) && (hi & ((unsigned HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT - 1))) != 0) { - hi = ~hi & ~((unsigned HOST_WIDE_INT) (-1) + hi = ~hi & ~(HOST_WIDE_INT_M1U << (width - HOST_BITS_PER_WIDE_INT - 1)); lo = ~lo; } else if (width <= HOST_BITS_PER_WIDE_INT && (lo & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0) - lo = ~lo & ~((unsigned HOST_WIDE_INT) (-1) << (width - 1)); + lo = ~lo & ~(HOST_WIDE_INT_M1U << (width - 1)); if (hi != 0) result = width - floor_log2 (hi) - 2 - HOST_BITS_PER_WIDE_INT; else if (lo != 0) diff --git a/gcc/combine.c b/gcc/combine.c index 29dfd15cc9f..fc566c55c16 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -8129,8 +8129,8 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask, /* If MODE is narrower than HOST_WIDE_INT and CVAL is a negative number, sign extend it. */ if (width > 0 && width < HOST_BITS_PER_WIDE_INT - && (cval & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0) - cval |= (unsigned HOST_WIDE_INT) -1 << width; + && (cval & (HOST_WIDE_INT_1U << (width - 1))) != 0) + cval |= HOST_WIDE_INT_M1U << width; y = simplify_gen_binary (AND, GET_MODE (x), XEXP (x, 0), GEN_INT (cval)); @@ -8158,8 +8158,8 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask, number, sign extend it. */ if (width < HOST_BITS_PER_WIDE_INT - && (smask & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0) - smask |= (unsigned HOST_WIDE_INT) (-1) << width; + && (smask & (HOST_WIDE_INT_1U << (width - 1))) != 0) + smask |= HOST_WIDE_INT_M1U << width; if (CONST_INT_P (XEXP (x, 1)) && exact_log2 (- smask) >= 0 diff --git a/gcc/cse.c b/gcc/cse.c index ee1b7be1170..b96af19f9e4 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -5381,7 +5381,7 @@ cse_insn (rtx insn) && CONST_INT_P (width) && INTVAL (width) < HOST_BITS_PER_WIDE_INT && ! (INTVAL (src_const) - & ((HOST_WIDE_INT) (-1) << INTVAL (width)))) + & (HOST_WIDE_INT_M1U << INTVAL (width)))) /* Exception: if the value is constant, and it won't be truncated, record it. */ ; diff --git a/gcc/double-int.c b/gcc/double-int.c index fe3c096619a..7eaad659279 100644 --- a/gcc/double-int.c +++ b/gcc/double-int.c @@ -271,13 +271,13 @@ rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1, ; else if ((prec - count) >= HOST_BITS_PER_WIDE_INT) { - *hv &= ~((HOST_WIDE_INT) (-1) << (prec - count - HOST_BITS_PER_WIDE_INT)); + *hv &= ~(HOST_WIDE_INT_M1U << (prec - count - HOST_BITS_PER_WIDE_INT)); *hv |= signmask << (prec - count - HOST_BITS_PER_WIDE_INT); } else { *hv = signmask; - *lv &= ~((unsigned HOST_WIDE_INT) (-1) << (prec - count)); + *lv &= ~(HOST_WIDE_INT_M1U << (prec - count)); *lv |= signmask << (prec - count); } } @@ -328,13 +328,13 @@ lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1, ; else if (prec >= HOST_BITS_PER_WIDE_INT) { - *hv &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT)); + *hv &= ~(HOST_WIDE_INT_M1U << (prec - HOST_BITS_PER_WIDE_INT)); *hv |= signmask << (prec - HOST_BITS_PER_WIDE_INT); } else { *hv = signmask; - *lv &= ~((unsigned HOST_WIDE_INT) (-1) << prec); + *lv &= ~(HOST_WIDE_INT_M1U << prec); *lv |= signmask << prec; } } diff --git a/gcc/expmed.c b/gcc/expmed.c index 79f3424961d..d18f09f4889 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -3697,11 +3697,11 @@ expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d) masklow = ((HOST_WIDE_INT) 1 << logd) - 1; if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) { - masklow |= (HOST_WIDE_INT) -1 << (GET_MODE_BITSIZE (mode) - 1); + masklow |= HOST_WIDE_INT_M1U << (GET_MODE_BITSIZE (mode) - 1); maskhigh = -1; } else - maskhigh = (HOST_WIDE_INT) -1 + maskhigh = HOST_WIDE_INT_M1U << (GET_MODE_BITSIZE (mode) - HOST_BITS_PER_WIDE_INT - 1); temp = expand_binop (mode, and_optab, op0, @@ -3715,7 +3715,7 @@ expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d) temp = expand_binop (mode, sub_optab, result, const1_rtx, result, 0, OPTAB_LIB_WIDEN); - masklow = (HOST_WIDE_INT) -1 << logd; + masklow = HOST_WIDE_INT_M1U << logd; maskhigh = -1; temp = expand_binop (mode, ior_optab, temp, immed_double_const (masklow, maskhigh, mode), diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 6506ae7bbfb..1e0e7e5f985 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3740,8 +3740,7 @@ sign_bit_p (tree exp, const_tree val) hi = (unsigned HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT - 1); lo = 0; - mask_hi = ((unsigned HOST_WIDE_INT) -1 - >> (HOST_BITS_PER_DOUBLE_INT - width)); + mask_hi = (HOST_WIDE_INT_M1U >> (HOST_BITS_PER_DOUBLE_INT - width)); mask_lo = -1; } else @@ -3750,8 +3749,7 @@ sign_bit_p (tree exp, const_tree val) lo = (unsigned HOST_WIDE_INT) 1 << (width - 1); mask_hi = 0; - mask_lo = ((unsigned HOST_WIDE_INT) -1 - >> (HOST_BITS_PER_WIDE_INT - width)); + mask_lo = (HOST_WIDE_INT_M1U >> (HOST_BITS_PER_WIDE_INT - width)); } /* We mask off those bits beyond TREE_TYPE (exp) so that we can @@ -4325,7 +4323,7 @@ build_range_check (location_t loc, tree type, tree exp, int in_p, else { hi = ((HOST_WIDE_INT) 1 << (prec - HOST_BITS_PER_WIDE_INT - 1)) - 1; - lo = (unsigned HOST_WIDE_INT) -1; + lo = HOST_WIDE_INT_M1U; } if (TREE_INT_CST_HIGH (high) == hi && TREE_INT_CST_LOW (high) == lo) @@ -8096,7 +8094,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) unsigned HOST_WIDE_INT cst; cst = tree_low_cst (and1, 1); - cst &= (HOST_WIDE_INT) -1 + cst &= HOST_WIDE_INT_M1U << (TYPE_PRECISION (TREE_TYPE (and1)) - 1); change = (cst == 0); #ifdef LOAD_EXTEND_OP @@ -11277,7 +11275,7 @@ fold_binary_loc (location_t loc, w <<= 1) { unsigned HOST_WIDE_INT mask - = (unsigned HOST_WIDE_INT) -1 >> (HOST_BITS_PER_WIDE_INT - w); + = HOST_WIDE_INT_M1U >> (HOST_BITS_PER_WIDE_INT - w); if (((c1.low | c2.low) & mask) == mask && (c1.low & ~mask) == 0 && c1.high == 0) { @@ -12297,7 +12295,7 @@ fold_binary_loc (location_t loc, /* X / -1 is -X. */ if (!TYPE_UNSIGNED (type) && TREE_CODE (arg1) == INTEGER_CST - && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1 + && TREE_INT_CST_LOW (arg1) == HOST_WIDE_INT_M1U && TREE_INT_CST_HIGH (arg1) == -1) return fold_convert_loc (loc, type, negate_expr (arg0)); @@ -12380,7 +12378,7 @@ fold_binary_loc (location_t loc, /* X % -1 is zero. */ if (!TYPE_UNSIGNED (type) && TREE_CODE (arg1) == INTEGER_CST - && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1 + && TREE_INT_CST_LOW (arg1) == HOST_WIDE_INT_M1U && TREE_INT_CST_HIGH (arg1) == -1) return omit_one_operand_loc (loc, type, integer_zero_node, arg0); @@ -13535,7 +13533,7 @@ fold_binary_loc (location_t loc, else { max_lo = signed_max_lo; - min_lo = ((unsigned HOST_WIDE_INT) -1 << (width - 1)); + min_lo = (HOST_WIDE_INT_M1U << (width - 1)); min_hi = -1; } } @@ -13556,7 +13554,7 @@ fold_binary_loc (location_t loc, else { max_hi = signed_max_hi; - min_hi = ((unsigned HOST_WIDE_INT) -1 << (width - 1)); + min_hi = (HOST_WIDE_INT_M1U << (width - 1)); } } @@ -14175,24 +14173,24 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, if (outer_width > HOST_BITS_PER_WIDE_INT) { - mask_hi = ((unsigned HOST_WIDE_INT) -1 + mask_hi = (HOST_WIDE_INT_M1U >> (HOST_BITS_PER_DOUBLE_INT - outer_width)); mask_lo = -1; } else { mask_hi = 0; - mask_lo = ((unsigned HOST_WIDE_INT) -1 + mask_lo = (HOST_WIDE_INT_M1U >> (HOST_BITS_PER_WIDE_INT - outer_width)); } if (inner_width > HOST_BITS_PER_WIDE_INT) { - mask_hi &= ~((unsigned HOST_WIDE_INT) -1 + mask_hi &= ~(HOST_WIDE_INT_M1U >> (HOST_BITS_PER_WIDE_INT - inner_width)); mask_lo = 0; } else - mask_lo &= ~((unsigned HOST_WIDE_INT) -1 + mask_lo &= ~(HOST_WIDE_INT_M1U >> (HOST_BITS_PER_WIDE_INT - inner_width)); if ((TREE_INT_CST_HIGH (arg1) & mask_hi) == mask_hi diff --git a/gcc/hwint.h b/gcc/hwint.h index dbf023975cb..9930baac100 100644 --- a/gcc/hwint.h +++ b/gcc/hwint.h @@ -110,7 +110,11 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1]; #endif +#define HOST_WIDE_INT_UC(X) HOST_WIDE_INT_C(X ## U) #define HOST_WIDE_INT_1 HOST_WIDE_INT_C(1) +#define HOST_WIDE_INT_1U HOST_WIDE_INT_UC(1) +#define HOST_WIDE_INT_M1 HOST_WIDE_INT_C(-1) +#define HOST_WIDE_INT_M1U HOST_WIDE_INT_UC(-1) /* This is a magic identifier which allows GCC to figure out the type of HOST_WIDE_INT for %wd specifier checks. You must issue this diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 95a314f0f3f..c15037e9645 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -4034,7 +4034,7 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x, && mode_width < BITS_PER_WORD && (UINTVAL (x) & ((unsigned HOST_WIDE_INT) 1 << (mode_width - 1))) != 0) - return UINTVAL (x) | ((unsigned HOST_WIDE_INT) (-1) << mode_width); + return UINTVAL (x) | (HOST_WIDE_INT_M1U << mode_width); #endif return UINTVAL (x); diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 17a3d12e076..65a59062a48 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -2018,14 +2018,13 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode, /* Test against the signed lower bound. */ if (width > HOST_BITS_PER_WIDE_INT) { - th = (unsigned HOST_WIDE_INT) (-1) - << (width - HOST_BITS_PER_WIDE_INT - 1); + th = HOST_WIDE_INT_M1U << (width - HOST_BITS_PER_WIDE_INT - 1); tl = 0; } else { th = -1; - tl = (unsigned HOST_WIDE_INT) (-1) << (width - 1); + tl = HOST_WIDE_INT_M1U << (width - 1); } real_from_integer (&t, VOIDmode, tl, th, 0); if (REAL_VALUES_LESS (x, t)) @@ -4191,7 +4190,7 @@ simplify_const_binary_operation (enum rtx_code code, enum machine_mode mode, /* Sign-extend the result for arithmetic right shifts. */ if (code == ASHIFTRT && arg0s < 0 && arg1 > 0) - val |= ((unsigned HOST_WIDE_INT) (-1)) << (width - arg1); + val |= HOST_WIDE_INT_M1U << (width - arg1); break; case ROTATERT: diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index ff6babb14a3..991a6b5800e 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -482,7 +482,7 @@ struct constraint_expr }; /* Use 0x8000... as special unknown offset. */ -#define UNKNOWN_OFFSET ((HOST_WIDE_INT)-1 << (HOST_BITS_PER_WIDE_INT-1)) +#define UNKNOWN_OFFSET HOST_WIDE_INT_MIN typedef struct constraint_expr ce_s; static void get_constraint_for_1 (tree, vec *, bool, bool); diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c index 50592c03a36..e4eb60ae042 100644 --- a/gcc/tree-stdarg.c +++ b/gcc/tree-stdarg.c @@ -105,7 +105,7 @@ reachable_at_most_once (basic_block va_arg_bb, basic_block va_start_bb) /* For statement COUNTER = RHS, if RHS is COUNTER + constant, - return constant, otherwise return (unsigned HOST_WIDE_INT) -1. + return constant, otherwise return HOST_WIDE_INT_M1U. GPR_P is true if this is GPR counter. */ static unsigned HOST_WIDE_INT @@ -149,7 +149,7 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs, stmt = SSA_NAME_DEF_STMT (lhs); if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != lhs) - return (unsigned HOST_WIDE_INT) -1; + return HOST_WIDE_INT_M1U; rhs_code = gimple_assign_rhs_code (stmt); rhs1 = gimple_assign_rhs1 (stmt); @@ -182,21 +182,21 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs, } if (get_gimple_rhs_class (rhs_code) != GIMPLE_SINGLE_RHS) - return (unsigned HOST_WIDE_INT) -1; + return HOST_WIDE_INT_M1U; rhs = gimple_assign_rhs1 (stmt); if (TREE_CODE (counter) != TREE_CODE (rhs)) - return (unsigned HOST_WIDE_INT) -1; + return HOST_WIDE_INT_M1U; if (TREE_CODE (counter) == COMPONENT_REF) { if (get_base_address (counter) != get_base_address (rhs) || TREE_CODE (TREE_OPERAND (rhs, 1)) != FIELD_DECL || TREE_OPERAND (counter, 1) != TREE_OPERAND (rhs, 1)) - return (unsigned HOST_WIDE_INT) -1; + return HOST_WIDE_INT_M1U; } else if (counter != rhs) - return (unsigned HOST_WIDE_INT) -1; + return HOST_WIDE_INT_M1U; lhs = NULL; } @@ -401,7 +401,7 @@ va_list_ptr_read (struct stdarg_info *si, tree ap, tree tem) if (! si->compute_sizes) return false; - if (va_list_counter_bump (si, ap, tem, true) == (unsigned HOST_WIDE_INT) -1) + if (va_list_counter_bump (si, ap, tem, true) == HOST_WIDE_INT_M1U) return false; /* Note the temporary, as we need to track whether it doesn't escape @@ -504,7 +504,7 @@ check_va_list_escapes (struct stdarg_info *si, tree lhs, tree rhs) } if (va_list_counter_bump (si, si->va_start_ap, lhs, true) - == (unsigned HOST_WIDE_INT) -1) + == HOST_WIDE_INT_M1U) { si->va_list_escapes = true; return; diff --git a/gcc/tree.c b/gcc/tree.c index 194710564a9..8f6ccde2584 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -2051,12 +2051,12 @@ integer_pow2p (const_tree expr) if (prec == HOST_BITS_PER_DOUBLE_INT) ; else if (prec > HOST_BITS_PER_WIDE_INT) - high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT)); + high &= ~(HOST_WIDE_INT_M1U << (prec - HOST_BITS_PER_WIDE_INT)); else { high = 0; if (prec < HOST_BITS_PER_WIDE_INT) - low &= ~((HOST_WIDE_INT) (-1) << prec); + low &= ~(HOST_WIDE_INT_M1U << prec); } if (high == 0 && low == 0) @@ -2115,12 +2115,12 @@ tree_log2 (const_tree expr) if (prec == HOST_BITS_PER_DOUBLE_INT) ; else if (prec > HOST_BITS_PER_WIDE_INT) - high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT)); + high &= ~(HOST_WIDE_INT_M1U << (prec - HOST_BITS_PER_WIDE_INT)); else { high = 0; if (prec < HOST_BITS_PER_WIDE_INT) - low &= ~((HOST_WIDE_INT) (-1) << prec); + low &= ~(HOST_WIDE_INT_M1U << prec); } return (high != 0 ? HOST_BITS_PER_WIDE_INT + exact_log2 (high) @@ -2152,12 +2152,12 @@ tree_floor_log2 (const_tree expr) if (prec == HOST_BITS_PER_DOUBLE_INT || prec == 0) ; else if (prec > HOST_BITS_PER_WIDE_INT) - high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT)); + high &= ~(HOST_WIDE_INT_M1U << (prec - HOST_BITS_PER_WIDE_INT)); else { high = 0; if (prec < HOST_BITS_PER_WIDE_INT) - low &= ~((HOST_WIDE_INT) (-1) << prec); + low &= ~(HOST_WIDE_INT_M1U << prec); } return (high != 0 ? HOST_BITS_PER_WIDE_INT + floor_log2 (high)