Fixture 30

finite difference

C · 1 functions · 4 lanes · 4 of 4 function-lanes behave identically

All 4 lanes recompile and return the same results as the original.

tests/decompiler_fixtures/src/30_finite_difference.c source
#include <stdint.h>

__attribute__((noinline)) uint32_t heat_step_1d(int32_t *destination,
                                                const int32_t *source,
                                                int32_t n) {
    uint32_t checksum = 0;
    int32_t i;
    if (destination == 0 || source == 0 || n < 0 || n > 16) {
        return 0;
    }
    if (n > 0) {
        destination[0] = source[0];
    }
    for (i = 1; i + 1 < n; ++i) {
        int64_t weighted = (int64_t)source[i - 1] +
                           2 * (int64_t)source[i] + source[i + 1];
        destination[i] = (int32_t)(weighted / 4);
    }
    if (n > 1) {
        destination[n - 1] = source[n - 1];
    }
    for (i = 0; i < n; ++i) {
        checksum = checksum * 33u + (uint32_t)destination[i];
    }
    return checksum;
}

Recovered C

Generated by glaurung decompile --style decbench at b47f6b43. baseline.json records the result after recompiling the C and calling it beside the original with seeded inputs.

clang -O0

1/1
heat_step_1d pass 41 lines
// glaurung: heat_step_1d @ 0x1100
uint32_t heat_step_1d(int32_t * arg0, const int32_t * arg1, int32_t arg2) {
    unsigned int checksum;
    int i;
    long weighted;
    int local_4;
    // x86-64 prologue: save rbp
    checksum = 0;
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if ((arg1 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((long)(arg2) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 16) | ((long)(arg2) < 16)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 0) | ((long)(arg2) < 0)) == 0)) {
        *(int *)((long)arg0) = *(int *)((long)arg1);
    }
    for (i = 1; ((long)((int)(((unsigned long)((unsigned int)(i)) + 1))) < (long)(arg2)); i++) {
        weighted = (((long)((int)(arg1[(long)((int)(((unsigned long)((unsigned int)(i)) - 1)))])) + ((long)((int)(arg1[(long)(i)])) << 1)) + (long)((int)(arg1[(long)((int)(((unsigned long)((unsigned int)(i)) + 1)))])));
        arg0[(long)(i)] = ((long)((((__int128)(long)(((long)(weighted) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(weighted)) / (long)(4)));
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 1) | ((long)(arg2) < 1)) == 0)) {
        arg0[(long)((int)(((unsigned long)((unsigned int)(arg2)) - 1)))] = arg1[(long)((int)(((unsigned long)((unsigned int)(arg2)) - 1)))];
    }
    for (i = 0; (i < arg2); i++) {
        checksum = ((checksum * 33) + arg0[(long)(i)]);
    }
    local_4 = checksum;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}

clang -O2

1/1
heat_step_1d pass 100 lines
// glaurung: heat_step_1d @ 0x1100
uint32_t heat_step_1d(int32_t * arg0, const int32_t * arg1, int32_t arg2) {
    long weighted;
    int i;
    unsigned int checksum;
    long ret;
    long var15;
    long var16;
    long var2;
    long var20;
    long var22;
    long var27;
    int var33;
    long var4;
    int var40;
    int var47;
    long var5;
    int var54;
    long var55;
    long var56;
    long var62;
    long var64;
    long var66;
    int var71;
    long var73;
    long var8;
    long var9;
    var2 = 0;
    ret = 0;
    if (((unsigned long)((unsigned long)((unsigned int)((arg2 - 17)))) < (unsigned long)(0xfffffff0))) {
        return ret;
    }
    ret = 0;
    if ((arg0 == 0)) {
        return ret;
    }
    ret = 0;
    if ((arg1 == 0)) {
        return ret;
    }
    *(int *)(((long)arg0)) = *(int *)(((long)arg1));
    if (((unsigned long)(3) <= (unsigned long)((unsigned long)((unsigned int)(arg2))))) {
        var4 = (unsigned long)((unsigned int)((arg2 - 1)));
        var5 = 1;
        do {
            var8 = ((long)((int)(*(int *)(((long)arg1 + var5 * 4 - 0x4)))) + ((long)((int)(*(int *)(((long)arg1 + var5 * 4)))) * 2));
            var9 = (long)((int)(*(int *)(((long)arg1 + var5 * 4 + 0x4))));
            weighted = (var8 + var9);
            *(int *)(((long)arg0 + var5 * 4)) = ((unsigned long)(((0 <= weighted) ? weighted : ((var9 + var8) + 3))) >> 2);
            var15 = (var5 + 1);
            var5 = var15;
        } while ((var4 != var15));
    }
    if (((long)(arg2) < 2)) {
        ret = var2;
        if (((unsigned long)((unsigned int)(arg2)) != 1)) {
            return ret;
        }
        L_118e: ;
        var16 = (unsigned long)((unsigned int)(arg2));
        var20 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) & 3)));
        if (((unsigned long)(3) <= (unsigned long)(((unsigned long)((unsigned int)(arg2)) - 1)))) {
            var22 = (unsigned long)((unsigned int)((var16 & -4)));
            i = 0;
            var27 = 0;
            do {
                var33 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var27)) << 5))) + var27)) + *(int *)(((long)arg0 + i * 4)));
                var40 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var33)) << 5))) + (unsigned long)((unsigned int)(var33)))) + *(int *)(((long)arg0 + i * 4 + 0x4)));
                var47 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var40)) << 5))) + (unsigned long)((unsigned int)(var40)))) + *(int *)(((long)arg0 + i * 4 + 0x8)));
                var54 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var47)) << 5))) + (unsigned long)((unsigned int)(var47)))) + *(int *)(((long)arg0 + i * 4 + 0xc)));
                var55 = (unsigned long)((unsigned int)(var54));
                i = (i + 4);
                var27 = (unsigned long)((unsigned int)(var54));
                var56 = (unsigned long)((unsigned int)(i));
            } while ((var22 != i));
        } else {
            var56 = 0;
            var55 = 0;
        }
        ret = (unsigned long)((unsigned int)(var55));
        if ((var20 == 0)) {
            return ret;
        }
        var62 = (long)(((long)arg0 + (var56 * 4)));
        var64 = 0;
        var66 = (unsigned long)((unsigned int)(var55));
        do {
            var71 = ((unsigned int)(((unsigned long)((unsigned int)((var66 << 5))) + var55)) + *(int *)((var62 + var64 * 4)));
            var66 = (unsigned long)((unsigned int)(var71));
            var64 = (var64 + 1);
            var55 = (unsigned long)((unsigned int)(var71));
            ret = (unsigned long)((unsigned int)(var71));
        } while ((var20 != var64));
    } else {
        var73 = (unsigned long)((unsigned int)((arg2 - 1)));
        *(int *)(((long)arg0 + var73 * 4)) = *(int *)(((long)arg1 + var73 * 4));
        goto L_118e;
    }
    return ret;
}

