Fixture 47

huffman

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

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

Huffman code lengths by repeated two-smallest merging over a flat node array, then the Kraft sum of the resulting lengths. The two-minimum scan carries two indices and two values through one loop body.

tests/decompiler_fixtures/src/47_huffman.c source
#include <stdint.h>

/* Huffman code lengths by repeated two-smallest merging over a flat node
 * array, then the Kraft sum of the resulting lengths.  The two-minimum scan
 * carries two indices and two values through one loop body. */

#define HUFF_SYMBOLS 8
#define HUFF_NODES (2 * HUFF_SYMBOLS)

__attribute__((noinline)) int32_t
huffman_code_lengths(const int32_t *frequencies, int32_t symbols,
                     int32_t *lengths) {
    int32_t weight[HUFF_NODES];
    int32_t parent[HUFF_NODES];
    int32_t alive[HUFF_NODES];
    int32_t nodes;
    int32_t index;
    int32_t total = 0;
    if (frequencies == 0 || lengths == 0 || symbols < 1 ||
        symbols > HUFF_SYMBOLS) {
        return -1;
    }
    for (index = 0; index < HUFF_NODES; ++index) {
        weight[index] = 0;
        parent[index] = -1;
        alive[index] = 0;
    }
    for (index = 0; index < symbols; ++index) {
        if (frequencies[index] < 0 || frequencies[index] > 1000) {
            return -2;
        }
        weight[index] = frequencies[index];
        alive[index] = 1;
        lengths[index] = 0;
    }
    nodes = symbols;
    while (nodes < HUFF_NODES) {
        int32_t first = -1;
        int32_t second = -1;
        int32_t scan;
        for (scan = 0; scan < nodes; ++scan) {
            if (!alive[scan]) {
                continue;
            }
            if (first < 0 || weight[scan] < weight[first]) {
                second = first;
                first = scan;
            } else if (second < 0 || weight[scan] < weight[second]) {
                second = scan;
            }
        }
        if (first < 0 || second < 0) {
            break;
        }
        weight[nodes] = weight[first] + weight[second];
        alive[nodes] = 1;
        alive[first] = 0;
        alive[second] = 0;
        parent[first] = nodes;
        parent[second] = nodes;
        nodes += 1;
    }
    for (index = 0; index < symbols; ++index) {
        int32_t depth = 0;
        int32_t walk = index;
        while (parent[walk] >= 0 && depth < HUFF_NODES) {
            walk = parent[walk];
            depth += 1;
        }
        lengths[index] = depth;
        total += depth;
    }
    return total;
}

__attribute__((noinline)) uint32_t
kraft_sum_q16(const int32_t *lengths, int32_t symbols) {
    uint32_t total = 0;
    int32_t index;
    if (lengths == 0 || symbols < 0 || symbols > HUFF_SYMBOLS) {
        return 0;
    }
    for (index = 0; index < symbols; ++index) {
        int32_t length = lengths[index];
        if (length > 0 && length < 16) {
            total += (uint32_t)65536 >> (uint32_t)length;
        }
    }
    return total;
}

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
huffman_code_lengths pass 142 lines
// glaurung: huffman_code_lengths @ 0x1100
__attribute__((no_stack_protector)) int32_t huffman_code_lengths(const int32_t * arg0, int32_t arg1, int32_t * arg2) {
    int total;
    int index;
    int nodes;
    int first;
    int second;
    int scan;
    int depth;
    int walk;
    signed char local_101;
    int local_4;
    unsigned char local_60[64];
    unsigned char local_a0[64];
    unsigned char local_e0[64];
    long t197;
    long t204;
    total = 0;
    if ((arg0 != 0)) {
        if ((arg2 != 0)) {
            if ((1 <= (long)(arg1))) {
                if ((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8))) {
                    goto L_1156;
                }
            }
        }
    }
    local_4 = -1;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
    L_1156: ;
    index = 0;
    L_1160: ;
    if (((long)(index) < 16)) {
        *(int *)((&local_60[0] + ((long)(index) * 4))) = 0;
        *(int *)((&local_a0[0] + ((long)(index) * 4))) = -1;
        *(int *)((&local_e0[0] + ((long)(index) * 4))) = 0;
        index = ((unsigned int)(index) + 1);
        goto L_1160;
    }
    index = 0;
    L_11be: ;
    if ((arg1 <= index)) {
        goto L_1257;
    }
    if ((0 <= (long)((int)(arg0[(long)(index)])))) {
        t197 = arg0[(long)(index)];
        if ((((unsigned long)((unsigned int)(t197)) == 1000) | ((long)((int)(t197)) < 1000))) {
            goto L_1206;
        }
    }
    local_4 = -2;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
    L_1206: ;
    *(int *)((&local_60[0] + ((long)(index) * 4))) = arg0[(long)(index)];
    *(int *)((&local_e0[0] + ((long)(index) * 4))) = 1;
    arg2[(long)(index)] = 0;
    index = ((unsigned int)(index) + 1);
    goto L_11be;
    L_1257: ;
    nodes = arg1;
    L_1260: ;
    if ((16 <= (long)(nodes))) {
        goto L_1402;
    }
    first = -1;
    second = -1;
    scan = 0;
    L_128b: ;
    if ((nodes <= scan)) {
        goto L_1350;
    }
    if (((unsigned long)((unsigned int)(*(int *)((&local_e0[0] + ((long)(scan) * 4))))) == 0)) {
        goto L_133c;
    }
    if ((0 <= (long)(first))) {
        if (((long)((int)(*(int *)((&local_60[0] + ((long)(first) * 4))))) <= (long)((int)(*(int *)((&local_60[0] + ((long)(scan) * 4))))))) {
            goto L_12fd;
        }
    }
    second = first;
    first = scan;
    goto L_1337;
    L_12fd: ;
    if ((0 <= (long)(second))) {
        if (((long)((int)(*(int *)((&local_60[0] + ((long)(second) * 4))))) <= (long)((int)(*(int *)((&local_60[0] + ((long)(scan) * 4))))))) {
            goto L_1332;
        }
    }
    second = scan;
    L_1332: ;
    goto L_1337;
    L_1337: ;
    goto L_133c;
    L_133c: ;
    scan = ((unsigned int)(scan) + 1);
    goto L_128b;
    L_1350: ;
    if ((0 <= (long)(first))) {
        if ((0 <= (long)(second))) {
            goto L_136f;
        }
    }
    goto L_1402;
    L_136f: ;
    *(int *)((&local_60[0] + ((long)(nodes) * 4))) = ((unsigned long)((unsigned int)(*(int *)((&local_60[0] + ((long)(first) * 4))))) + *(int *)((&local_60[0] + ((long)(second) * 4))));
    *(int *)((&local_e0[0] + ((long)(nodes) * 4))) = 1;
    *(int *)((&local_e0[0] + ((long)(first) * 4))) = 0;
    *(int *)((&local_e0[0] + ((long)(second) * 4))) = 0;
    *(int *)((&local_a0[0] + ((long)(first) * 4))) = nodes;
    *(int *)((&local_a0[0] + ((long)(second) * 4))) = nodes;
    nodes = ((unsigned int)(nodes) + 1);
    goto L_1260;
    L_1402: ;
    index = 0;
    L_140c: ;
    if ((arg1 <= index)) {
        goto L_14d3;
    }
    depth = 0;
    walk = index;
    L_1431: ;
    t204 = *(int *)((&local_a0[0] + ((long)(walk) * 4)));
    local_101 = 0;
    if ((0 <= (long)((int)(t204)))) {
        local_101 = ((long)(depth) < 16);
    }
    if (((unsigned long)((unsigned char)((local_101 & 1))) != 0)) {
        walk = *(int *)((&local_a0[0] + ((long)(walk) * 4)));
        depth = ((unsigned int)(depth) + 1);
        goto L_1431;
    }
    arg2[(long)(index)] = depth;
    total = ((unsigned int)(depth) + total);
    index = ((unsigned int)(index) + 1);
    goto L_140c;
    L_14d3: ;
    local_4 = total;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
