Fixture 31

edit distance

C · 2 functions · 4 lanes · 8 of 8 function-lanes behave identically

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

Levenshtein distance over a flat (ED_MAX+1)^2 table. The classic three-way minimum makes the inner body a small dependence lattice: every cell reads two previous rows/columns, so a decompiler must keep the row stride and the -1 offsets exact to reproduce the result.

tests/decompiler_fixtures/src/31_edit_distance.c source
#include <stdint.h>

/* Levenshtein distance over a flat (ED_MAX+1)^2 table. The classic
 * three-way minimum makes the inner body a small dependence lattice: every
 * cell reads two previous rows/columns, so a decompiler must keep the row
 * stride and the -1 offsets exact to reproduce the result. */

#define ED_MAX 8
#define ED_STRIDE (ED_MAX + 1)

__attribute__((noinline)) int32_t
edit_distance(const uint8_t *left, int32_t left_length, const uint8_t *right,
              int32_t right_length) {
    int32_t table[ED_STRIDE * ED_STRIDE];
    int32_t i;
    int32_t j;
    if (left == 0 || right == 0 || left_length < 0 || right_length < 0 ||
        left_length > ED_MAX || right_length > ED_MAX) {
        return -1;
    }
    for (i = 0; i <= left_length; ++i) {
        table[i * ED_STRIDE] = i;
    }
    for (j = 0; j <= right_length; ++j) {
        table[j] = j;
    }
    for (i = 1; i <= left_length; ++i) {
        for (j = 1; j <= right_length; ++j) {
            int32_t cost = (left[i - 1] == right[j - 1]) ? 0 : 1;
            int32_t best = table[(i - 1) * ED_STRIDE + j] + 1;
            int32_t insertion = table[i * ED_STRIDE + (j - 1)] + 1;
            int32_t substitution = table[(i - 1) * ED_STRIDE + (j - 1)] + cost;
            if (insertion < best) {
                best = insertion;
            }
            if (substitution < best) {
                best = substitution;
            }
            table[i * ED_STRIDE + j] = best;
        }
    }
    return table[left_length * ED_STRIDE + right_length];
}

__attribute__((noinline)) int32_t
hamming_distance(const uint8_t *left, const uint8_t *right, int32_t length) {
    int32_t distance = 0;
    int32_t i;
    if (left == 0 || right == 0 || length < 0 || length > ED_MAX) {
        return -1;
    }
    for (i = 0; i < length; ++i) {
        if (left[i] != right[i]) {
            distance += 1;
        }
    }
    return distance;
}

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

