1

xz: optimize for-loop conditions in the BCJ decoders

Compilers cannot optimize the addition "i + 4" away since theoretically it
could overflow.

Link: https://lkml.kernel.org/r/20240721133633.47721-11-lasse.collin@tukaani.org
Signed-off-by: Lasse Collin <lasse.collin@tukaani.org>
Reviewed-by: Sam James <sam@gentoo.org>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Emil Renner Berthing <emil.renner.berthing@canonical.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Jubin Zhong <zhongjubin@huawei.com>
Cc: Jules Maselbas <jmaselbas@zdiv.net>
Cc: Krzysztof Kozlowski <krzk@kernel.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Rui Li <me@lirui.org>
Cc: Simon Glass <sjg@chromium.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Lasse Collin 2024-07-21 16:36:25 +03:00 committed by Andrew Morton
parent 2ee96abef2
commit bdfc041171

View File

@ -161,7 +161,9 @@ static size_t bcj_powerpc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
size_t i; size_t i;
uint32_t instr; uint32_t instr;
for (i = 0; i + 4 <= size; i += 4) { size &= ~(size_t)3;
for (i = 0; i < size; i += 4) {
instr = get_unaligned_be32(buf + i); instr = get_unaligned_be32(buf + i);
if ((instr & 0xFC000003) == 0x48000001) { if ((instr & 0xFC000003) == 0x48000001) {
instr &= 0x03FFFFFC; instr &= 0x03FFFFFC;
@ -218,7 +220,9 @@ static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
/* Instruction normalized with bit_res for easier manipulation */ /* Instruction normalized with bit_res for easier manipulation */
uint64_t norm; uint64_t norm;
for (i = 0; i + 16 <= size; i += 16) { size &= ~(size_t)15;
for (i = 0; i < size; i += 16) {
mask = branch_table[buf[i] & 0x1F]; mask = branch_table[buf[i] & 0x1F];
for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41) { for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41) {
if (((mask >> slot) & 1) == 0) if (((mask >> slot) & 1) == 0)
@ -266,7 +270,9 @@ static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
size_t i; size_t i;
uint32_t addr; uint32_t addr;
for (i = 0; i + 4 <= size; i += 4) { size &= ~(size_t)3;
for (i = 0; i < size; i += 4) {
if (buf[i + 3] == 0xEB) { if (buf[i + 3] == 0xEB) {
addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8) addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8)
| ((uint32_t)buf[i + 2] << 16); | ((uint32_t)buf[i + 2] << 16);
@ -289,7 +295,12 @@ static size_t bcj_armthumb(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
size_t i; size_t i;
uint32_t addr; uint32_t addr;
for (i = 0; i + 4 <= size; i += 2) { if (size < 4)
return 0;
size -= 4;
for (i = 0; i <= size; i += 2) {
if ((buf[i + 1] & 0xF8) == 0xF0 if ((buf[i + 1] & 0xF8) == 0xF0
&& (buf[i + 3] & 0xF8) == 0xF8) { && (buf[i + 3] & 0xF8) == 0xF8) {
addr = (((uint32_t)buf[i + 1] & 0x07) << 19) addr = (((uint32_t)buf[i + 1] & 0x07) << 19)
@ -317,7 +328,9 @@ static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
size_t i; size_t i;
uint32_t instr; uint32_t instr;
for (i = 0; i + 4 <= size; i += 4) { size &= ~(size_t)3;
for (i = 0; i < size; i += 4) {
instr = get_unaligned_be32(buf + i); instr = get_unaligned_be32(buf + i);
if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) { if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) {
instr <<= 2; instr <<= 2;