--- gcc/tree-ssa-ccp.cc.jj 2023-08-24 15:37:29.264410998 +0200 +++ gcc/tree-ssa-ccp.cc 2023-10-06 17:20:49.504965969 +0200 @@ -1966,7 +1966,8 @@ bit_value_binop (enum tree_code code, si } else { - widest_int upper = wi::udiv_trunc (r1max, r2min); + widest_int upper + = wi::udiv_trunc (wi::zext (r1max, width), r2min); unsigned int lzcount = wi::clz (upper); unsigned int bits = wi::get_precision (upper) - lzcount; *mask = wi::mask (bits, false); --- gcc/wide-int.cc.jj 2023-10-06 12:31:56.841517949 +0200 +++ gcc/wide-int.cc 2023-10-06 17:21:59.930022075 +0200 @@ -2406,6 +2406,17 @@ debug (const widest_int *ptr) fprintf (stderr, "\n"); } +bool wide_int_bitint_seen = false; + +void +wide_int_log (const char *p, int n) +{ + extern const char *current_function_name (void); + FILE *f = fopen ("/tmp/wis", "a"); + fprintf (f, "%d %s %s %s %d %c\n", (int) BITS_PER_WORD, main_input_filename ? main_input_filename : "-", current_function_name (), p, n, wide_int_bitint_seen ? 'y' : 'n'); + fclose (f); +} + #if CHECKING_P namespace selftest { --- gcc/gimple-ssa-sprintf.cc.jj 2023-01-02 09:32:20.797308227 +0100 +++ gcc/gimple-ssa-sprintf.cc 2023-10-06 17:08:45.516732616 +0200 @@ -1181,8 +1181,15 @@ adjust_range_for_overflow (tree dirtype, *argmin), size_int (dirprec))))) { - *argmin = force_fit_type (dirtype, wi::to_widest (*argmin), 0, false); - *argmax = force_fit_type (dirtype, wi::to_widest (*argmax), 0, false); + unsigned int maxprec = MAX (argprec, dirprec); + *argmin = force_fit_type (dirtype, + wide_int::from (wi::to_wide (*argmin), maxprec, + TYPE_SIGN (argtype)), + 0, false); + *argmax = force_fit_type (dirtype, + wide_int::from (wi::to_wide (*argmax), maxprec, + TYPE_SIGN (argtype)), + 0, false); /* If *ARGMIN is still less than *ARGMAX the conversion above is safe. Otherwise, it has overflowed and would be unsafe. */ --- gcc/match.pd.jj 2023-10-04 10:26:45.861259889 +0200 +++ gcc/match.pd 2023-10-06 17:09:34.435070589 +0200 @@ -6431,8 +6431,12 @@ (define_operator_list SYNC_FETCH_AND_AND code and here to avoid a spurious overflow flag on the resulting constant which fold_convert produces. */ (if (TREE_CODE (@1) == INTEGER_CST) - (cmp @00 { force_fit_type (TREE_TYPE (@00), wi::to_widest (@1), 0, - TREE_OVERFLOW (@1)); }) + (cmp @00 { force_fit_type (TREE_TYPE (@00), + wide_int::from (wi::to_wide (@1), + MAX (TYPE_PRECISION (TREE_TYPE (@1)), + TYPE_PRECISION (TREE_TYPE (@00))), + TYPE_SIGN (TREE_TYPE (@1))), + 0, TREE_OVERFLOW (@1)); }) (cmp @00 (convert @1))) (if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (TREE_TYPE (@00))) --- gcc/tree.cc.jj 2023-10-05 11:36:54.618251787 +0200 +++ gcc/tree.cc 2023-10-06 17:23:07.321118844 +0200 @@ -7178,6 +7178,8 @@ tree build_bitint_type (unsigned HOST_WIDE_INT precision, int unsignedp) { tree itype, ret; +extern bool wide_int_bitint_seen; +if (precision > 128) wide_int_bitint_seen = true; gcc_checking_assert (precision >= 1 + !unsignedp); --- gcc/wide-int.h.jj 2023-10-06 13:12:05.720338130 +0200 +++ gcc/wide-int.h 2023-10-06 17:42:59.980139497 +0200 @@ -1206,7 +1206,11 @@ inline wide_int_storage::wide_int_storag WIDE_INT_REF_FOR (T) xi (x); precision = xi.precision; if (UNLIKELY (precision > WIDE_INT_MAX_INL_PRECISION)) +{ +extern void wide_int_log (const char *, int); +wide_int_log ("ctor", precision); u.valp = XNEWVEC (HOST_WIDE_INT, CEIL (precision, HOST_BITS_PER_WIDE_INT)); +} wi::copy (*this, xi); } @@ -1216,6 +1220,8 @@ inline wide_int_storage::wide_int_storag precision = x.precision; if (UNLIKELY (precision > WIDE_INT_MAX_INL_PRECISION)) { +extern void wide_int_log (const char *, int); +wide_int_log ("copy ctor", precision); u.valp = XNEWVEC (HOST_WIDE_INT, CEIL (precision, HOST_BITS_PER_WIDE_INT)); memcpy (u.valp, x.u.valp, len * sizeof (HOST_WIDE_INT)); } @@ -1242,6 +1248,8 @@ wide_int_storage::operator = (const wide precision = x.precision; if (UNLIKELY (precision > WIDE_INT_MAX_INL_PRECISION)) { +extern void wide_int_log (const char *, int); +wide_int_log ("operator=1", precision); u.valp = XNEWVEC (HOST_WIDE_INT, CEIL (precision, HOST_BITS_PER_WIDE_INT)); memcpy (u.valp, x.u.valp, len * sizeof (HOST_WIDE_INT)); } @@ -1265,8 +1273,12 @@ wide_int_storage::operator = (const T &x XDELETEVEC (u.valp); precision = xi.precision; if (UNLIKELY (precision > WIDE_INT_MAX_INL_PRECISION)) +{ +extern void wide_int_log (const char *, int); +wide_int_log ("operator=2", precision); u.valp = XNEWVEC (HOST_WIDE_INT, CEIL (precision, HOST_BITS_PER_WIDE_INT)); +} } wi::copy (*this, xi); return *this; @@ -1339,8 +1351,12 @@ wide_int_storage::create (unsigned int p wide_int x; x.precision = precision; if (UNLIKELY (precision > WIDE_INT_MAX_INL_PRECISION)) +{ +extern void wide_int_log (const char *, int); +wide_int_log ("create", precision); x.u.valp = XNEWVEC (HOST_WIDE_INT, CEIL (precision, HOST_BITS_PER_WIDE_INT)); +} return x; } @@ -1756,6 +1772,8 @@ widest_int_storage ::widest_int_stora len = x.len; if (UNLIKELY (len > N / HOST_BITS_PER_WIDE_INT)) { +extern void wide_int_log (const char *, int); +wide_int_log ("wi copy ctor", len); u.valp = XNEWVEC (HOST_WIDE_INT, len); memcpy (u.valp, x.u.valp, len * sizeof (HOST_WIDE_INT)); } @@ -1783,6 +1801,8 @@ widest_int_storage ::operator = (cons len = x.len; if (UNLIKELY (len > N / HOST_BITS_PER_WIDE_INT)) { +extern void wide_int_log (const char *, int); +wide_int_log ("wi operator=1", len); u.valp = XNEWVEC (HOST_WIDE_INT, len); memcpy (u.valp, x.u.valp, len * sizeof (HOST_WIDE_INT)); } @@ -1837,6 +1857,8 @@ widest_int_storage ::write_val (unsig len = l; if (UNLIKELY (l > N / HOST_BITS_PER_WIDE_INT)) { +extern void wide_int_log (const char *, int); +wide_int_log ("wi write_val", l); u.valp = XNEWVEC (HOST_WIDE_INT, l); return u.valp; } --- gcc/fold-const.cc.jj 2023-09-29 18:58:47.252895500 +0200 +++ gcc/fold-const.cc 2023-10-06 17:03:24.561076214 +0200 @@ -2137,7 +2137,10 @@ fold_convert_const_int_from_int (tree ty /* Given an integer constant, make new constant with new type, appropriately sign-extended or truncated. Use widest_int so that any extension is done according ARG1's type. */ - return force_fit_type (type, wi::to_widest (arg1), + tree arg1_type = TREE_TYPE (arg1); + unsigned prec = MAX (TYPE_PRECISION (arg1_type), TYPE_PRECISION (type)); + return force_fit_type (type, wide_int::from (wi::to_wide (arg1), prec, + TYPE_SIGN (arg1_type)), !POINTER_TYPE_P (TREE_TYPE (arg1)), TREE_OVERFLOW (arg1)); } @@ -9565,8 +9568,13 @@ fold_unary_loc (location_t loc, enum tre } if (change) { - tem = force_fit_type (type, wi::to_widest (and1), 0, - TREE_OVERFLOW (and1)); + tree and1_type = TREE_TYPE (and1); + unsigned prec = MAX (TYPE_PRECISION (and1_type), + TYPE_PRECISION (type)); + tem = force_fit_type (type, + wide_int::from (wi::to_wide (and1), prec, + TYPE_SIGN (and1_type)), + 0, TREE_OVERFLOW (and1)); return fold_build2_loc (loc, BIT_AND_EXPR, type, fold_convert_loc (loc, type, and0), tem); }