2/2
edit_distance pass 68 lines
// glaurung: edit_distance @ 0x1100
__attribute__((no_stack_protector)) int32_t edit_distance(const uint8_t * arg0, int32_t arg1, const uint8_t * arg2, int32_t arg3) {
    int i;
    int j;
    int cost;
    int best;
    int insertion;
    int substitution;
    unsigned char local_170[324];
    int local_4;
    // x86-64 prologue: save rbp, frame 272 bytes
    if ((arg0 == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if ((arg2 == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg1) < 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg3) < 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg3)) == 8) | ((long)(arg3) < 8)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    for (i = 0; ((((unsigned int)(i) == (unsigned int)(arg1)) | (i < arg1)) != 0); i++) {
        *(int *)((&local_170[0] + ((long)((int)((i * 9))) * 4))) = i;
    }
    for (j = 0; ((((unsigned int)(j) == (unsigned int)(arg3)) | (j < arg3)) != 0); j++) {
        *(int *)((&local_170[0] + ((long)(j) * 4))) = j;
    }
    i = 1;
    while (((((unsigned int)(i) == (unsigned int)(arg1)) | (i < arg1)) != 0)) {
        for (j = 1; ((((unsigned int)(j) == (unsigned int)(arg3)) | (j < arg3)) != 0); j++) {
            cost = (((unsigned int)((unsigned char)(arg0[(long)((int)(((unsigned long)((unsigned int)(i)) - 1)))])) == (unsigned int)((unsigned char)(arg2[(long)((int)(((unsigned long)((unsigned int)(j)) - 1)))]))) ? 0 : 1);
            best = ((unsigned int)(*(int *)((&local_170[0] + ((long)((int)((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) - 1))) * 9) + j))) * 4)))) + 1);
            insertion = ((unsigned int)(*(int *)((&local_170[0] + ((long)((int)(((i * 9) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(j)) - 1)))))) * 4)))) + 1);
            substitution = ((unsigned int)(*(int *)((&local_170[0] + ((long)((int)((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) - 1))) * 9) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(j)) - 1)))))) * 4)))) + cost);
            if ((insertion < best)) {
                best = insertion;
            }
            if ((substitution < best)) {
                best = substitution;
            }
            *(int *)((&local_170[0] + ((long)((int)(((i * 9) + j))) * 4))) = best;
        }
        i = ((unsigned int)(i) + 1);
    }
    local_4 = *(int *)((&local_170[0] + ((long)((int)(((arg1 * 9) + arg3))) * 4)));
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
hamming_distance pass 36 lines
// glaurung: hamming_distance @ 0x1370
int32_t hamming_distance(const uint8_t * arg0, const uint8_t * arg1, int32_t arg2) {
    int distance;
    int i;
    int local_4;
    // x86-64 prologue: save rbp
    distance = 0;
    if ((arg0 == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if ((arg1 == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg2) < 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 8) | ((long)(arg2) < 8)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    for (i = 0; (i < arg2); i++) {
        if (((unsigned int)((unsigned char)(arg0[i])) != (unsigned int)((unsigned char)(arg1[i])))) {
            distance = ((unsigned int)(distance) + 1);
        }
    }
    local_4 = distance;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}

clang -O2

2/2
edit_distance pass 529 lines
// glaurung: edit_distance @ 0x1100
__attribute__((no_stack_protector)) int32_t edit_distance(const uint8_t * arg0, int32_t arg1, const uint8_t * arg2, int32_t arg3) {
    extern long __unknown(long, ...);
    int i;
    int best;
    int j;
    int substitution;
    unsigned char local_17c[380];
    long local_180;
    long local_188;
    long local_190;
    long local_198;
    long local_1a0;
    long local_1a8;
    long local_1b8;
    long local_1c0;
    long local_1c8;
    long local_1d0;
    long local_1d8;
    long local_1e0;
    long ret;
    long var0;
    long var11;
    long var14;
    long var153;
    long var154;
    long var156;
    int var157;
    int var158;
    int var159;
    long var16;
    int var160;
    int var161;
    int var162;
    int var163;
    int var164;
    long var174;
    long var176;
    long var177;
    long var179;
    long var181;
    long var184;
    long var185;
    long var187;
    long var188;
    long var189;
    long var191;
    int var192;
    int var193;
    int var194;
    int var195;
    int var196;
    int var197;
    int var198;
    int var199;
    long var200;
    long var203;
    long var204;
    int var207;
    long var208;
    long var210;
    long var211;
    long var217;
    long var218;
    long var22;
    long var220;
    long var222;
    long var225;
    long var229;
    long var23;
    long var231;
    long var233;
    long var235;
    long var25;
    long var255;
    long var256;
    long var26;
    int var269;
    int var27;
    int var270;
    long var28;
    int var285;
    int var286;
    int var287;
    int var288;
    long var29;
    int var290;
    int var291;
    int var292;
    int var293;
    int var295;
    int var296;
    int var297;
    int var298;
    long var3;
    int var304;
    int var305;
    int var306;
    int var307;
    int var316;
    int var317;
    int var318;
    int var319;
    long var32;
    int var325;
    int var326;
    int var327;
    int var328;
    char * var33;
    long var350;
    int var351;
    long var353;
    int var354;
    long var357;
    long var358;
    long var36;
    long var39;
    long var4;
    long var42;
    int var43;
    int var44;
    int var45;
    int var46;
    long var49;
    long var50;
    int var51;
    int var52;
    int var53;
    int var54;
    long var57;
    int var58;
    int var59;
    int var60;
    int var61;
    int var62;
    int var63;
    int var64;
    int var65;
    int var66;
    int var67;
    int var68;
    int var69;
    int var70;
    int var71;
    int var72;
    int var73;
    int var74;
    int var75;
    int var76;
    int var77;
    int var78;
    int var79;
    long var8;
    int var80;
    int var81;
    int var82;
    int var83;
    int var84;
    int var85;
    int var86;
    int var87;
    int var88;
    int var89;
    // x86-64 prologue: save callee registers, frame 48 bytes
    ret = 0xffffffff;
    if (((((unsigned long)((unsigned int)(arg3)) == 8) | ((long)(arg3) < 8)) == 0)) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    if ((arg2 == 0)) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    var0 = (unsigned long)((unsigned int)(arg3));
    if (((long)((int)((arg3 | arg1))) < 0)) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    var3 = var4;
    if (((long)(arg1) < 0)) {
        goto L_11bf;
    }
    var3 = ((unsigned long)((unsigned int)(arg1)) + 1);
    var8 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var3)) & 3)));
    if (((unsigned long)((unsigned long)((unsigned int)(arg1))) < (unsigned long)(3))) {
        var11 = 0;
        goto L_1195;
    }
    var3 = (unsigned long)((unsigned int)((var3 & -4)));
    var14 = (long)((&local_17c[0] + 4));
    var16 = 0;
    do {
        *(int *)((var14)) = var16;
        *(int *)((var14 + 0x24)) = (var16 + 1);
        *(int *)((var14 + 0x48)) = (var16 + 2);
        *(int *)((var14 + 0x6c)) = (var16 + 3);
        var16 = (var16 + 4);
        var14 = (var14 + 144);
        var11 = var16;
    } while ((var16 != var3));
    L_1195: ;
    ret = var11;
    if ((var8 == 0)) {
        goto L_11bf;
    }
    var3 = (long)((((&local_17c[0] + 20) + ((var11 + (var11 * 8)) * 4)) - 16));
    var22 = (var8 << 2);
    var23 = (var22 + (var22 * 8));
    var25 = 0;
    var26 = var11;
    do {
        *(int *)((var3 + var25)) = var26;
        var27 = (var26 + 1);
        var26 = (unsigned long)((unsigned int)(var27));
        var25 = (var25 + 36);
        ret = (unsigned long)((unsigned int)(var27));
    } while ((var23 != var25));
    L_11bf: ;
    var28 = (long)arg0;
    if (((long)((int)(var0)) < 0)) {
        goto L_133d;
    }
    var29 = (unsigned long)((unsigned int)((var0 + 1)));
    if (((unsigned long)((unsigned long)((unsigned int)(var0))) < (unsigned long)(7))) {
        var32 = 0;
        var28 = (long)arg0;
        goto L_1330;
    }
    var33 = (char *)arg0;
    var32 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var29)) & -8)));
    var36 = (var32 - 8);
    var39 = (((unsigned long)(var36) >> 3) + 1);
    var42 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var39)) & 3)));
    if (((unsigned long)(var36) < (unsigned long)(24))) {
        var43 = 0;
        var44 = 1;
        var45 = 2;
        var46 = 3;
        var49 = 0;
        goto L_12d8;
    }
    var50 = (var39 & -4);
    var51 = 0;
    var52 = 1;
    var53 = 2;
    var54 = 3;
    var57 = 0;
    var58 = 4;
    var59 = 4;
    var60 = 4;
    var61 = 4;
    var62 = 8;
    var63 = 8;
    var64 = 8;
    var65 = 8;
    var66 = 12;
    var67 = 12;
    var68 = 12;
    var69 = 12;
    var70 = 16;
    var71 = 16;
    var72 = 16;
    var73 = 16;
    var74 = 20;
    var75 = 20;
    var76 = 20;
    var77 = 20;
    var78 = 24;
    var79 = 24;
    var80 = 24;
    var81 = 24;
    var82 = 28;
    var83 = 28;
    var84 = 28;
    var85 = 28;
    var86 = 32;
    var87 = 32;
    var88 = 32;
    var89 = 32;
    do {
        *(int *)((&local_17c[0] + ((var57 * 4) + 4))) = var51;
        *(int *)((&local_17c[0] + ((var57 * 4) + 8))) = var52;
        *(int *)((&local_17c[0] + ((var57 * 4) + 12))) = var53;
        *(int *)((&local_17c[0] + ((var57 * 4) + 16))) = var54;
        *(int *)((&local_17c[0] + ((var57 * 4) + 20))) = (var51 + var58);
        *(int *)((&local_17c[0] + ((var57 * 4) + 24))) = (var52 + var59);
        *(int *)((&local_17c[0] + ((var57 * 4) + 28))) = (var53 + var60);
        *(int *)((&local_17c[0] + ((var57 * 4) + 32))) = (var54 + var61);
        *(int *)((&local_17c[0] + ((var57 * 4) + 36))) = (var51 + var62);
        *(int *)((&local_17c[0] + ((var57 * 4) + 40))) = (var52 + var63);
        *(int *)((&local_17c[0] + ((var57 * 4) + 44))) = (var53 + var64);
        *(int *)((&local_17c[0] + ((var57 * 4) + 48))) = (var54 + var65);
        *(int *)((&local_17c[0] + ((var57 * 4) + 52))) = (var51 + var66);
        *(int *)((&local_17c[0] + ((var57 * 4) + 56))) = (var52 + var67);
        *(int *)((&local_17c[0] + ((var57 * 4) + 60))) = (var53 + var68);
        *(int *)((&local_17c[0] + ((var57 * 4) + 64))) = (var54 + var69);
        *(int *)((&local_17c[0] + ((var57 * 4) + 68))) = (var51 + var70);
        *(int *)((&local_17c[0] + ((var57 * 4) + 72))) = (var52 + var71);
        *(int *)((&local_17c[0] + ((var57 * 4) + 76))) = (var53 + var72);
        *(int *)((&local_17c[0] + ((var57 * 4) + 80))) = (var54 + var73);
        *(int *)((&local_17c[0] + ((var57 * 4) + 84))) = (var51 + var74);
        *(int *)((&local_17c[0] + ((var57 * 4) + 88))) = (var52 + var75);
        *(int *)((&local_17c[0] + ((var57 * 4) + 92))) = (var53 + var76);
        *(int *)((&local_17c[0] + ((var57 * 4) + 96))) = (var54 + var77);
        *(int *)((&local_17c[0] + ((var57 * 4) + 100))) = (var51 + var78);
        *(int *)((&local_17c[0] + ((var57 * 4) + 104))) = (var52 + var79);
        *(int *)((&local_17c[0] + ((var57 * 4) + 108))) = (var53 + var80);
        *(int *)((&local_17c[0] + ((var57 * 4) + 112))) = (var54 + var81);
        *(int *)((&local_17c[0] + ((var57 * 4) + 116))) = (var51 + var82);
        *(int *)((&local_17c[0] + ((var57 * 4) + 120))) = (var52 + var83);
        *(int *)((&local_17c[0] + ((var57 * 4) + 124))) = (var53 + var84);
        *(int *)((&local_17c[0] + ((var57 * 4) + 128))) = (var54 + var85);
        var57 = (var57 + 32);
        var51 = (var51 + var86);
        var52 = (var52 + var87);
        var53 = (var53 + var88);
        var54 = (var54 + var89);
        var50 = (var50 - 4);
        var49 = var57;
        var39 = var50;
        var43 = var51;
        var44 = var52;
        var45 = var53;
        var46 = var54;
    } while ((var50 != 0));
    L_12d8: ;
    if ((var42 != 0)) {
        var153 = (long)(((&local_17c[0] + 20) + (var49 * 4)));
        var154 = (var42 << 5);
        var156 = 0;
        var157 = 4;
        var158 = 4;
        var159 = 4;
        var160 = 4;
        var161 = 8;
        var162 = 8;
        var163 = 8;
        var164 = 8;
        do {
            *(int *)((var153 + var156 - 0x10)) = var43;
            *(int *)((var153 + var156 - 0xc)) = var44;
            *(int *)((var153 + var156 - 0x8)) = var45;
            *(int *)((var153 + var156 - 0x4)) = var46;
            *(int *)((var153 + var156)) = (var43 + var157);
            *(int *)((var153 + var156 + 0x4)) = (var44 + var158);
            *(int *)((var153 + var156 + 0x8)) = (var45 + var159);
            *(int *)((var153 + var156 + 0xc)) = (var46 + var160);
            var43 = (var43 + var161);
            var44 = (var44 + var162);
            var45 = (var45 + var163);
            var46 = (var46 + var164);
            var156 = (var156 + 32);
        } while ((var154 != var156));
    }
    var28 = (long)var33;
    if ((var32 == var29)) {
        goto L_133d;
    }
    L_1330: ;
    *(int *)((&local_17c[0] + ((var32 * 4) + 4))) = var32;
    var174 = (var32 + 1);
    var32 = var174;
    if ((var29 != var174)) {
        goto L_1330;
    }
    L_133d: ;
    var176 = var0;
    if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
        // x86-64 epilogue: restore callee registers
        return (unsigned int)(*(int *)((&local_17c[0] + (((long)((int)(((unsigned long)((unsigned int)((arg1 + (arg1 * 8)))) + var176))) * 4) + 4))));
    }
    var177 = (unsigned long)((unsigned int)((var0 + 1)));
    var179 = (unsigned long)((unsigned int)((arg1 + 1)));
    local_180 = (var177 - 2);
    var181 = (var177 - 1);
    local_188 = (long)((((&local_17c[0] + 20) + (var177 * 4)) - 20));
    local_190 = (var177 + 8);
    local_1b8 = var181;
    var184 = (var181 & -4);
    local_198 = var184;
    var185 = (var184 + 1);
    local_1a0 = var185;
    var187 = (long)((&local_17c[0] + 4));
    var188 = 10;
    var189 = 9;
    var191 = 0;
    var192 = -1;
    var193 = -1;
    var194 = -1;
    var195 = -1;
    var196 = 1;
    var197 = 1;
    var198 = 1;
    var199 = 1;
    local_1a8 = var0;
    local_1e0 = var28;
    var200 = 1;
    goto L_13ed;
    L_13d0: ;
    i = (var200 + 1);
    var191 = (var191 + 1);
    var187 = (var187 + 36);
    var188 = (var188 + 9);
    var189 = (var189 + 9);
    var200 = (unsigned long)((unsigned int)(i));
    var176 = var0;
    if ((i == var179)) {
        // x86-64 epilogue: restore callee registers
        return (unsigned int)(*(int *)((&local_17c[0] + (((long)((int)(((unsigned long)((unsigned int)((arg1 + (arg1 * 8)))) + var176))) * 4) + 4))));
    }
    L_13ed: ;
    if ((((unsigned long)((unsigned int)(var0)) == 0) | ((long)((int)(var0)) < 0))) {
        goto L_13d0;
    }
    var203 = (*(char *)((var200 + var28 - 0x1)) & 255);
    var204 = 1;
    if (((unsigned long)(local_1b8) < (unsigned long)(4))) {
        goto L_15b0;
    }
    var207 = ((-(unsigned long)((unsigned int)((var191 + (var191 * 8))))) - 11);
    var185 = (unsigned long)((unsigned int)(var207));
    var208 = local_180;
    if (((unsigned long)((unsigned long)((unsigned int)(var207))) < (unsigned long)((unsigned long)((unsigned int)(local_180))))) {
        goto L_15b0;
    }
    var185 = ((unsigned long)(var208) >> 32);
    if ((var185 != 0)) {
        goto L_15b0;
    }
    var210 = var179;
    var211 = (var191 + (var191 * 8));
    local_1c0 = (local_190 + var211);
    local_1c8 = (local_1b8 + var211);
    var217 = (unsigned long)((unsigned int)(((var191 + (var191 * 8)) + 10)));
    var218 = (long)((((&local_17c[0] + 20) + (var217 * 4)) - 16));
    var220 = (local_188 + (var217 * 4));
    local_1d8 = (long)((((&local_17c[0] + 20) + (var211 * 4)) - 12));
    var222 = (long)((((&local_17c[0] + 20) + ((var211 + var177) * 4)) - 16));
    local_1d0 = (long)((((&local_17c[0] + 20) + (var211 * 4)) + 20));
    var225 = (long)((((&local_17c[0] + 20) + (local_1c0 * 4)) - 16));
    local_1c0 = (long)((((&local_17c[0] + 20) + (var211 * 4)) - 16));
    var229 = (long)((((&local_17c[0] + 20) + (local_1c8 * 4)) - 16));
    local_1c8 = ((unsigned long)(var218) < (unsigned long)(var222));
    local_1d8 = ((unsigned long)(local_1d8) < (unsigned long)(var220));
    var231 = ((var222 & -256) | ((unsigned long)(var218) < (unsigned long)(var225)));
    local_1d0 = ((unsigned long)(local_1d0) < (unsigned long)(var220));
    var233 = ((unsigned long)(var218) < (unsigned long)(var229));
    var235 = ((unsigned long)(local_1c0) < (unsigned long)(var220));
    var185 = ((var229 & -256) | ((unsigned char)(local_1d8) & 255));
    if (((unsigned long)((unsigned char)(((unsigned char)(local_1c8) & (var185 & 255)))) == 0)) {
        var0 = local_1a8;
        if (((unsigned long)((unsigned char)(((var231 & 255) & (unsigned char)(local_1d0)))) != 0)) {
            goto L_15a3;
        }
        var28 = local_1e0;
        var179 = var210;
        if (((unsigned long)((unsigned char)(((var233 & 255) & (var235 & 255)))) != 0)) {
            goto L_15b0;
        }
        var255 = 0;
        var256 = local_198;
        do {
            var269 = __unknown(0);
            var270 = __unknown(0);
            var285 = (*(int *)((var187 + var255 * 4)) + (((unsigned int)((unsigned short)(var269)) | ((unsigned int)((unsigned short)(var269)) << 16)) & var196));
            var286 = (*(int *)((var187 + var255 * 4 + 0x4)) + (((unsigned int)((unsigned short)((((unsigned int)(var269) >> 16) & 0xffff))) | ((unsigned int)((unsigned short)((((unsigned int)(var269) >> 16) & 0xffff))) << 16)) & var197));
            var287 = (*(int *)((var187 + var255 * 4 + 0x8)) + (((unsigned int)((unsigned short)(var270)) | ((unsigned int)((unsigned short)(var270)) << 16)) & var198));
            var288 = (*(int *)((var187 + var255 * 4 + 0xc)) + (((unsigned int)((unsigned short)((((unsigned int)(var270) >> 16) & 0xffff))) | ((unsigned int)((unsigned short)((((unsigned int)(var270) >> 16) & 0xffff))) << 16)) & var199));
            var290 = *(int *)((var187 + var255 * 4 + 0x4));
            var291 = *(int *)((var187 + var255 * 4 + 0x8));
            var292 = *(int *)((var187 + var255 * 4 + 0xc));
            var293 = *(int *)((var187 + var255 * 4 + 0x10));
            var295 = *(int *)((var187 + var255 * 4 + 0x24));
            var296 = *(int *)((var187 + var255 * 4 + 0x28));
            var297 = *(int *)((var187 + var255 * 4 + 0x2c));
            var298 = *(int *)((var187 + var255 * 4 + 0x30));
            var304 = (-(var295 < var290));
            var305 = (-(var296 < var291));
            var306 = (-(var297 < var292));
            var307 = (-(var298 < var293));
            var316 = (((~var304) & var290) | (var295 & var304));
            var317 = (((~var305) & var291) | (var296 & var305));
            var318 = (((~var306) & var292) | (var297 & var306));
            var319 = (((~var307) & var293) | (var298 & var307));
            var325 = (-(var316 < var285));
            var326 = (-(var317 < var286));
            var327 = (-(var318 < var287));
            var328 = (-(var319 < var288));
            var185 = (unsigned long)((unsigned int)((var188 + var255)));
            *(int *)((&local_17c[0] + ((var185 * 4) + 4))) = (((~var325) & var285) | ((var316 - var192) & var325));
            *(int *)((&local_17c[0] + ((var185 * 4) + 8))) = (((~var326) & var286) | ((var317 - var193) & var326));
            *(int *)((&local_17c[0] + ((var185 * 4) + 12))) = (((~var327) & var287) | ((var318 - var194) & var327));
            *(int *)((&local_17c[0] + ((var185 * 4) + 16))) = (((~var328) & var288) | ((var319 - var195) & var328));
            var255 = (var255 + 4);
        } while ((var256 != var255));
        var204 = local_1a0;
        if ((local_1b8 != var256)) {
            goto L_15b0;
        }
        goto L_13d0;
    }
    var0 = local_1a8;
    L_15a3: ;
    var28 = local_1e0;
    var179 = var210;
    L_15b0: ;
    var350 = (unsigned long)((unsigned int)(*(int *)((var187 + var204 * 4))));
    var351 = (((unsigned char)((var203 & 255)) != (unsigned char)(*(char *)(((long)arg2 + var204 - 0x1)))) + *(int *)((var187 + var204 * 4 - 0x4)));
    var353 = (unsigned long)((unsigned int)(*(int *)((var187 + var204 * 4 + 0x20))));
    var354 = (((long)((int)(var353)) < (long)((int)(var350))) ? var353 : var350);
    var357 = (unsigned long)((unsigned int)((var189 + var204)));
    *(int *)((&local_17c[0] + ((var357 * 4) + 4))) = ((((unsigned int)(var351) == (unsigned int)(var354)) | (var351 < var354)) ? (unsigned long)((unsigned int)(var351)) : (unsigned long)((unsigned int)((var354 + 1))));
    var358 = (var204 + 1);
    var204 = var358;
    var185 = var357;
    if ((var177 != var358)) {
        goto L_15b0;
    }
    var185 = var357;
    goto L_13d0;
}
hamming_distance pass 65 lines
// glaurung: hamming_distance @ 0x1610
int32_t hamming_distance(const uint8_t * arg0, const uint8_t * arg1, int32_t arg2) {
    int distance;
    int i;
    long ret;
    int var15;
    int var22;
    int var30;
    int var38;
    int var46;
    int var54;
    long var55;
    long var8;
    ret = 0xffffffff;
    if (((unsigned long)((unsigned long)((unsigned int)(arg2))) <= (unsigned long)(8))) {
        ret = 0xffffffff;
        if ((arg0 == 0)) {
            return ret;
        }
        ret = 0xffffffff;
        if ((arg1 == 0)) {
            return ret;
        }
        if (((unsigned long)((unsigned int)(arg2)) == 0)) {
            return 0;
        }
        var8 = ((unsigned char)((*(char *)(((long)arg0)) & 255)) != (unsigned char)(*(char *)(((long)arg1))));
        ret = var8;
        if (((unsigned long)((unsigned int)(arg2)) == 1)) {
            return ret;
        }
        var15 = (var8 + ((unsigned char)((*(char *)(((long)arg0 + 0x1)) & 255)) != (unsigned char)(*(char *)(((long)arg1 + 0x1)))));
        ret = (unsigned long)((unsigned int)(var15));
        if (((unsigned long)((unsigned int)(arg2)) == 2)) {
            return ret;
        }
        var22 = ((unsigned int)(var15) + ((unsigned char)((*(char *)(((long)arg0 + 0x2)) & 255)) != (unsigned char)(*(char *)(((long)arg1 + 0x2)))));
        ret = (unsigned long)((unsigned int)(var22));
        if (((unsigned long)((unsigned int)(arg2)) == 3)) {
            return ret;
        }
        var30 = ((unsigned int)(var22) + ((unsigned char)((*(char *)(((long)arg0 + 0x3)) & 255)) != (unsigned char)(*(char *)(((long)arg1 + 0x3)))));
        ret = (unsigned long)((unsigned int)(var30));
        if (((unsigned long)((unsigned int)(arg2)) == 4)) {
            return ret;
        }
        var38 = ((unsigned int)(var30) + ((unsigned char)((*(char *)(((long)arg0 + 0x4)) & 255)) != (unsigned char)(*(char *)(((long)arg1 + 0x4)))));
        ret = (unsigned long)((unsigned int)(var38));
        if (((unsigned long)((unsigned int)(arg2)) == 5)) {
            return ret;
        }
        var46 = ((unsigned int)(var38) + ((unsigned char)((*(char *)(((long)arg0 + 0x5)) & 255)) != (unsigned char)(*(char *)(((long)arg1 + 0x5)))));
        ret = (unsigned long)((unsigned int)(var46));
        if (((unsigned long)((unsigned int)(arg2)) == 6)) {
            return ret;
        }
        var54 = ((unsigned int)(var46) + ((unsigned char)((*(char *)(((long)arg0 + 0x6)) & 255)) != (unsigned char)(*(char *)(((long)arg1 + 0x6)))));
        var55 = (unsigned long)((unsigned int)(var54));
        ret = (unsigned long)((unsigned int)(var54));
        if (((unsigned long)((unsigned int)(arg2)) != 7)) {
            ret = (unsigned long)((unsigned int)((var55 + ((unsigned char)((*(char *)(((long)arg0 + 0x7)) & 255)) != (unsigned char)(*(char *)(((long)arg1 + 0x7)))))));
        }
    }
    return ret;
}