kraft_sum_q16 pass 32 lines
// glaurung: kraft_sum_q16 @ 0x14f0
uint32_t kraft_sum_q16(const int32_t * arg0, int32_t arg1) {
    unsigned int total;
    int index;
    int length;
    int local_4;
    // x86-64 prologue: save rbp
    total = 0;
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((long)(arg1) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    for (index = 0; (index < arg1); index++) {
        length = arg0[(long)(index)];
        if (((((unsigned long)((unsigned int)(length)) == 0) | ((long)(length) < 0)) == 0)) {
            if (((long)(length) < 16)) {
                total = ((unsigned int)(((unsigned long)(0x10000) >> ((unsigned long)((unsigned int)(length)) & 31))) + total);
            }
        }
    }
    local_4 = total;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}

clang -O2

2/2
huffman_code_lengths pass 337 lines
// glaurung: huffman_code_lengths @ 0x1100
__attribute__((no_stack_protector)) int32_t huffman_code_lengths(const int32_t * arg0, int32_t arg1, int32_t * arg2) {
    int second;
    int nodes;
    int first;
    int scan;
    int index;
    int depth;
    int total;
    int walk;
    unsigned char local_48[72];
    unsigned char local_88[64];
    unsigned char local_c8[64];
    long ret;
    long t369;
    long t373;
    long var10;
    long var11;
    long var13;
    long var19;
    long var24;
    long var25;
    long var29;
    long var42;
    long var44;
    long var45;
    long var46;
    long var47;
    long var48;
    long var49;
    long var50;
    long var53;
    long var58;
    long var61;
    long var62;
    long var63;
    int var64;
    long var65;
    long var72;
    long var73;
    long var79;
    long var81;
    int var85;
    long var86;
    long var88;
    long var91;
    // x86-64 prologue: save callee registers, frame 8 bytes
    ret = 0xffffffff;
    if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 9)))) < (unsigned long)(0xfffffff8))) {
        // 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;
    }
    *(int *)((&local_c8[0] + 48)) = 0;
    *(int *)((&local_c8[0] + 52)) = 0;
    *(int *)((&local_c8[0] + 56)) = 0;
    *(int *)((&local_c8[0] + 60)) = 0;
    *(int *)((&local_c8[0] + 32)) = 0;
    *(int *)((&local_c8[0] + 36)) = 0;
    *(int *)((&local_c8[0] + 40)) = 0;
    *(int *)((&local_c8[0] + 44)) = 0;
    *(int *)((&local_c8[0] + 16)) = 0;
    *(int *)((&local_c8[0] + 20)) = 0;
    *(int *)((&local_c8[0] + 24)) = 0;
    *(int *)((&local_c8[0] + 28)) = 0;
    *(int *)(&local_c8[0]) = 0;
    *(int *)((&local_c8[0] + 4)) = 0;
    *(int *)((&local_c8[0] + 8)) = 0;
    *(int *)((&local_c8[0] + 12)) = 0;
    *(int *)(&local_48[0]) = -1;
    *(int *)((&local_48[0] + 4)) = -1;
    *(int *)((&local_48[0] + 8)) = -1;
    *(int *)((&local_48[0] + 12)) = -1;
    *(int *)((&local_48[0] + 16)) = -1;
    *(int *)((&local_48[0] + 20)) = -1;
    *(int *)((&local_48[0] + 24)) = -1;
    *(int *)((&local_48[0] + 28)) = -1;
    *(int *)((&local_48[0] + 32)) = -1;
    *(int *)((&local_48[0] + 36)) = -1;
    *(int *)((&local_48[0] + 40)) = -1;
    *(int *)((&local_48[0] + 44)) = -1;
    *(int *)((&local_48[0] + 48)) = -1;
    *(int *)((&local_48[0] + 52)) = -1;
    *(int *)((&local_48[0] + 56)) = -1;
    *(int *)((&local_48[0] + 60)) = -1;
    *(int *)(&local_88[0]) = 0;
    *(int *)((&local_88[0] + 4)) = 0;
    *(int *)((&local_88[0] + 8)) = 0;
    *(int *)((&local_88[0] + 12)) = 0;
    *(int *)((&local_88[0] + 16)) = 0;
    *(int *)((&local_88[0] + 20)) = 0;
    *(int *)((&local_88[0] + 24)) = 0;
    *(int *)((&local_88[0] + 28)) = 0;
    *(int *)((&local_88[0] + 32)) = 0;
    *(int *)((&local_88[0] + 36)) = 0;
    *(int *)((&local_88[0] + 40)) = 0;
    *(int *)((&local_88[0] + 44)) = 0;
    *(int *)((&local_88[0] + 48)) = 0;
    *(int *)((&local_88[0] + 52)) = 0;
    *(int *)((&local_88[0] + 56)) = 0;
    *(int *)((&local_88[0] + 60)) = 0;
    var10 = (unsigned long)((unsigned int)(*(int *)(((long)arg0))));
    ret = 0xfffffffe;
    if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var10))))) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    *(int *)(&local_c8[0]) = var10;
    *(int *)(&local_88[0]) = 1;
    *(int *)(((long)arg2)) = 0;
    if (((unsigned long)((unsigned int)(arg1)) != 1)) {
        goto L_1277;
    }
    L_119c: ;
    var11 = (unsigned long)((unsigned int)(arg1));
    if (((((unsigned long)((unsigned int)(arg1)) == 15) | ((long)(arg1) < 15)) == 0)) {
        goto L_125a;
    }
    second = var13;
    nodes = (long)(arg1);
    L_11b0: ;
    if ((nodes <= 0)) {
        goto L_125a;
    }
    var19 = (unsigned long)((unsigned int)(nodes));
    second = 0xffffffff;
    var24 = 0;
    var25 = 0xffffffff;
    goto L_11db;
    L_11d0: ;
    var25 = (unsigned long)((unsigned int)(first));
    L_11d2: ;
    scan = (var24 + 1);
    var24 = (unsigned long)((unsigned int)(scan));
    if ((var19 == scan)) {
        goto L_1210;
    }
    L_11db: ;
    first = (unsigned long)((unsigned int)(var25));
    if (((unsigned long)((unsigned int)(*(int *)((&local_88[0] + (var24 * 4))))) == 0)) {
        goto L_11d0;
    }
    if ((0 <= (long)(first))) {
        var29 = (unsigned long)((unsigned int)(*(int *)((&local_c8[0] + (var24 * 4)))));
        if (((long)((int)(*(int *)((&local_c8[0] + ((unsigned long)((unsigned int)(first)) * 4))))) <= (long)((int)(var29)))) {
            goto L_11fb;
        }
    }
    second = (unsigned long)((unsigned int)(first));
    var25 = (unsigned long)((unsigned int)(var24));
    goto L_11d2;
    L_11fb: ;
    if ((0 <= (long)(second))) {
        if (((long)((int)(*(int *)((&local_c8[0] + ((unsigned long)((unsigned int)(second)) * 4))))) <= (long)((int)(var29)))) {
            goto L_11d0;
        }
    }
    second = (unsigned long)((unsigned int)(var24));
    var25 = (unsigned long)((unsigned int)(first));
    goto L_11d2;
    L_1210: ;
    if (((long)((int)(var25)) < 0)) {
        goto L_125a;
    }
    if (((long)(second) < 0)) {
        goto L_125a;
    }
    *(int *)((&local_c8[0] + (nodes * 4))) = ((unsigned long)((unsigned int)(*(int *)((&local_c8[0] + ((unsigned long)((unsigned int)(second)) * 4))))) + *(int *)((&local_c8[0] + ((unsigned long)((unsigned int)(var25)) * 4))));
    *(int *)((&local_88[0] + (nodes * 4))) = 1;
    *(int *)((&local_88[0] + ((unsigned long)((unsigned int)(var25)) * 4))) = 0;
    *(int *)((&local_88[0] + ((unsigned long)((unsigned int)(second)) * 4))) = 0;
    *(int *)((&local_48[0] + ((unsigned long)((unsigned int)(var25)) * 4))) = nodes;
    *(int *)((&local_48[0] + ((unsigned long)((unsigned int)(second)) * 4))) = nodes;
    nodes = (nodes + 1);
    if (((unsigned long)((unsigned int)(nodes)) != 16)) {
        goto L_11b0;
    }
    L_125a: ;
    if (((unsigned long)((unsigned int)(arg1)) != 1)) {
        goto L_13a0;
    }
    var42 = 0;
    index = 0;
    if (((unsigned long)((unsigned char)((var11 & 1))) != 0)) {
        goto L_1433;
    }
    // x86-64 epilogue: restore callee registers
    return var42;
    L_1277: ;
    var44 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x4))));
    if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var44))))) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    *(int *)((&local_c8[0] + 4)) = var44;
    *(int *)((&local_88[0] + 4)) = 1;
    *(int *)(((long)arg2 + 0x4)) = 0;
    if (((unsigned long)((unsigned int)(arg1)) == 2)) {
        goto L_119c;
    }
    var45 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x8))));
    if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var45))))) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    *(int *)((&local_c8[0] + 8)) = var45;
    *(int *)((&local_88[0] + 8)) = 1;
    *(int *)(((long)arg2 + 0x8)) = 0;
    if (((unsigned long)((unsigned int)(arg1)) == 3)) {
        goto L_119c;
    }
    var46 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0xc))));
    if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var46))))) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    *(int *)((&local_c8[0] + 12)) = var46;
    *(int *)((&local_88[0] + 12)) = 1;
    *(int *)(((long)arg2 + 0xc)) = 0;
    if (((unsigned long)((unsigned int)(arg1)) == 4)) {
        goto L_119c;
    }
    var47 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x10))));
    if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var47))))) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    *(int *)((&local_c8[0] + 16)) = var47;
    *(int *)((&local_88[0] + 16)) = 1;
    *(int *)(((long)arg2 + 0x10)) = 0;
    if (((unsigned long)((unsigned int)(arg1)) == 5)) {
        goto L_119c;
    }
    var48 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x14))));
    if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var48))))) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    *(int *)((&local_c8[0] + 20)) = var48;
    *(int *)((&local_88[0] + 20)) = 1;
    *(int *)(((long)arg2 + 0x14)) = 0;
    if (((unsigned long)((unsigned int)(arg1)) == 6)) {
        goto L_119c;
    }
    var49 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x18))));
    if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var49))))) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    *(int *)((&local_c8[0] + 24)) = var49;
    *(int *)((&local_88[0] + 24)) = 1;
    *(int *)(((long)arg2 + 0x18)) = 0;
    if (((unsigned long)((unsigned int)(arg1)) == 7)) {
        goto L_119c;
    }
    var50 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x1c))));
    if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var50))))) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    *(int *)((&local_c8[0] + 28)) = var50;
    *(int *)((&local_88[0] + 28)) = 1;
    *(int *)(((long)arg2 + 0x1c)) = 0;
    goto L_119c;
    L_13a0: ;
    var53 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var11)) & -2)));
    index = 0;
    var58 = 0;
    goto L_13c9;
    L_13b0: ;
    *(int *)(((long)arg2 + var61 * 4)) = (depth - 1);
    var64 = (var62 + var63);
    var65 = (unsigned long)((unsigned int)(var64));
    index = (index + 2);
    var58 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((depth + (unsigned long)((unsigned int)(var64))))) - 2)));
    if ((index == var53)) {
        goto L_1426;
    }
    L_13c9: ;
    var62 = (unsigned long)((unsigned int)(var58));
    var72 = 0;
    var73 = (unsigned long)((unsigned int)(index));
    L_13e0: ;
    var73 = (unsigned long)((unsigned int)(*(int *)((&local_48[0] + ((long)((int)(var73)) * 4)))));
    var63 = (unsigned long)((unsigned int)((var72 + 1)));
    if ((0 <= (long)((int)(var73)))) {
        t369 = (unsigned long)((unsigned int)(var72));
        var72 = (unsigned long)((unsigned int)(var63));
        if (((unsigned long)(t369) < (unsigned long)(16))) {
            goto L_13e0;
        }
    }
    *(int *)(((long)arg2 + index * 4)) = (var63 - 1);
    var61 = ((unsigned long)((unsigned int)(index)) | 1);
    var79 = 0;
    var81 = (unsigned long)((unsigned int)(var61));
    do {
        var81 = (unsigned long)((unsigned int)(*(int *)((&local_48[0] + ((long)((int)(var81)) * 4)))));
        depth = (unsigned long)((unsigned int)((var79 + 1)));
        if (((long)((int)(var81)) < 0)) {
            goto L_13b0;
        }
        t373 = (unsigned long)((unsigned int)(var79));
        var79 = (unsigned long)((unsigned int)(depth));
    } while (((unsigned long)(t373) < (unsigned long)(16)));
    goto L_13b0;
    L_1426: ;
    var85 = ((unsigned int)((depth + var65)) - 2);
    var42 = (unsigned long)((unsigned int)(var85));
    ret = (unsigned long)((unsigned int)(var85));
    if (((unsigned long)((unsigned char)((var11 & 1))) == 0)) {
        // x86-64 epilogue: restore callee registers
        return ret;
    }
    L_1433: ;
    var86 = 0xffffffff;
    var88 = (unsigned long)((unsigned int)(index));
    L_1440: ;
    var86 = (unsigned long)((unsigned int)((var86 + 1)));
    var91 = (unsigned long)((unsigned int)(*(int *)((&local_48[0] + ((long)((int)(var88)) * 4)))));
    if ((0 <= (long)((int)(var91)))) {
        var88 = var91;
        if (((unsigned long)((unsigned long)((unsigned int)(var86))) < (unsigned long)(16))) {
            goto L_1440;
        }
    }
    *(int *)(((long)arg2 + index * 4)) = var86;
    // x86-64 epilogue: restore callee registers
    return (unsigned int)((var42 + var86));
}
kraft_sum_q16 pass 79 lines
// glaurung: kraft_sum_q16 @ 0x1460
uint32_t kraft_sum_q16(const int32_t * arg0, int32_t arg1) {
    int index;
    int length;
    unsigned int total;
    long ret;
    long var12;
    long var13;
    int var19;
    long var21;
    long var3;
    int var32;
    long var34;
    int var40;
    long var42;
    int var53;
    long var55;
    int var61;
    long var63;
    int var70;
    long var72;
    int var74;
    long var75;
    long var76;
    ret = 0;
    if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 1)))) <= (unsigned long)(7))) {
        ret = 0;
        if ((arg0 == 0)) {
            return ret;
        }
        var3 = (unsigned long)((unsigned int)(*(int *)(((long)arg0))));
        var12 = (((unsigned long)(15) <= (unsigned long)((unsigned long)((unsigned int)((var3 - 1))))) ? 0 : (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var3 & 31)))));
        ret = var12;
        if (((unsigned long)((unsigned int)(arg1)) == 1)) {
            return ret;
        }
        var13 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x4))));
        var19 = (var12 + (((unsigned long)((unsigned long)((unsigned int)((var13 - 1)))) < (unsigned long)(15)) ? (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var13 & 31)))) : 0));
        ret = (unsigned long)((unsigned int)(var19));
        if (((unsigned long)((unsigned int)(arg1)) == 2)) {
            return ret;
        }
        var21 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x8))));
        var32 = ((unsigned int)(var19) + (((unsigned long)(15) <= (unsigned long)((unsigned long)((unsigned int)((var21 - 1))))) ? 0 : (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var21 & 31))))));
        ret = (unsigned long)((unsigned int)(var32));
        if (((unsigned long)((unsigned int)(arg1)) == 3)) {
            return ret;
        }
        var34 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0xc))));
        var40 = ((unsigned int)(var32) + (((unsigned long)((unsigned long)((unsigned int)((var34 - 1)))) < (unsigned long)(15)) ? (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var34 & 31)))) : 0));
        ret = (unsigned long)((unsigned int)(var40));
        if (((unsigned long)((unsigned int)(arg1)) == 4)) {
            return ret;
        }
        var42 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x10))));
        var53 = ((unsigned int)(var40) + (((unsigned long)(15) <= (unsigned long)((unsigned long)((unsigned int)((var42 - 1))))) ? 0 : (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var42 & 31))))));
        ret = (unsigned long)((unsigned int)(var53));
        if (((unsigned long)((unsigned int)(arg1)) == 5)) {
            return ret;
        }
        var55 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x14))));
        var61 = ((unsigned int)(var53) + (((unsigned long)((unsigned long)((unsigned int)((var55 - 1)))) < (unsigned long)(15)) ? (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var55 & 31)))) : 0));
        ret = (unsigned long)((unsigned int)(var61));
        if (((unsigned long)((unsigned int)(arg1)) == 6)) {
            return ret;
        }
        var63 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x18))));
        var70 = 0x10000;
        var72 = 0;
        var74 = ((unsigned int)(var61) + (((unsigned long)(15) <= (unsigned long)((unsigned long)((unsigned int)((var63 - 1))))) ? 0 : (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var63 & 31))))));
        var75 = (unsigned long)((unsigned int)(var74));
        ret = (unsigned long)((unsigned int)(var74));
        if (((unsigned long)((unsigned int)(arg1)) != 7)) {
            var76 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x1c))));
            ret = (unsigned long)((unsigned int)((var75 + (((unsigned long)((unsigned long)((unsigned int)((var76 - 1)))) < (unsigned long)(15)) ? (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var70)) >> (var76 & 31)))) : var72))));
        }
    }
    return ret;
}

