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? Thanks, Kyrill 2016-11-08 Kyrylo Tkachov <kyrylo.tkac...@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)