On Fri, 15 May 2026, Xi Ruoyao wrote:

> For 3 iterations of
> 
>     unsigned char flagbits;
>     _877 = flagbits_832 + 254;
>     _879 = (int) _877;
>     # prephitmp_880 = PHI <_879(40), 6(41)>
>     _70 = _68 >> prephitmp_880;
> 
> The peeled converted IV handling added in r16-3562 incorrectly analyzes
> it as [6, 6 + 254, 6 + 254 * 2] instead of [6, 4, 2].  Then VRP uses the
> intersect of {6, 560, 514} and {2, 4, 6}, i.e. {6} as the possible value
> range, and propagates the constant 6 for _70.
> 
> Extend the step (for example, 254 => -2) to fix the issue.

OK.

Thanks,
Richard.

>       PR tree-optimization/125291
> 
> gcc/
> 
>       * tree-scalar-evolution.cc (simplify_peeled_chrec): Sign-extend
>       the step for peeled converted IV.
> 
> gcc/testsuite/
> 
>       * gcc.c-torture/execute/pr125291.c: New test.
> ---
> 
> Bootstrapped and regtested on x86_64-linux-gnu and
> loongarch64-linux-gnu.  Ok for trunk?
> 
>  .../gcc.c-torture/execute/pr125291.c          | 39 +++++++++++++++++++
>  gcc/tree-scalar-evolution.cc                  | 17 ++++++--
>  2 files changed, 52 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr125291.c
> 
> diff --git a/gcc/testsuite/gcc.c-torture/execute/pr125291.c 
> b/gcc/testsuite/gcc.c-torture/execute/pr125291.c
> new file mode 100644
> index 00000000000..073866a9b73
> --- /dev/null
> +++ b/gcc/testsuite/gcc.c-torture/execute/pr125291.c
> @@ -0,0 +1,39 @@
> +/* PR tree-optimization/125291 */
> +
> +char buf[1111];
> +char *archive_le16dec_filename = buf;
> +unsigned int archive_le16dec_end, archive_le16dec_fn_end,
> +    archive_le16dec_filename_size, archive_le16dec_offset;
> +char archive_le16dec_p[] = { 21, 0x7f };
> +
> +[[gnu::noipa]]
> +void
> +archive_le16dec ()
> +{
> +  archive_le16dec_filename_size = (short)archive_le16dec_filename_size;
> +  unsigned char flagbits = 0, flagbyte;
> +  archive_le16dec_end = archive_le16dec_filename_size;
> +  archive_le16dec_fn_end = archive_le16dec_filename_size * 2;
> +  archive_le16dec_filename_size = flagbits = 0;
> +  while (archive_le16dec_offset < archive_le16dec_end
> +         && archive_le16dec_filename_size < archive_le16dec_fn_end)
> +    {
> +      if (!flagbits)
> +        {
> +          flagbyte = archive_le16dec_p[archive_le16dec_offset++];
> +          flagbits = 8;
> +        }
> +      flagbits -= 2;
> +      if (!(flagbyte >> flagbits & 3))
> +        archive_le16dec_filename_size++;
> +    }
> +}
> +
> +int
> +main ()
> +{
> +  archive_le16dec_filename_size = 2;
> +  archive_le16dec ();
> +  if (archive_le16dec_filename_size != 1)
> +    __builtin_trap ();
> +}
> diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc
> index f524786f33b..b27037cb02f 100644
> --- a/gcc/tree-scalar-evolution.cc
> +++ b/gcc/tree-scalar-evolution.cc
> @@ -1391,10 +1391,19 @@ simplify_peeled_chrec (class loop *loop, tree arg, 
> tree init_cond)
>         && wi::to_widest (init_cond) == wi::to_widest (left_before)
>         && !scev_probably_wraps_p (NULL_TREE, left_before, right, NULL,
>                                    loop, false))
> -     return build_polynomial_chrec (loop->num, init_cond,
> -                                    chrec_convert (TREE_TYPE (ev),
> -                                                   right, NULL,
> -                                                   false, NULL_TREE));
> +     {
> +       tree tp = TREE_TYPE (right);
> +
> +       /* We need a sign-extension to make things like
> +          u8(6, 4, 2) => i32(6, 4, 2), instead of i32(6, 260, 514).  */
> +       if (TYPE_UNSIGNED (tp))
> +         right = fold_convert (signed_type_for (tp), right);
> +
> +       return build_polynomial_chrec (loop->num, init_cond,
> +                                      chrec_convert (TREE_TYPE (ev),
> +                                                     right, NULL,
> +                                                     false, NULL_TREE));
> +     }
>        return chrec_dont_know;
>      }
>  
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to