On Fri, 22 Jan 2021, Jakub Jelinek wrote:

> Hi!
> 
> As discussed in the PR, the problem here is that the routines changed in
> this patch sign extend the difference of index and low_bound from the
> precision of the index, so e.g. when index is unsigned int and contains
> value -2U, we treat it as index -2 rather than 0x00000000fffffffeU on 64-bit
> arches.
> On the other hand, get_inner_reference which is used during expansion, does:
>             if (! integer_zerop (low_bound))
>               index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
>                                    index, low_bound);
>     
>             offset = size_binop (PLUS_EXPR, offset,
>                                  size_binop (MULT_EXPR,
>                                              fold_convert (sizetype, index),
>                                              unit_size));
> which effectively requires that either low_bound is constant 0 and then
> index in ARRAY_REFs can be arbitrary type which is then sign or zero
> extended to sizetype, or low_bound is something else and then index and
> low_bound must have compatible types and it is still converted afterwards to
> sizetype and from there then a few lines later:
> expr.c-  if (poly_int_tree_p (offset))
> expr.c-    {
> expr.c:      poly_offset_int tem = wi::sext (wi::to_poly_offset (offset),
> expr.c-                               TYPE_PRECISION (sizetype));
> The following patch makes those routines match what get_inner_reference is
> doing.
> 
> Bootstrapped/regtested on x86_64-linux (as usually, including Ada) and
> i686-linux, ok for trunk?

OK for trunk.

Thanks,
Richard.

> 2021-01-22  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/98255
>       * tree-dfa.c (get_ref_base_and_extent): For ARRAY_REFs, sign
>       extend index - low_bound from sizetype's precision rather than index
>       precision.
>       (get_addr_base_and_unit_offset_1): Likewise.
>       * tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Likewise.
>       * gimple-fold.c (fold_const_aggregate_ref_1): Likewise.
> 
>       * gcc.dg/pr98255.c: New test.
> 
> --- gcc/tree-dfa.c.jj 2021-01-04 10:25:37.220252089 +0100
> +++ gcc/tree-dfa.c    2021-01-21 16:43:33.302962080 +0100
> @@ -503,7 +503,7 @@ get_ref_base_and_extent (tree exp, poly_
>               poly_offset_int woffset
>                 = wi::sext (wi::to_poly_offset (index)
>                             - wi::to_poly_offset (low_bound),
> -                           TYPE_PRECISION (TREE_TYPE (index)));
> +                           TYPE_PRECISION (sizetype));
>               woffset *= wi::to_offset (unit_size);
>               woffset <<= LOG2_BITS_PER_UNIT;
>               bit_offset += woffset;
> @@ -564,7 +564,7 @@ get_ref_base_and_extent (tree exp, poly_
>                     {
>                       poly_offset_int woffset
>                         = wi::sext (omin - lbound,
> -                                   TYPE_PRECISION (TREE_TYPE (index)));
> +                                   TYPE_PRECISION (sizetype));
>                       woffset *= wi::to_offset (unit_size);
>                       woffset <<= LOG2_BITS_PER_UNIT;
>                       bit_offset += woffset;
> @@ -822,7 +822,7 @@ get_addr_base_and_unit_offset_1 (tree ex
>           poly_offset_int woffset
>               = wi::sext (wi::to_poly_offset (index)
>                           - wi::to_poly_offset (low_bound),
> -                         TYPE_PRECISION (TREE_TYPE (index)));
> +                         TYPE_PRECISION (sizetype));
>           woffset *= wi::to_offset (unit_size);
>           byte_offset += woffset.force_shwi ();
>         }
> --- gcc/tree-ssa-sccvn.c.jj   2021-01-13 11:22:30.807345423 +0100
> +++ gcc/tree-ssa-sccvn.c      2021-01-21 16:46:52.780699466 +0100
> @@ -1108,7 +1108,7 @@ ao_ref_init_from_vn_reference (ao_ref *r
>             poly_offset_int woffset
>               = wi::sext (wi::to_poly_offset (op->op0)
>                           - wi::to_poly_offset (op->op1),
> -                         TYPE_PRECISION (TREE_TYPE (op->op0)));
> +                         TYPE_PRECISION (sizetype));
>             woffset *= wi::to_offset (op->op2) * vn_ref_op_align_unit (op);
>             woffset <<= LOG2_BITS_PER_UNIT;
>             offset += woffset;
> --- gcc/gimple-fold.c.jj      2021-01-05 09:17:24.754566798 +0100
> +++ gcc/gimple-fold.c 2021-01-21 16:45:58.960309941 +0100
> @@ -8007,7 +8007,7 @@ fold_const_aggregate_ref_1 (tree t, tree
>             poly_offset_int woffset
>               = wi::sext (wi::to_poly_offset (idx)
>                           - wi::to_poly_offset (low_bound),
> -                         TYPE_PRECISION (TREE_TYPE (idx)));
> +                         TYPE_PRECISION (sizetype));
>             woffset *= tree_to_uhwi (unit_size);
>             woffset *= BITS_PER_UNIT;
>             if (woffset.to_shwi (&offset))
> --- gcc/testsuite/gcc.dg/pr98255.c.jj 2021-01-21 16:54:39.258416413 +0100
> +++ gcc/testsuite/gcc.dg/pr98255.c    2021-01-21 16:54:11.531730111 +0100
> @@ -0,0 +1,49 @@
> +/* PR tree-optimization/98255 */
> +/* { dg-do run } */
> +/* { dg-options "-Os" } */
> +/* { dg-additional-options "-fPIC" { target fpic } } */
> +
> +struct A { volatile unsigned b; unsigned c; };
> +int d, *e, h, k, l;
> +static struct A f;
> +long g;
> +static unsigned i = -2U;
> +volatile int j;
> +
> +long
> +foo (void)
> +{
> +  char n[4][4][3]
> +    = { { {9, 2, 8}, {9, 2, 8}, {9, 2, 8}, {9} }, { {8} }, { {8} }, { {2} } 
> };
> +  while (d)
> +    {
> +      for (; f.c < 4; f.c++)
> +     {
> +       *e = 0;
> +       h = n[f.c + 4][0][d];
> +     }
> +      while (g)
> +     return n[0][3][i];
> +      while (1)
> +     {
> +       if (k)
> +         {
> +           j = 0;
> +           if (j)
> +             continue;
> +         }
> +       if (l)
> +         break;
> +     }
> +    }
> +  return 0;
> +}
> +
> +int
> +main ()
> +{
> +  asm volatile ("" : "+g" (d), "+g" (g), "+g" (f.c));
> +  asm volatile ("" : "+g" (e), "+g" (k), "+g" (l));
> +  foo ();
> +  return 0;
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to