wide-int: Fix estimation of buffer sizes for wide_int printing [PR111800]

Message ID ZSpPVW+zyc9egEwc@tucnak
State Unresolved
Headers
Series wide-int: Fix estimation of buffer sizes for wide_int printing [PR111800] |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Jakub Jelinek Oct. 14, 2023, 8:20 a.m. UTC
  Hi!

As mentioned in the PR, my estimations on needed buffer size for wide_int
and especially widest_int printing were incorrect, I've used get_len ()
in the estimations, but that is true only for !wi::neg_p (x) values.
Under the hood, we have 3 ways to print numbers.
print_decs which if
  if ((wi.get_precision () <= HOST_BITS_PER_WIDE_INT)
      || (wi.get_len () == 1))
uses sprintf which always fits into WIDE_INT_PRINT_BUFFER_SIZE (positive or
negative) and otherwise uses print_hex,
print_decu which if
  if ((wi.get_precision () <= HOST_BITS_PER_WIDE_INT)
      || (wi.get_len () == 1 && !wi::neg_p (wi)))
uses sprintf which always fits into WIDE_INT_PRINT_BUFFER_SIZE (positive
only) and print_hex, which doesn't print most significant limbs which are
zero and the first limb which is non-zero prints such that redundant 0
hex digits aren't printed, while all limbs below that are printed with
"%016" PRIx64.  For wi::neg_p (x) values, the first limb of the precision
is always non-zero, so we print all the limbs for the precision.
So, the current estimations are accurate if !wi::neg_p (x), or when
print_decs will be used and x.get_len () == 1, otherwise we need to use
estimation based on get_precision () rather than get_len ().

The following patch does that, bootstrapped/regtested on x86_64-linux and
i686-linux, ok for trunk?

The patch doesn't address what I've talked about earlier, that we might
actually stop using print_hex when asked for print_dec{s,u} - we could for
negative print_decs just negate and call print_decu, and in print_decu
e.g. in a loop UNSIGNED wi::divmod_trunc by
HOST_WIDE_INT_UC (10000000000000000000) and print the 19 decimal digits of
remainder if quotient is non-zero, otherwise non-padded rest, and then
reshuffle the buffer.  And/or perhaps print_hex should also take signop
and print negative hex constants as -0x..... if asked for SIGNED.
And finally, I think we should try to rewrite tree-ssa-ccp.cc bit-cp from
widest_int to wide_int, even the earlier:
PHI node value: CONSTANT 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2 (0x19)
in the -fdump-tree-ccp-details dumps is horribly confusing when the
type is say just 32-bit or 64-bit, and with the recent widest_int changes
those are now around with > 32000 f hex digits in there.  Not to mention we shouldn't
really care about state of bits beyond the precision and I think we always
have the type in question around (x.val is INTEGER_CST of the right type
and we just to::widest it, just x.mask is widest_int).

2023-10-14  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/111800
gcc/
	* wide-int.cc (assert_deceq): Use wi.get_len () for buffer size
	estimation only if !wi::neg_p (wi) or if len is 1 and sgn is SIGNED,
	otherwise use WIDE_INT_MAX_HWIS for wi.get_precision ().
	(assert_hexeq): Use wi.get_len () for buffer size estimation only
	if !wi::neg_p (wi), otherwise use WIDE_INT_MAX_HWIS for
	wi.get_precision ().
	* wide-int-print.cc (print_decs): Use wi.get_len () for buffer size
	estimation only if !wi::neg_p (wi) or if len is 1, otherwise use
	WIDE_INT_MAX_HWIS for wi.get_precision ().
	(print_decu): Use wi.get_len () for buffer size estimation only if
	!wi::neg_p (wi), otherwise use WIDE_INT_MAX_HWIS for
	wi.get_precision ().
	(print_hex): Likewise.
	* value-range.cc (irange_bitmask::dump): Use get_len () for
	buffer size estimation only if !wi::neg_p (wi), otherwise use
	WIDE_INT_MAX_HWIS for get_precision ().
	* value-range-pretty-print.cc (vrange_printer::print_irange_bitmasks):
	Likewise.
	* tree-ssa-loop-niter.cc (do_warn_aggressive_loop_optimizations): Use
	i_bound.get_len () for buffer size estimation only if
	!wi::neg_p (i_bound) or if len is 1 and !TYPE_UNSIGNED, otherwise use
	WIDE_INT_MAX_HWIS for i_bound.get_precision ().  Use TYPE_SIGN macro
	in print_dec call argument.