gcc -O0

2/2
huffman_code_lengths pass 146 lines
// glaurung: huffman_code_lengths @ 0x1119
int32_t huffman_code_lengths(const int32_t * arg0, int32_t arg1, int32_t * arg2) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    int total;
    int index;
    int nodes;
    int first;
    int second;
    int scan;
    int depth;
    int walk;
    unsigned char local_50[64];
    long local_8;
    unsigned char local_90[64];
    unsigned char local_d0[64];
    long ret;
    long var20;
    local_8 = (long)(0x28);
    total = 0;
    if ((arg0 != 0)) {
        if ((arg2 != 0)) {
            if (((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0)) == 0)) {
                if ((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8))) {
                    goto L_1185;
                }
            }
        }
    }
    ret = 0xffffffff;
    goto L_14e6;
    L_1185: ;
    index = 0;
    goto L_11ce;
    L_1191: ;
    *(int *)((&local_d0[0] + ((long)(index) * 4))) = 0;
    *(int *)((&local_90[0] + ((long)(index) * 4))) = -1;
    *(int *)((&local_50[0] + ((long)(index) * 4))) = 0;
    index = (index + 1);
    L_11ce: ;
    if ((((unsigned long)((unsigned int)(index)) == 15) | ((long)(index) < 15))) {
        goto L_1191;
    }
    index = 0;
    goto L_1295;
    L_11e6: ;
    if ((0 <= (long)((int)(arg0[(long)(index)])))) {
        var20 = (unsigned long)((unsigned int)(arg0[(long)(index)]));
        if ((((unsigned long)((unsigned int)(var20)) == 1000) | ((long)((int)(var20)) < 1000))) {
            goto L_1233;
        }
    }
    ret = 0xfffffffe;
    goto L_14e6;
    L_1233: ;
    *(int *)((&local_d0[0] + ((long)(index) * 4))) = arg0[(long)(index)];
    *(int *)((&local_50[0] + ((long)(index) * 4))) = 1;
    arg2[(long)(index)] = 0;
    index = (index + 1);
    L_1295: ;
    if ((index < arg1)) {
        goto L_11e6;
    }
    nodes = arg1;
    goto L_142d;
    L_12b8: ;
    first = -1;
    second = -1;
    scan = 0;
    goto L_1371;
    L_12db: ;
    if (((unsigned long)((unsigned int)(*(int *)((&local_50[0] + ((long)(scan) * 4))))) == 0)) {
        goto L_1369;
    }
    if ((0 <= (long)(first))) {
        if (((long)((int)(*(int *)((&local_d0[0] + ((long)(first) * 4))))) <= (long)((int)(*(int *)((&local_d0[0] + ((long)(scan) * 4))))))) {
            goto L_1330;
        }
    }
    second = first;
    first = scan;
    goto L_136a;
    L_1330: ;
    if ((0 <= (long)(second))) {
        if (((long)((int)(*(int *)((&local_d0[0] + ((long)(second) * 4))))) <= (long)((int)(*(int *)((&local_d0[0] + ((long)(scan) * 4))))))) {
            goto L_136a;
        }
    }
    second = scan;
    goto L_136a;
    L_1369: ;
    L_136a: ;
    scan = (scan + 1);
    L_1371: ;
    if ((scan < nodes)) {
        goto L_12db;
    }
    if (((long)(first) < 0)) {
        goto L_143a;
    }
    if (((long)(second) < 0)) {
        goto L_143a;
    }
    *(int *)((&local_d0[0] + ((long)(nodes) * 4))) = ((unsigned long)((unsigned int)(*(int *)((&local_d0[0] + ((long)(first) * 4))))) + (unsigned long)((unsigned int)(*(int *)((&local_d0[0] + ((long)(second) * 4))))));
    *(int *)((&local_50[0] + ((long)(nodes) * 4))) = 1;
    *(int *)((&local_50[0] + ((long)(first) * 4))) = 0;
    *(int *)((&local_50[0] + ((long)(second) * 4))) = 0;
    *(int *)((&local_90[0] + ((long)(first) * 4))) = nodes;
    *(int *)((&local_90[0] + ((long)(second) * 4))) = nodes;
    nodes = (nodes + 1);
    L_142d: ;
    if ((((unsigned long)((unsigned int)(nodes)) == 15) | ((long)(nodes) < 15))) {
        goto L_12b8;
    }
    L_143a: ;
    index = 0;
    goto L_14ce;
    L_1449: ;
    depth = 0;
    walk = index;
    goto L_147d;
    L_1461: ;
    walk = *(int *)((&local_90[0] + ((long)(walk) * 4)));
    depth = (depth + 1);
    L_147d: ;
    if ((0 <= (long)((int)(*(int *)((&local_90[0] + ((long)(walk) * 4))))))) {
        if ((((unsigned long)((unsigned int)(depth)) == 15) | ((long)(depth) < 15))) {
            goto L_1461;
        }
    }
    arg2[(long)(index)] = depth;
    total = (total + (unsigned int)(depth));
    index = (index + 1);
    L_14ce: ;
    if ((index < arg1)) {
        goto L_1449;
    }
    ret = (unsigned long)((unsigned int)(total));
    L_14e6: ;
    if ((local_8 == 0x28)) {
        // x86-64 epilogue: restore rbp
        return ret;
    }
    __stack_chk_fail();
    // x86-64 epilogue: restore rbp
    return ret;
}
kraft_sum_q16 pass 30 lines
// glaurung: kraft_sum_q16 @ 0x14fc
uint32_t kraft_sum_q16(const int32_t * arg0, int32_t arg1) {
    unsigned int total;
    int index;
    int length;
    // x86-64 prologue: save rbp
    total = 0;
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((long)(arg1) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    for (index = 0; (index < arg1); index++) {
        length = arg0[(long)(index)];
        if (((((unsigned long)((unsigned int)(length)) == 0) | ((long)(length) < 0)) == 0)) {
            if (((((unsigned long)((unsigned int)(length)) == 15) | ((long)(length) < 15)) != 0)) {
                total = (total + (unsigned int)(((unsigned long)(0x10000) >> ((unsigned long)((unsigned int)(length)) & 31))));
            }
        }
    }
    // x86-64 epilogue: restore rbp
    return total;
}

gcc -O2

2/2
huffman_code_lengths pass 221 lines
// glaurung: huffman_code_lengths @ 0x1120
int32_t huffman_code_lengths(const int32_t * arg0, int32_t arg1, int32_t * arg2) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    int index;
    int nodes;
    int second;
    int first;
    int depth;
    int scan;
    int total;
    int walk;
    long rbp;
    unsigned char stack_0[64];
    unsigned char stack_1[64];
    unsigned char stack_2[120];
    long var16;
    long var18;
    long var21;
    long var23;
    long var25;
    long var3;
    long var32;
    long var35;
    long var36;
    long var37;
    int var44;
    long var46;
    long var48;
    long var5;
    long var50;
    long var52;
    long var57;
    long var58;
    // x86-64 prologue: save callee registers, frame 32 bytes
    *(long *)((&stack_2[0] + 72)) = (long)((long)(0x28));
    if ((arg0 == 0)) {
        goto L_1350;
    }
    var3 = (long)arg2;
    if ((arg2 == 0)) {
        goto L_1350;
    }
    var5 = (unsigned long)((unsigned int)(arg1));
    if (((unsigned long)(7) < (unsigned long)((unsigned long)((unsigned int)((arg1 - 1)))))) {
        goto L_1350;
    }
    index = 0;
    *(int *)(&stack_0[0]) = 0;
    *(int *)((&stack_0[0] + 4)) = 0;
    *(int *)((&stack_0[0] + 8)) = 0;
    *(int *)((&stack_0[0] + 12)) = 0;
    *(int *)((&stack_0[0] + 16)) = 0;
    *(int *)((&stack_0[0] + 20)) = 0;
    *(int *)((&stack_0[0] + 24)) = 0;
    *(int *)((&stack_0[0] + 28)) = 0;
    *(int *)((&stack_0[0] + 32)) = 0;
    *(int *)((&stack_0[0] + 36)) = 0;
    *(int *)((&stack_0[0] + 40)) = 0;
    *(int *)((&stack_0[0] + 44)) = 0;
    *(int *)((&stack_0[0] + 48)) = 0;
    *(int *)((&stack_0[0] + 52)) = 0;
    *(int *)((&stack_0[0] + 56)) = 0;
    *(int *)((&stack_0[0] + 60)) = 0;
    *(int *)(&stack_1[0]) = -1;
    *(int *)((&stack_1[0] + 4)) = -1;
    *(int *)((&stack_1[0] + 8)) = -1;
    *(int *)((&stack_1[0] + 12)) = -1;
    *(int *)((&stack_1[0] + 16)) = -1;
    *(int *)((&stack_1[0] + 20)) = -1;
    *(int *)((&stack_1[0] + 24)) = -1;
    *(int *)((&stack_1[0] + 28)) = -1;
    *(int *)((&stack_1[0] + 32)) = -1;
    *(int *)((&stack_1[0] + 36)) = -1;
    *(int *)((&stack_1[0] + 40)) = -1;
    *(int *)((&stack_1[0] + 44)) = -1;
    *(int *)((&stack_1[0] + 48)) = -1;
    *(int *)((&stack_1[0] + 52)) = -1;
    *(int *)((&stack_1[0] + 56)) = -1;
    *(int *)((&stack_1[0] + 60)) = -1;
    *(int *)(&stack_2[0]) = 0;
    *(int *)((&stack_2[0] + 4)) = 0;
    *(int *)((&stack_2[0] + 8)) = 0;
    *(int *)((&stack_2[0] + 12)) = 0;
    *(int *)((&stack_2[0] + 16)) = 0;
    *(int *)((&stack_2[0] + 20)) = 0;
    *(int *)((&stack_2[0] + 24)) = 0;
    *(int *)((&stack_2[0] + 28)) = 0;
    *(int *)((&stack_2[0] + 32)) = 0;
    *(int *)((&stack_2[0] + 36)) = 0;
    *(int *)((&stack_2[0] + 40)) = 0;
    *(int *)((&stack_2[0] + 44)) = 0;
    *(int *)((&stack_2[0] + 48)) = 0;
    *(int *)((&stack_2[0] + 52)) = 0;
    *(int *)((&stack_2[0] + 56)) = 0;
    *(int *)((&stack_2[0] + 60)) = 0;
    do {
        var16 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + index * 4))));
        if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var16))))) {
            goto L_1348;
        }
        rbp = (long)(&stack_0[0]);
        *(int *)((var3 + index * 4)) = 0;
        *(int *)((rbp + index * 4)) = var16;
        *(int *)((&stack_2[0] + (index * 4))) = 1;
        var18 = ((unsigned long)((unsigned int)(index)) + 1);
        index = var18;
    } while (((((unsigned int)(var5) == (unsigned int)(var18)) | ((long)((int)(var5)) < (long)((int)(var18)))) == 0));
    nodes = (long)((int)(var5));
    L_1200: ;
    var23 = (unsigned long)((unsigned int)(nodes));
    var25 = 0;
    var21 = 0;
    second = -1;
    first = -1;
    goto L_124d;
    L_1220: ;
    var32 = (unsigned long)((unsigned int)(*(int *)((rbp + var25))));
    if (((long)((int)(var32)) < (long)((int)(*(int *)((&stack_0[0] + ((long)(first) * 4))))))) {
        goto L_1270;
    }
    if (((unsigned long)((unsigned int)(second)) == 0xffffffff)) {
        goto L_1330;
    }
    second = (((long)((int)(var32)) < (long)((int)(*(int *)((&stack_0[0] + ((long)(second) * 4)))))) ? var21 : (unsigned long)((unsigned int)(second)));
    L_1242: ;
    var36 = (unsigned long)((unsigned int)(second));
    var37 = (unsigned long)((unsigned int)(first));
    if (((long)(nodes) <= (long)((int)(var35)))) {
        goto L_127a;
    }
    L_1246: ;
    var25 = (var25 + 4);
    var21 = (long)((int)(var35));
    L_124d: ;
    var32 = (unsigned long)((unsigned int)(*(int *)((&stack_2[0] + var25))));
    var35 = (unsigned long)((unsigned int)((var21 + 1)));
    if (((unsigned long)((unsigned int)(var32)) == 0)) {
        goto L_1242;
    }
    if (((unsigned long)((unsigned int)(first)) != 0xffffffff)) {
        goto L_1220;
    }
    if (((long)(nodes) <= (long)((int)(var35)))) {
        goto L_12bf;
    }
    second = -1;
    first = (long)((int)(var21));
    goto L_1246;
    L_1270: ;
    var36 = (long)(first);
    var37 = (long)((int)(var21));
    second = (long)(first);
    first = (long)((int)(var21));
    if (((long)((int)(var35)) < (long)(nodes))) {
        goto L_1246;
    }
    L_127a: ;
    if (((long)((int)(((unsigned long)((unsigned int)(var37)) | var36))) < 0)) {
        goto L_12bf;
    }
    var44 = ((unsigned int)(*(int *)((&stack_0[0] + (var36 * 4)))) + *(int *)((&stack_0[0] + (var37 * 4))));
    var18 = (unsigned long)((unsigned int)(var44));
    *(int *)((&stack_1[0] + (var37 * 4))) = var23;
    *(int *)((&stack_2[0] + (nodes * 4))) = 1;
    *(int *)((rbp + nodes * 4)) = var44;
    nodes = (nodes + 1);
    *(int *)((&stack_2[0] + (var37 * 4))) = 0;
    *(int *)((&stack_1[0] + (var36 * 4))) = var23;
    *(int *)((&stack_2[0] + (var36 * 4))) = 0;
    if (((unsigned long)((unsigned int)(nodes)) != 16)) {
        goto L_1200;
    }
    L_12bf: ;
    var46 = 0;
    var48 = 0;
    L_12d0: ;
    var50 = (long)((int)(*(int *)((&stack_1[0] + (var46 * 4)))));
    var52 = 0;
    depth = 0;
    if (((long)((int)(var50)) < 0)) {
        goto L_12f5;
    }
    depth = var52;
    do {
        var50 = (long)((int)(*(int *)((&stack_1[0] + (var50 * 4)))));
        depth = (unsigned long)((unsigned int)((depth + 1)));
        if (((long)((int)(var50)) < 0)) {
            goto L_1340;
        }
    } while (((unsigned long)((unsigned int)(depth)) != 16));
    var48 = (unsigned long)((unsigned int)((var48 + 16)));
    L_12f5: ;
    *(int *)((var3 + var46 * 4)) = depth;
    var57 = (var46 + 1);
    var46 = var57;
    var35 = (unsigned long)((unsigned int)(depth));
    var58 = var48;
    if (((((unsigned int)(var5) == (unsigned int)(var57)) | ((long)((int)(var5)) < (long)((int)(var57)))) == 0)) {
        goto L_12d0;
    }
    L_1302: ;
    if ((*(long *)((&stack_2[0] + 72)) != 0x28)) {
        goto L_1358;
    }
    // x86-64 epilogue: restore callee registers
    return (unsigned int)(var58);
    L_1330: ;
    second = (long)((int)(var21));
    goto L_1242;
    L_1340: ;
    var48 = (unsigned long)((unsigned int)((var48 + depth)));
    goto L_12f5;
    L_1348: ;
    var58 = 0xfffffffe;
    goto L_1302;
    L_1350: ;
    var58 = 0xffffffff;
    goto L_1302;
    L_1358: ;
    __stack_chk_fail();
}
kraft_sum_q16 pass 31 lines
// glaurung: kraft_sum_q16 @ 0x1360
uint32_t kraft_sum_q16(const int32_t * arg0, int32_t arg1) {
    int index;
    int length;
    unsigned int total;
    long ret;
    long var2;
    long var3;
    int var4;
    long var5;
    long var6;
    long var7;
    ret = 0;
    if ((arg0 != 0)) {
        var2 = (unsigned long)((unsigned int)((arg1 - 1)));
        if (((unsigned long)(7) < (unsigned long)((unsigned long)((unsigned int)(var2))))) {
            return ret;
        }
        var3 = (long)((((long)arg0 + (var2 * 4)) + 4));
        var4 = 0x10000;
        var5 = 0;
        var6 = (long)arg0;
        do {
            var7 = (unsigned long)((unsigned int)(*(int *)((var6))));
            ret = (((unsigned long)(15) <= (unsigned long)((unsigned long)((unsigned int)((var7 - 1))))) ? (unsigned long)((unsigned int)(var5)) : (unsigned long)((unsigned int)((var5 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var4)) >> (var7 & 31))))))));
            var6 = (var6 + 4);
            var5 = ret;
        } while ((var6 != var3));
    }
    return ret;
}

← 213 fixtures