Richard Biener <rguent...@suse.de> writes: > The following avoids accessing out-of-bound vector elements when > native encoding a boolean vector with sub-BITS_PER_UNIT precision > elements. The error was basing the number of elements to extract > on the rounded up total byte size involved and the patch bases > everything on the total number of elements to extract instead.
It's too long ago to be certain, but I think this was a deliberate choice. The point of the new vector constant encoding is that it can give an allegedly sensible value for any given index, even out-of-range ones. Since the padding bits are undefined, we should in principle have a free choice of what to use. And for VLA, it's often better to continue the existing pattern rather than force to zero. I don't strongly object to changing it. I think we should be careful about relying on zeroing for correctness though. The bits are in principle undefined and we can't rely on reading zeros from equivalent memory or register values. Thanks, Richard > > As a side-effect this now consistently results in zeros in the > padding of the last encoded byte which also avoids the failure > mode seen in PR113576. > > Bootstrapped and tested on x86_64-unknown-linux-gnu. > > OK? > > Thanks, > Richard. > > PR middle-end/113576 > * fold-const.cc (native_encode_vector_part): Avoid accessing > out-of-bound elements. > --- > gcc/fold-const.cc | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc > index 80e211e18c0..8638757312b 100644 > --- a/gcc/fold-const.cc > +++ b/gcc/fold-const.cc > @@ -8057,13 +8057,13 @@ native_encode_vector_part (const_tree expr, unsigned > char *ptr, int len, > off = 0; > > /* Zero the buffer and then set bits later where necessary. */ > - int extract_bytes = MIN (len, total_bytes - off); > + unsigned elts_per_byte = BITS_PER_UNIT / elt_bits; > + unsigned first_elt = off * elts_per_byte; > + unsigned extract_elts = MIN (len * elts_per_byte, count - first_elt); > + unsigned extract_bytes = CEIL (elt_bits * extract_elts, BITS_PER_UNIT); > if (ptr) > memset (ptr, 0, extract_bytes); > > - unsigned int elts_per_byte = BITS_PER_UNIT / elt_bits; > - unsigned int first_elt = off * elts_per_byte; > - unsigned int extract_elts = extract_bytes * elts_per_byte; > for (unsigned int i = 0; i < extract_elts; ++i) > { > tree elt = VECTOR_CST_ELT (expr, first_elt + i);