gcc/c-family/
	* c-warn.cc (match_case_to_enum_1): Assert w.get_precision ()
	is smaller or equal to WIDE_INT_MAX_INL_PRECISION rather than
	w.get_len () is smaller or equal to WIDE_INT_MAX_INL_ELTS.


	Jakub
  

Comments

Richard Biener Oct. 14, 2023, 8:41 a.m. UTC | #1
> Am 14.10.2023 um 10:21 schrieb Jakub Jelinek <jakub@redhat.com>:
> 
> Hi!
> 
> As mentioned in the PR, my estimations on needed buffer size for wide_int
> and especially widest_int printing were incorrect, I've used get_len ()
> in the estimations, but that is true only for !wi::neg_p (x) values.
> Under the hood, we have 3 ways to print numbers.
> print_decs which if
>  if ((wi.get_precision () <= HOST_BITS_PER_WIDE_INT)
>      || (wi.get_len () == 1))
> uses sprintf which always fits into WIDE_INT_PRINT_BUFFER_SIZE (positive or
> negative) and otherwise uses print_hex,
> print_decu which if
>  if ((wi.get_precision () <= HOST_BITS_PER_WIDE_INT)
>      || (wi.get_len () == 1 && !wi::neg_p (wi)))
> uses sprintf which always fits into WIDE_INT_PRINT_BUFFER_SIZE (positive
> only) and print_hex, which doesn't print most significant limbs which are
> zero and the first limb which is non-zero prints such that redundant 0
> hex digits aren't printed, while all limbs below that are printed with
> "%016" PRIx64.  For wi::neg_p (x) values, the first limb of the precision
> is always non-zero, so we print all the limbs for the precision.
> So, the current estimations are accurate if !wi::neg_p (x), or when
> print_decs will be used and x.get_len () == 1, otherwise we need to use
> estimation based on get_precision () rather than get_len ().
> 
> The following patch does that, bootstrapped/regtested on x86_64-linux and
> i686-linux, ok for trunk?

Can we somehow abstract this common pattern?

