]> git.ipfire.org Git - thirdparty/xz.git/commitdiff
liblzma: Optimize the loop conditions in BCJ filters
authorLasse Collin <lasse.collin@tukaani.org>
Wed, 30 Oct 2024 17:54:34 +0000 (19:54 +0200)
committerLasse Collin <lasse.collin@tukaani.org>
Tue, 26 Nov 2024 17:17:42 +0000 (19:17 +0200)
Compilers cannot optimize the addition "i + 4" away since theoretically
it could overflow.

src/liblzma/simple/arm.c
src/liblzma/simple/arm64.c
src/liblzma/simple/armthumb.c
src/liblzma/simple/ia64.c
src/liblzma/simple/powerpc.c
src/liblzma/simple/sparc.c

index 58acb2d11adf7f09755100f05e0da965cc25ee92..f9d9c08b3c4238f71b96f12b57882a6753774ef3 100644 (file)
@@ -18,8 +18,10 @@ arm_code(void *simple lzma_attribute((__unused__)),
                uint32_t now_pos, bool is_encoder,
                uint8_t *buffer, size_t size)
 {
+       size &= ~(size_t)3;
+
        size_t i;
-       for (i = 0; i + 4 <= size; i += 4) {
+       for (i = 0; i < size; i += 4) {
                if (buffer[i + 3] == 0xEB) {
                        uint32_t src = ((uint32_t)(buffer[i + 2]) << 16)
                                        | ((uint32_t)(buffer[i + 1]) << 8)
index 16c2f565f73df85cf20d3117ef686ccb8277ff3a..bc5d3c3208aaee4b174c4f96c73dfe20715baeb5 100644 (file)
@@ -28,6 +28,8 @@ arm64_code(void *simple lzma_attribute((__unused__)),
                uint32_t now_pos, bool is_encoder,
                uint8_t *buffer, size_t size)
 {
+       size &= ~(size_t)3;
+
        size_t i;
 
        // Clang 14.0.6 on x86-64 makes this four times bigger and 40 % slower
@@ -37,7 +39,7 @@ arm64_code(void *simple lzma_attribute((__unused__)),
 #ifdef __clang__
 #      pragma clang loop vectorize(disable)
 #endif
-       for (i = 0; i + 4 <= size; i += 4) {
+       for (i = 0; i < size; i += 4) {
                uint32_t pc = (uint32_t)(now_pos + i);
                uint32_t instr = read32le(buffer + i);
 
index f1eeca9b80f14cbe07a21c470b354a89b6aed0f1..368b51c7fea9015b0d4fb9a73aa9509ef7f6db4a 100644 (file)
@@ -18,8 +18,13 @@ armthumb_code(void *simple lzma_attribute((__unused__)),
                uint32_t now_pos, bool is_encoder,
                uint8_t *buffer, size_t size)
 {
+       if (size < 4)
+               return 0;
+
+       size -= 4;
+
        size_t i;
-       for (i = 0; i + 4 <= size; i += 2) {
+       for (i = 0; i <= size; i += 2) {
                if ((buffer[i + 1] & 0xF8) == 0xF0
                                && (buffer[i + 3] & 0xF8) == 0xF8) {
                        uint32_t src = (((uint32_t)(buffer[i + 1]) & 7) << 19)
index 50250140997776e2dfaf3561c35229e188d96bfa..2a4aaebb47207864ffb05f845a3a786b7697ea5c 100644 (file)
@@ -25,8 +25,10 @@ ia64_code(void *simple lzma_attribute((__unused__)),
                4, 4, 0, 0, 4, 4, 0, 0
        };
 
+       size &= ~(size_t)15;
+
        size_t i;
-       for (i = 0; i + 16 <= size; i += 16) {
+       for (i = 0; i < size; i += 16) {
                const uint32_t instr_template = buffer[i] & 0x1F;
                const uint32_t mask = BRANCH_TABLE[instr_template];
                uint32_t bit_pos = 5;
index ba6cfbef3ab6448e1eac59a4ec447a0c1273df0e..ea47d14d4c3f8c3a4691f603fddf3b93dde2729a 100644 (file)
@@ -18,8 +18,10 @@ powerpc_code(void *simple lzma_attribute((__unused__)),
                uint32_t now_pos, bool is_encoder,
                uint8_t *buffer, size_t size)
 {
+       size &= ~(size_t)3;
+
        size_t i;
-       for (i = 0; i + 4 <= size; i += 4) {
+       for (i = 0; i < size; i += 4) {
                // PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link)
                if ((buffer[i] >> 2) == 0x12
                                && ((buffer[i + 3] & 3) == 1)) {
index e8ad285a1927c68a39362a806fd692c446c41d97..1fa4850458e8085a3c6cfe8f05325748a42127d4 100644 (file)
@@ -18,9 +18,10 @@ sparc_code(void *simple lzma_attribute((__unused__)),
                uint32_t now_pos, bool is_encoder,
                uint8_t *buffer, size_t size)
 {
-       size_t i;
-       for (i = 0; i + 4 <= size; i += 4) {
+       size &= ~(size_t)3;
 
+       size_t i;
+       for (i = 0; i < size; i += 4) {
                if ((buffer[i] == 0x40 && (buffer[i + 1] & 0xC0) == 0x00)
                                || (buffer[i] == 0x7F
                                && (buffer[i + 1] & 0xC0) == 0xC0)) {