gcc -O0

2/2
edit_distance pass 52 lines
// glaurung: edit_distance @ 0x1119
int32_t edit_distance(const uint8_t * arg0, int32_t arg1, const uint8_t * arg2, int32_t arg3) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    int i;
    int j;
    int cost;
    int best;
    int insertion;
    int substitution;
    unsigned char local_150[324];
    long local_8;
    long ret;
    long var34;
    long var63;
    // x86-64 prologue: save rbp, frame 400 bytes
    local_8 = (long)(0x28);
    if (((((((arg0 == 0) || (arg2 == 0)) || ((long)(arg1) < 0)) || ((long)(arg3) < 0)) || ((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) || (((unsigned long)((unsigned int)(arg3)) != 8) && (8 <= (long)(arg3))))) {
        ret = 0xffffffff;
    } else {
        for (i = 0; ((((unsigned int)(i) == (unsigned int)(arg1)) | (i < arg1)) != 0); i++) {
            *(int *)((&local_150[0] + ((long)((int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) << 3))) + (unsigned long)((unsigned int)(i))))) * 4))) = i;
        }
        for (j = 0; ((((unsigned int)(j) == (unsigned int)(arg3)) | (j < arg3)) != 0); j++) {
            *(int *)((&local_150[0] + ((long)(j) * 4))) = j;
        }
        i = 1;
        while (((((unsigned int)(i) == (unsigned int)(arg1)) | (i < arg1)) != 0)) {
            for (j = 1; ((((unsigned int)(j) == (unsigned int)(arg3)) | (j < arg3)) != 0); j++) {
                cost = ((unsigned char)(((unsigned int)((unsigned char)(arg0[((long)(i) - 1)])) & 255)) != (unsigned char)(((unsigned int)((unsigned char)(arg2[((long)(j) - 1)])) & 255)));
                var34 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) - 1)));
                best = ((unsigned int)(*(int *)((&local_150[0] + ((long)((int)(((unsigned long)((unsigned int)(j)) + (unsigned long)((unsigned int)((var34 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var34)) << 3))))))))) * 4)))) + 1);
                insertion = ((unsigned int)(*(int *)((&local_150[0] + ((long)((int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(j)) - 1))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) << 3))))))))) * 4)))) + 1);
                var63 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) - 1)));
                substitution = ((unsigned int)(cost) + (unsigned int)(*(int *)((&local_150[0] + ((long)((int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(j)) - 1))) + (unsigned long)((unsigned int)((var63 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var63)) << 3))))))))) * 4)))));
                if ((insertion < best)) {
                    best = insertion;
                }
                if ((substitution < best)) {
                    best = substitution;
                }
                *(int *)((&local_150[0] + ((long)((int)(((unsigned long)((unsigned int)(j)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) << 3))))))))) * 4))) = best;
            }
            i = (i + 1);
        }
        ret = (unsigned long)((unsigned int)(*(int *)((&local_150[0] + ((long)((int)(((unsigned long)((unsigned int)(arg3)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) << 3))))))))) * 4)))));
    }
    if ((local_8 != 0x28)) {
        __stack_chk_fail();
    }
    // x86-64 epilogue: restore rbp
    return ret;
}
hamming_distance pass 30 lines
// glaurung: hamming_distance @ 0x13a8
int32_t hamming_distance(const uint8_t * arg0, const uint8_t * arg1, int32_t arg2) {
    int distance;
    int i;
    // x86-64 prologue: save rbp
    distance = 0;
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if ((arg1 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((long)(arg2) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 8) | ((long)(arg2) < 8)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    for (i = 0; (i < arg2); i++) {
        if (((unsigned char)(((unsigned int)((unsigned char)(arg0[i])) & 255)) != (unsigned char)(((unsigned int)((unsigned char)(arg1[i])) & 255)))) {
            distance = (distance + 1);
        }
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(distance);
}

gcc -O2

2/2
edit_distance pass 108 lines
// glaurung: edit_distance @ 0x1120
int32_t edit_distance(const uint8_t * arg0, int32_t arg1, const uint8_t * arg2, int32_t arg3) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    int j;
    int best;
    int i;
    int insertion;
    int substitution;
    unsigned char local_188[324];
    long local_40;
    long ret;
    long var10;
    int var11;
    long var15;
    long var16;
    long var17;
    long var18;
    long var2;
    long var20;
    long var21;
    int var22;
    long var25;
    long var26;
    long var3;
    int var33;
    int var34;
    long var36;
    int var37;
    long var4;
    long var5;
    long var6;
    long var7;
    long var8;
    long var9;
    local_40 = (long)(0x28);
    var2 = 0;
    if ((arg0 == 0)) {
        L_123d: ;
        ret = 0xffffffff;
    } else {
        var3 = (long)arg2;
        if ((arg2 == 0)) {
            goto L_123d;
        } else {
            var4 = (unsigned long)((unsigned int)(arg3));
            if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg3))))) {
                goto L_123d;
            } else {
                var5 = (unsigned long)((unsigned int)(arg1));
                if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
                    goto L_123d;
                } else {
                    var6 = (long)(&local_188[0]);
                    var7 = (long)arg0;
                    var8 = var6;
                    var9 = var6;
                    var10 = var2;
                    do {
                        *(int *)((var8)) = var10;
                        var11 = (var10 + 1);
                        var8 = (var8 + 36);
                        var10 = (unsigned long)((unsigned int)(var11));
                    } while (((long)((int)(var11)) <= (long)((int)(var5))));
                    var15 = 0;
                    do {
                        *(int *)((var6 + var15 * 4)) = var15;
                        var16 = (var15 + 1);
                        var15 = var16;
                    } while (((long)((int)(var16)) <= (long)((int)(var4))));
                    if (((unsigned long)((unsigned int)(var5)) != 0)) {
                        var17 = (long)((&local_188[0] + 36));
                        var18 = (unsigned long)((unsigned int)((var5 + (var5 * 8))));
                        var20 = 0;
                        do {
                            var21 = var6;
                            if (((unsigned long)((unsigned int)(var4)) != 0)) {
                                var22 = (unsigned int)((unsigned char)(*(char *)((var7))));
                                j = 1;
                                do {
                                    var25 = (unsigned long)((unsigned int)(*(int *)((var9 + j * 4))));
                                    var26 = (unsigned long)((unsigned int)(*(int *)((var17 + j * 4 - 0x4))));
                                    var33 = (((unsigned char)(*(char *)((var3 + j - 0x1))) != (unsigned char)((var22 & 255))) + *(int *)((var9 + j * 4 - 0x4)));
                                    var34 = ((((unsigned int)(var25) == (unsigned int)(var26)) | ((long)((int)(var25)) < (long)((int)(var26)))) ? (unsigned long)((unsigned int)((var25 + 1))) : (unsigned long)((unsigned int)((var26 + 1))));
                                    *(int *)((var17 + j * 4)) = (((((unsigned int)(var34) == (unsigned int)(var33)) | (var34 < var33)) == 0) ? (unsigned long)((unsigned int)(var33)) : var34);
                                    var36 = ((unsigned long)((unsigned int)(j)) + 1);
                                    j = var36;
                                    var21 = (unsigned long)((unsigned int)(var33));
                                } while (((long)((int)(var36)) <= (long)((int)(var4))));
                            }
                            var37 = (var20 + 9);
                            var20 = (unsigned long)((unsigned int)(var37));
                            var17 = (var17 + 36);
                            var9 = (var9 + 36);
                            var7 = (var7 + 1);
                            var6 = var21;
                        } while (((unsigned int)(var37) != (unsigned int)(var18)));
                    }
                    ret = (unsigned long)((unsigned int)(*(int *)((&local_188[0] + ((long)((int)(((unsigned long)((unsigned int)((var5 + (var5 * 8)))) + var4))) * 4)))));
                }
            }
        }
    }
    if ((local_40 != 0x28)) {
        __stack_chk_fail();
    }
    // x86-64 epilogue: tear down frame
    return ret;
}
hamming_distance pass 35 lines
// glaurung: hamming_distance @ 0x1250
int32_t hamming_distance(const uint8_t * arg0, const uint8_t * arg1, int32_t arg2) {
    int i;
    int distance;
    long t10;
    long t11;
    long var1;
    long var8;
    if ((arg0 == 0)) {
        var1 = 0xffffffff;
        return 0xffffffff;
    }
    if ((arg1 == 0)) {
        var1 = 0xffffffff;
        return 0xffffffff;
    }
    if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg2))))) {
        var1 = 0xffffffff;
        return 0xffffffff;
    }
    if (((unsigned long)((unsigned int)(arg2)) == 0)) {
        return 0;
    }
    i = 0;
    var8 = 0;
    do {
        t10 = *(char *)(((long)arg0 + i));
        t11 = ((unsigned int)((unsigned char)(*(char *)(((long)arg1 + i)))) & 255);
        i = (i + 1);
        distance = (var8 + ((unsigned char)(t10) != (unsigned char)(t11)));
        var8 = (unsigned long)((unsigned int)(distance));
        var1 = (unsigned long)((unsigned int)(distance));
    } while (((((unsigned int)(arg2) == (unsigned int)(i)) | (arg2 < i)) == 0));
    return (unsigned int)(var1);
}

← 213 fixtures