gcc -O0

1/1
heat_step_1d pass 48 lines
// glaurung: heat_step_1d @ 0x10f9
uint32_t heat_step_1d(int32_t * arg0, const int32_t * arg1, int32_t arg2) {
    unsigned int checksum;
    int i;
    long weighted;
    long var20;
    int var4;
    // x86-64 prologue: save rbp
    checksum = 0;
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if ((arg1 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((long)(arg2) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 16) | ((long)(arg2) < 16)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 0) | ((long)(arg2) < 0)) == 0)) {
        *(int *)((long)arg0) = *(int *)((long)arg1);
    }
    i = 1;
    while (1) {
        var4 = ((unsigned int)(i) + 1);
        if (((((unsigned int)(arg2) == (unsigned int)(var4)) | (arg2 < var4)) != 0)) {
            break;
        }
        var20 = (long)((int)(arg1[(long)(i)]));
        weighted = ((long)((int)(arg1[((long)(i) + 1)])) + ((long)((int)(*(int *)(((long)arg1 + (((long)(i) << 2) - 4))))) + (var20 + var20)));
        arg0[(long)(i)] = ((long)(((weighted < 0) ? (weighted + 3) : weighted)) >> 2);
        i = (i + 1);
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 1) | ((long)(arg2) < 1)) == 0)) {
        *(int *)(((long)arg0 + (((long)(arg2) << 2) - 4))) = *(int *)(((long)arg1 + (((long)(arg2) << 2) - 4)));
    }
    for (i = 0; (i < arg2); i++) {
        checksum = ((unsigned int)(arg0[(long)(i)]) + (unsigned int)(((unsigned long)((unsigned int)((checksum << 5))) + checksum)));
    }
    // x86-64 epilogue: restore rbp
    return checksum;
}

gcc -O2

1/1
heat_step_1d pass 60 lines
// glaurung: heat_step_1d @ 0x1100
uint32_t heat_step_1d(int32_t * arg0, const int32_t * arg1, int32_t arg2) {
    int i;
    unsigned int checksum;
    long ret;
    long var0;
    long var13;
    long var15;
    long var2;
    long var21;
    int var27;
    long var4;
    long var9;
    long zf_6;
    var0 = (unsigned long)((unsigned int)(arg2));
    ret = 0;
    if ((arg0 == 0)) {
        return ret;
    }
    if ((arg1 == 0)) {
        return ret;
    }
    if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg2))))) {
        return ret;
    }
    if (((unsigned long)((unsigned int)(arg2)) == 0)) {
        return ret;
    }
    ret = (unsigned long)((unsigned int)(*(int *)(((long)arg1))));
    *(int *)(((long)arg0)) = ret;
    zf_6 = ((unsigned long)((unsigned int)(arg2)) == 2);
    if ((((unsigned long)((unsigned int)(arg2)) == 2) | ((long)(arg2) < 2))) {
        goto L_118c;
    }
    var2 = (unsigned long)((unsigned int)((arg2 - 3)));
    var4 = 0;
    do {
        var9 = (((long)((int)(*(int *)(((long)arg1 + var4 * 4)))) + ((long)((int)(*(int *)(((long)arg1 + var4 * 4 + 0x4)))) * 2)) + (long)((int)(*(int *)(((long)arg1 + var4 * 4 + 0x8)))));
        *(int *)(((long)arg0 + var4 * 4 + 0x4)) = ((long)(((0 <= var9) ? var9 : (var9 + 3))) >> 2);
        var13 = var4;
        var4 = (var4 + 1);
    } while ((var2 != var13));
    L_1161: ;
    var15 = ((long)((int)(var0)) << 2);
    *(int *)(((long)arg0 + var15 - 0x4)) = *(int *)(((long)arg1 + var15 - 0x4));
    i = 0;
    var21 = 0;
    do {
        var27 = ((unsigned int)((var21 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var21)) << 5))))) + *(int *)(((long)arg0 + i * 4)));
        ret = (unsigned long)((unsigned int)(var27));
        i = (i + 1);
        var21 = (unsigned long)((unsigned int)(var27));
    } while (((((unsigned int)(var0) == (unsigned int)(i)) | ((long)((int)(var0)) < (long)(i))) == 0));
    return ret;
    L_118c: ;
    if (zf_6) {
        goto L_1161;
    }
    return ret;
}

← 213 fixtures