> The patch doesn't address what I've talked about earlier, that we might
> actually stop using print_hex when asked for print_dec{s,u} - we could for
> negative print_decs just negate and call print_decu, and in print_decu
> e.g. in a loop UNSIGNED wi::divmod_trunc by
> HOST_WIDE_INT_UC (10000000000000000000) and print the 19 decimal digits of
> remainder if quotient is non-zero, otherwise non-padded rest, and then
> reshuffle the buffer.  And/or perhaps print_hex should also take signop
> and print negative hex constants as -0x..... if asked for SIGNED.
> And finally, I think we should try to rewrite tree-ssa-ccp.cc bit-cp from
> widest_int to wide_int, even the earlier:
> PHI node value: CONSTANT 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2 (0x19)
> in the -fdump-tree-ccp-details dumps is horribly confusing when the
> type is say just 32-bit or 64-bit, and with the recent widest_int changes
> those are now around with > 32000 f hex digits in there.  Not to mention we shouldn't
> really care about state of bits beyond the precision and I think we always
> have the type in question around (x.val is INTEGER_CST of the right type
> and we just to::widest it, just x.mask is widest_int).
> 
> 2023-10-14  Jakub Jelinek  <jakub@redhat.com>
> 
>    PR tree-optimization/111800
> gcc/
>    * wide-int.cc (assert_deceq): Use wi.get_len () for buffer size
>    estimation only if !wi::neg_p (wi) or if len is 1 and sgn is SIGNED,
>    otherwise use WIDE_INT_MAX_HWIS for wi.get_precision ().
>    (assert_hexeq): Use wi.get_len () for buffer size estimation only
>    if !wi::neg_p (wi), otherwise use WIDE_INT_MAX_HWIS for
>    wi.get_precision ().
>    * wide-int-print.cc (print_decs): Use wi.get_len () for buffer size
>    estimation only if !wi::neg_p (wi) or if len is 1, otherwise use
>    WIDE_INT_MAX_HWIS for wi.get_precision ().
>    (print_decu): Use wi.get_len () for buffer size estimation only if
>    !wi::neg_p (wi), otherwise use WIDE_INT_MAX_HWIS for
>    wi.get_precision ().
>    (print_hex): Likewise.
>    * value-range.cc (irange_bitmask::dump): Use get_len () for
>    buffer size estimation only if !wi::neg_p (wi), otherwise use
>    WIDE_INT_MAX_HWIS for get_precision ().
>    * value-range-pretty-print.cc (vrange_printer::print_irange_bitmasks):
>    Likewise.
>    * tree-ssa-loop-niter.cc (do_warn_aggressive_loop_optimizations): Use
>    i_bound.get_len () for buffer size estimation only if
>    !wi::neg_p (i_bound) or if len is 1 and !TYPE_UNSIGNED, otherwise use
>    WIDE_INT_MAX_HWIS for i_bound.get_precision ().  Use TYPE_SIGN macro
>    in print_dec call argument.
> gcc/c-family/
>    * c-warn.cc (match_case_to_enum_1): Assert w.get_precision ()
>    is smaller or equal to WIDE_INT_MAX_INL_PRECISION rather than
>    w.get_len () is smaller or equal to WIDE_INT_MAX_INL_ELTS.
> 
> --- gcc/wide-int.cc.jj    2023-10-13 19:34:44.288830022 +0200
> +++ gcc/wide-int.cc    2023-10-13 20:23:12.889386810 +0200
> @@ -2450,7 +2450,9 @@ static void
> assert_deceq (const char *expected, const wide_int_ref &wi, signop sgn)
> {
>   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p = buf;
>   unsigned len = wi.get_len ();
> +  if ((len != 1 || sgn == UNSIGNED) && wi::neg_p (wi))
> +    len = WIDE_INT_MAX_HWIS (wi.get_precision ());
>   if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS))
>     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
>   print_dec (wi, p, sgn);
> @@ -2463,7 +2465,11 @@ static void
> assert_hexeq (const char *expected, const wide_int_ref &wi)
> {
>   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p = buf;
> -  unsigned len = wi.get_len ();
> +  unsigned len;
> +  if (wi::neg_p (wi))
> +    len = WIDE_INT_MAX_HWIS (wi.get_precision ());
> +  else
> +    len = wi.get_len ();
>   if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS))
>     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
>   print_hex (wi, p);
> --- gcc/wide-int-print.cc.jj    2023-10-13 19:34:44.282830103 +0200
> +++ gcc/wide-int-print.cc    2023-10-13 20:24:17.240518824 +0200
> @@ -76,6 +76,8 @@ print_decs (const wide_int_ref &wi, FILE
> {
>   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p = buf;
>   unsigned len = wi.get_len ();
> +  if (len != 1 && wi::neg_p (wi))
> +    len = WIDE_INT_MAX_HWIS (wi.get_precision ());
>   if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS))
>     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
>   print_decs (wi, p);
> @@ -103,6 +105,10 @@ print_decu (const wide_int_ref &wi, FILE
> {
>   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p = buf;
> -  unsigned len = wi.get_len ();
> +  unsigned len;
> +  if (wi::neg_p (wi))
> +    len = WIDE_INT_MAX_HWIS (wi.get_precision ());
> +  else
> +    len = wi.get_len ();
>   if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS))
>     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
>   print_decu (wi, p);
> @@ -141,7 +147,11 @@ void
> print_hex (const wide_int_ref &wi, FILE *file)
> {
>   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p = buf;
> -  unsigned len = wi.get_len ();
> +  unsigned len;
> +  if (wi::neg_p (wi))
> +    len = WIDE_INT_MAX_HWIS (wi.get_precision ());
> +  else
> +    len = wi.get_len ();
>   if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS))
>     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
>   print_hex (wi, p);
> --- gcc/value-range.cc.jj    2023-10-13 19:34:44.281830116 +0200
> +++ gcc/value-range.cc    2023-10-13 20:22:11.810210668 +0200
> @@ -251,8 +251,15 @@ irange_bitmask::dump (FILE *file) const
>   pp_needs_newline (&buffer) = true;
>   buffer.buffer->stream = file;
>   pp_string (&buffer, "MASK ");
> -  unsigned len_mask = m_mask.get_len ();
> -  unsigned len_val = m_value.get_len ();
> +  unsigned len_mask, len_val;
> +  if (wi::neg_p (m_mask))
> +    len_mask = WIDE_INT_MAX_HWIS (m_mask.get_precision ());
> +  else
> +    len_mask = m_mask.get_len ();
> +  if (wi::neg_p (m_value))
> +    len_val = WIDE_INT_MAX_HWIS (m_value.get_precision ());
> +  else
> +    len_val = m_value.get_len ();
>   unsigned len = MAX (len_mask, len_val);
>   if (len > WIDE_INT_MAX_INL_ELTS)
>     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
> --- gcc/value-range-pretty-print.cc.jj    2023-10-13 19:34:44.260830398 +0200
> +++ gcc/value-range-pretty-print.cc    2023-10-13 20:20:11.740830199 +0200
> @@ -100,8 +100,15 @@ vrange_printer::print_irange_bitmasks (c
> 
>   pp_string (pp, " MASK ");
>   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p;
> -  unsigned len_mask = bm.mask ().get_len ();
> -  unsigned len_val = bm.value ().get_len ();
> +  unsigned len_mask, len_val;
> +  if (wi::neg_p (bm.mask ()))
> +    len_mask = WIDE_INT_MAX_HWIS (bm.mask ().get_precision ());
> +  else
> +    len_mask = bm.mask ().get_len ();
> +  if (wi::neg_p (bm.value ()))
> +    len_val = WIDE_INT_MAX_HWIS (bm.value ().get_precision ());
> +  else
> +    len_val = bm.value ().get_len ();
>   unsigned len = MAX (len_mask, len_val);
>   if (len > WIDE_INT_MAX_INL_ELTS)
>     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
> --- gcc/tree-ssa-loop-niter.cc.jj    2023-10-13 19:34:44.220830936 +0200
> +++ gcc/tree-ssa-loop-niter.cc    2023-10-14 09:43:59.343845355 +0200
> @@ -3875,12 +3875,14 @@ do_warn_aggressive_loop_optimizations (c
>   gimple *estmt = last_nondebug_stmt (e->src);
>   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p;
>   unsigned len = i_bound.get_len ();
> +  if ((len != 1 || TYPE_UNSIGNED (TREE_TYPE (loop->nb_iterations)))
> +      && wi::neg_p (i_bound))
> +    len = WIDE_INT_MAX_HWIS (i_bound.get_precision ());
>   if (len > WIDE_INT_MAX_INL_ELTS)
>     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
>   else
>     p = buf;
> -  print_dec (i_bound, p, TYPE_UNSIGNED (TREE_TYPE (loop->nb_iterations))
> -         ? UNSIGNED : SIGNED);
> +  print_dec (i_bound, p, TYPE_SIGN (TREE_TYPE (loop->nb_iterations)));
>   auto_diagnostic_group d;
>   if (warning_at (gimple_location (stmt), OPT_Waggressive_loop_optimizations,
>          "iteration %s invokes undefined behavior", p))
> --- gcc/c-family/c-warn.cc.jj    2023-10-13 19:34:43.678838226 +0200
> +++ gcc/c-family/c-warn.cc    2023-10-13 20:16:08.246114521 +0200
> @@ -1519,7 +1519,7 @@ match_case_to_enum_1 (tree key, tree typ
>   char buf[WIDE_INT_PRINT_BUFFER_SIZE];
>   wide_int w = wi::to_wide (key);
> 
> -  gcc_assert (w.get_len () <= WIDE_INT_MAX_INL_ELTS);
> +  gcc_assert (w.get_precision () <= WIDE_INT_MAX_INL_PRECISION);
>   if (tree_fits_uhwi_p (key))
>     print_dec (w, buf, UNSIGNED);
>   else if (tree_fits_shwi_p (key))
> 
>    Jakub
>
  

Patch

--- gcc/wide-int.cc.jj	2023-10-13 19:34:44.288830022 +0200
+++ gcc/wide-int.cc	2023-10-13 20:23:12.889386810 +0200
@@ -2450,7 +2450,9 @@  static void
 assert_deceq (const char *expected, const wide_int_ref &wi, signop sgn)
 {
   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p = buf;
   unsigned len = wi.get_len ();
+  if ((len != 1 || sgn == UNSIGNED) && wi::neg_p (wi))
+    len = WIDE_INT_MAX_HWIS (wi.get_precision ());
   if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS))
     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
   print_dec (wi, p, sgn);
@@ -2463,7 +2465,11 @@  static void
 assert_hexeq (const char *expected, const wide_int_ref &wi)
 {
   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p = buf;
-  unsigned len = wi.get_len ();
+  unsigned len;
+  if (wi::neg_p (wi))
+    len = WIDE_INT_MAX_HWIS (wi.get_precision ());
+  else
+    len = wi.get_len ();
   if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS))
     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
   print_hex (wi, p);
--- gcc/wide-int-print.cc.jj	2023-10-13 19:34:44.282830103 +0200
+++ gcc/wide-int-print.cc	2023-10-13 20:24:17.240518824 +0200
@@ -76,6 +76,8 @@  print_decs (const wide_int_ref &wi, FILE
 {
   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p = buf;
   unsigned len = wi.get_len ();
+  if (len != 1 && wi::neg_p (wi))
+    len = WIDE_INT_MAX_HWIS (wi.get_precision ());
   if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS))
     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
   print_decs (wi, p);
@@ -103,6 +105,10 @@  print_decu (const wide_int_ref &wi, FILE
 {
   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p = buf;
-  unsigned len = wi.get_len ();
+  unsigned len;
+  if (wi::neg_p (wi))
+    len = WIDE_INT_MAX_HWIS (wi.get_precision ());
+  else
+    len = wi.get_len ();
   if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS))
     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
   print_decu (wi, p);
@@ -141,7 +147,11 @@  void
 print_hex (const wide_int_ref &wi, FILE *file)
 {
   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p = buf;
-  unsigned len = wi.get_len ();
+  unsigned len;
+  if (wi::neg_p (wi))
+    len = WIDE_INT_MAX_HWIS (wi.get_precision ());
+  else
+    len = wi.get_len ();
   if (UNLIKELY (len > WIDE_INT_MAX_INL_ELTS))
     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
   print_hex (wi, p);
--- gcc/value-range.cc.jj	2023-10-13 19:34:44.281830116 +0200
+++ gcc/value-range.cc	2023-10-13 20:22:11.810210668 +0200
@@ -251,8 +251,15 @@  irange_bitmask::dump (FILE *file) const
   pp_needs_newline (&buffer) = true;
   buffer.buffer->stream = file;
   pp_string (&buffer, "MASK ");
-  unsigned len_mask = m_mask.get_len ();
-  unsigned len_val = m_value.get_len ();
+  unsigned len_mask, len_val;
+  if (wi::neg_p (m_mask))
+    len_mask = WIDE_INT_MAX_HWIS (m_mask.get_precision ());
+  else
+    len_mask = m_mask.get_len ();
+  if (wi::neg_p (m_value))
+    len_val = WIDE_INT_MAX_HWIS (m_value.get_precision ());
+  else
+    len_val = m_value.get_len ();
   unsigned len = MAX (len_mask, len_val);
   if (len > WIDE_INT_MAX_INL_ELTS)
     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
--- gcc/value-range-pretty-print.cc.jj	2023-10-13 19:34:44.260830398 +0200
+++ gcc/value-range-pretty-print.cc	2023-10-13 20:20:11.740830199 +0200
@@ -100,8 +100,15 @@  vrange_printer::print_irange_bitmasks (c
 
   pp_string (pp, " MASK ");
   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p;
-  unsigned len_mask = bm.mask ().get_len ();
-  unsigned len_val = bm.value ().get_len ();
+  unsigned len_mask, len_val;
+  if (wi::neg_p (bm.mask ()))
+    len_mask = WIDE_INT_MAX_HWIS (bm.mask ().get_precision ());
+  else
+    len_mask = bm.mask ().get_len ();
+  if (wi::neg_p (bm.value ()))
+    len_val = WIDE_INT_MAX_HWIS (bm.value ().get_precision ());
+  else
+    len_val = bm.value ().get_len ();
   unsigned len = MAX (len_mask, len_val);
   if (len > WIDE_INT_MAX_INL_ELTS)
     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
--- gcc/tree-ssa-loop-niter.cc.jj	2023-10-13 19:34:44.220830936 +0200
+++ gcc/tree-ssa-loop-niter.cc	2023-10-14 09:43:59.343845355 +0200
@@ -3875,12 +3875,14 @@  do_warn_aggressive_loop_optimizations (c
   gimple *estmt = last_nondebug_stmt (e->src);
   char buf[WIDE_INT_PRINT_BUFFER_SIZE], *p;
   unsigned len = i_bound.get_len ();
+  if ((len != 1 || TYPE_UNSIGNED (TREE_TYPE (loop->nb_iterations)))
+      && wi::neg_p (i_bound))
+    len = WIDE_INT_MAX_HWIS (i_bound.get_precision ());
   if (len > WIDE_INT_MAX_INL_ELTS)
     p = XALLOCAVEC (char, len * HOST_BITS_PER_WIDE_INT / 4 + 4);
   else
     p = buf;
-  print_dec (i_bound, p, TYPE_UNSIGNED (TREE_TYPE (loop->nb_iterations))
-	     ? UNSIGNED : SIGNED);
+  print_dec (i_bound, p, TYPE_SIGN (TREE_TYPE (loop->nb_iterations)));
   auto_diagnostic_group d;
   if (warning_at (gimple_location (stmt), OPT_Waggressive_loop_optimizations,
 		  "iteration %s invokes undefined behavior", p))
--- gcc/c-family/c-warn.cc.jj	2023-10-13 19:34:43.678838226 +0200
+++ gcc/c-family/c-warn.cc	2023-10-13 20:16:08.246114521 +0200
@@ -1519,7 +1519,7 @@  match_case_to_enum_1 (tree key, tree typ
   char buf[WIDE_INT_PRINT_BUFFER_SIZE];
   wide_int w = wi::to_wide (key);
 
-  gcc_assert (w.get_len () <= WIDE_INT_MAX_INL_ELTS);
+  gcc_assert (w.get_precision () <= WIDE_INT_MAX_INL_PRECISION);
   if (tree_fits_uhwi_p (key))
     print_dec (w, buf, UNSIGNED);
   else if (tree_fits_shwi_p (key))