Message ID | 5821BF0A.1020609@foss.arm.com |
---|---|
State | New |
Headers | show |
On Tue, Nov 8, 2016 at 1:03 PM, Kyrill Tkachov <kyrylo.tkachov@foss.arm.com> wrote: > Hi all, > > There is an off-by-one error in the clear_bit_region helper in store merging > in the case where it deals with > multi-byte quantities starting at a non-zero bit offset. The particular > input is > {0xff, 0xff, 0xff} and we want to clear all bits except the least and most > significant i.e. we want: > {0x01, 0x00, 0x80} so it's called as clear_bit_region (input, 1, 22); > This ends up clearing one more bit due to this bug. The patch fixes that. > The last argument to clear_bit_region is the number of bits left to clear > and since in the previous call we cleared > BITS_PER_UNIT - start bits we should subtract exactly that amount from len > when calculating the bits left to clear. > This was uncovered when writing initial unit tests for these functions which > are included in the followup patch. > > Bootstrapped and tested on aarch64 and x86_64 (the affected function is only > called for little-endian code). > > Ok for trunk? Ok. Richard. > Thanks, > Kyrill > > 2016-11-08 Kyrylo Tkachov <kyrylo.tkachov@arm.com> > > PR tree-optimization/78234 > * gimple-ssa-store-merging.c (clear_bit_region): Fix off-by-one error > in start != 0 case.
diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index 36bc833af910f85c4c8ed7581a247f5d3182053d..46f92ba2d2f4e85c4256be11be5c8b1d40c21499 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -337,7 +337,7 @@ clear_bit_region (unsigned char *ptr, unsigned int start, else if (start != 0) { clear_bit_region (ptr, start, BITS_PER_UNIT - start); - clear_bit_region (ptr + 1, 0, len - (BITS_PER_UNIT - start) + 1); + clear_bit_region (ptr + 1, 0, len - (BITS_PER_UNIT - start)); } /* Whole bytes need to be cleared. */ else if (start == 0 && len > BITS_PER_UNIT)