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)