Fixture 46

bitset

C · 3 functions · 4 lanes · 12 of 12 function-lanes behave identically

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

A word-addressed bit set: population count, rank, and select. The word/bit index split (>>5, &31) and the SWAR popcount are dense bit arithmetic with no control flow to lean on.

tests/decompiler_fixtures/src/46_bitset.c source
#include <stdint.h>

/* A word-addressed bit set: population count, rank, and select.  The
 * word/bit index split (>>5, &31) and the SWAR popcount are dense bit
 * arithmetic with no control flow to lean on. */

#define BITSET_WORDS 8
#define BITSET_BITS (BITSET_WORDS * 32)

static uint32_t popcount32(uint32_t word) {
    word = word - ((word >> 1) & 0x55555555u);
    word = (word & 0x33333333u) + ((word >> 2) & 0x33333333u);
    word = (word + (word >> 4)) & 0x0F0F0F0Fu;
    return (word * 0x01010101u) >> 24;
}

__attribute__((noinline)) uint32_t
bitset_population(const uint32_t *words, int32_t word_count) {
    uint32_t total = 0;
    int32_t index;
    if (words == 0 || word_count < 0 || word_count > BITSET_WORDS) {
        return 0;
    }
    for (index = 0; index < word_count; ++index) {
        total += popcount32(words[index]);
    }
    return total;
}

__attribute__((noinline)) int32_t
bitset_rank(const uint32_t *words, int32_t word_count, int32_t position) {
    uint32_t total = 0;
    int32_t whole;
    int32_t index;
    if (words == 0 || word_count < 0 || word_count > BITSET_WORDS ||
        position < 0 || position > word_count * 32) {
        return -1;
    }
    whole = position / 32;
    for (index = 0; index < whole; ++index) {
        total += popcount32(words[index]);
    }
    if ((position % 32) != 0 && whole < word_count) {
        uint32_t mask = (1u << (uint32_t)(position % 32)) - 1u;
        total += popcount32(words[whole] & mask);
    }
    return (int32_t)total;
}

__attribute__((noinline)) int32_t
bitset_select(const uint32_t *words, int32_t word_count, int32_t ordinal) {
    int32_t seen = 0;
    int32_t index;
    if (words == 0 || word_count < 0 || word_count > BITSET_WORDS ||
        ordinal < 0) {
        return -1;
    }
    for (index = 0; index < word_count * 32; ++index) {
        uint32_t word = words[index / 32];
        if (((word >> (uint32_t)(index % 32)) & 1u) != 0u) {
            if (seen == ordinal) {
                return index;
            }
            seen += 1;
        }
    }
    return -2;
}

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

3/3
bitset_population pass 29 lines
// glaurung: bitset_population @ 0x1100
uint32_t bitset_population(const uint32_t * arg0, int32_t arg1) {
    extern unsigned int popcount32(unsigned int);
    unsigned int total;
    int index;
    int local_4;
    unsigned int var3;
    // x86-64 prologue: save rbp, frame 32 bytes
    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++) {
        var3 = popcount32((unsigned long)((unsigned int)(arg0[(long)(index)])));
        total = (var3 + total);
    }
    local_4 = total;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
bitset_rank pass 55 lines
// glaurung: bitset_rank @ 0x11f0
int32_t bitset_rank(const uint32_t * arg0, int32_t arg1, int32_t arg2) {
    extern unsigned int popcount32(unsigned int);
    unsigned int total;
    int whole;
    int index;
    unsigned int mask;
    int local_4;
    unsigned int var12;
    long var3;
    unsigned int var40;
    // x86-64 prologue: save rbp, frame 48 bytes
    total = 0;
    if ((arg0 == 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 (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 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);
    }
    var3 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) << 5)));
    if (((((unsigned int)(arg2) == (unsigned int)(var3)) | ((long)(arg2) < (long)((int)(var3)))) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    whole = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(arg2))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(arg2)))) / (int)(32)));
    for (index = 0; (index < whole); index++) {
        var12 = popcount32((unsigned long)((unsigned int)(arg0[(long)(index)])));
        total = (var12 + total);
    }
    if (((unsigned long)((unsigned int)(((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(arg2))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(arg2)))) % (int)(32))))) != 0)) {
        if ((whole < arg1)) {
            mask = ((unsigned int)((1 << ((unsigned long)((unsigned int)(((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(arg2))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(arg2)))) % (int)(32))))) & 31))) - 1);
            var40 = popcount32((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(whole)])) & mask))));
            total = (var40 + total);
        }
    }
    local_4 = total;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
bitset_select pass 45 lines
// glaurung: bitset_select @ 0x1300
int32_t bitset_select(const uint32_t * arg0, int32_t arg1, int32_t arg2) {
    int seen;
    int index;
    unsigned int word;
    int local_28;
    int local_4;
    seen = 0;
    if ((arg0 != 0)) {
        if ((0 <= (long)(arg1))) {
            if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) != 0)) {
                if ((0 <= (long)(arg2))) {
                    goto L_134a;
                }
            }
        }
    }
    local_4 = -1;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
    L_134a: ;
    index = 0;
    L_1351: ;
    if (((long)((int)(((unsigned long)((unsigned int)(arg1)) << 5))) <= (long)(index))) {
        goto L_13db;
    }
    word = arg0[(long)((int)(((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(index))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(index)))) / (int)(32)))))];
    local_28 = word;
    if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(local_28)) >> ((unsigned long)((unsigned int)(((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(index))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(index)))) % (int)(32))))) & 31)))) & 1))) != 0)) {
        if (((unsigned int)(seen) == (unsigned int)(arg2))) {
            local_4 = index;
            // x86-64 epilogue: restore rbp
            return (unsigned int)(local_4);
        }
        seen = ((unsigned int)(seen) + 1);
    }
    goto L_13cd;
    L_13cd: ;
    index = ((unsigned int)(index) + 1);
    goto L_1351;
    L_13db: ;
    local_4 = -2;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}

clang -O2

3/3
bitset_population pass 104 lines
// glaurung: bitset_population @ 0x1100
uint32_t bitset_population(const uint32_t * arg0, int32_t arg1) {
    int index;
    unsigned int total;
    long ret;
    long var107;
    long var11;
    int var116;
    int var130;
    long var132;
    long var140;
    int var149;
    int var163;
    long var165;
    long var173;
    int var182;
    int var196;
    long var198;
    int var20;
    long var206;
    int var215;
    int var229;
    long var230;
    long var231;
    long var239;
    int var248;
    long var3;
    long var33;
    long var41;
    int var50;
    int var64;
    long var66;
    long var74;
    int var83;
    int var97;
    long var99;
    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))));
        var11 = (unsigned long)((unsigned int)((var3 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var3)) >> 1))) & 0x55555555))))));
        var20 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var11)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var11)) & 0x33333333)));
        ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var20)) >> 4))) + (unsigned long)((unsigned int)(var20))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
        if (((unsigned long)((unsigned int)(arg1)) == 1)) {
            return ret;
        }
        var33 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x4))));
        var41 = (unsigned long)((unsigned int)((var33 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var33)) >> 1))) & 0x55555555))))));
        var50 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var41)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var41)) & 0x33333333)));
        var64 = (ret + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var50)) >> 4))) + (unsigned long)((unsigned int)(var50))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
        ret = (unsigned long)((unsigned int)(var64));
        if (((unsigned long)((unsigned int)(arg1)) == 2)) {
            return ret;
        }
        var66 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x8))));
        var74 = (unsigned long)((unsigned int)((var66 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var66)) >> 1))) & 0x55555555))))));
        var83 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var74)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var74)) & 0x33333333)));
        var97 = ((unsigned int)(var64) + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var83)) >> 4))) + (unsigned long)((unsigned int)(var83))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
        ret = (unsigned long)((unsigned int)(var97));
        if (((unsigned long)((unsigned int)(arg1)) == 3)) {
            return ret;
        }
        var99 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0xc))));
        var107 = (unsigned long)((unsigned int)((var99 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var99)) >> 1))) & 0x55555555))))));
        var116 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var107)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var107)) & 0x33333333)));
        var130 = ((unsigned int)(var97) + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var116)) >> 4))) + (unsigned long)((unsigned int)(var116))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
        ret = (unsigned long)((unsigned int)(var130));
        if (((unsigned long)((unsigned int)(arg1)) == 4)) {
            return ret;
        }
        var132 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x10))));
        var140 = (unsigned long)((unsigned int)((var132 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var132)) >> 1))) & 0x55555555))))));
        var149 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var140)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var140)) & 0x33333333)));
        var163 = ((unsigned int)(var130) + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var149)) >> 4))) + (unsigned long)((unsigned int)(var149))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
        ret = (unsigned long)((unsigned int)(var163));
        if (((unsigned long)((unsigned int)(arg1)) == 5)) {
            return ret;
        }
        var165 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x14))));
        var173 = (unsigned long)((unsigned int)((var165 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var165)) >> 1))) & 0x55555555))))));
        var182 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var173)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var173)) & 0x33333333)));
        var196 = ((unsigned int)(var163) + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var182)) >> 4))) + (unsigned long)((unsigned int)(var182))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
        ret = (unsigned long)((unsigned int)(var196));
        if (((unsigned long)((unsigned int)(arg1)) == 6)) {
            return ret;
        }
        var198 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x18))));
        var206 = (unsigned long)((unsigned int)((var198 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var198)) >> 1))) & 0x55555555))))));
        var215 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var206)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var206)) & 0x33333333)));
        var229 = ((unsigned int)(var196) + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var215)) >> 4))) + (unsigned long)((unsigned int)(var215))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
        var230 = (unsigned long)((unsigned int)(var229));
        ret = (unsigned long)((unsigned int)(var229));
        if (((unsigned long)((unsigned int)(arg1)) != 7)) {
            var231 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x1c))));
            var239 = (unsigned long)((unsigned int)((var231 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var231)) >> 1))) & 0x55555555))))));
            var248 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var239)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var239)) & 0x33333333)));
            ret = (unsigned long)((unsigned int)((var230 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var248)) >> 4))) + (unsigned long)((unsigned int)(var248))))) & 0xf0f0f0f))) * 0x1010101))) >> 24))))));
        }
    }
    return ret;
}
bitset_rank pass 140 lines
// glaurung: bitset_rank @ 0x1320
int32_t bitset_rank(const uint32_t * arg0, int32_t arg1, int32_t arg2) {
    int whole;
    int index;
    unsigned int mask;
    unsigned int total;
    long ret;
    int var106;
    long var107;
    long var108;
    int var11;
    long var116;
    long var12;
    int var125;
    int var139;
    long var140;
    long var141;
    long var149;
    int var158;
    int var172;
    long var173;
    long var174;
    long var182;
    int var191;
    long var20;
    int var205;
    long var206;
    long var207;
    long var215;
    int var224;
    int var238;
    long var239;
    long var240;
    long var248;
    int var257;
    int var277;
    long var278;
    long var286;
    int var29;
    long var294;
    int var303;
    long var42;
    long var50;
    int var59;
    int var73;
    long var74;
    long var75;
    long var83;
    long var9;
    int var92;
    ret = 0xffffffff;
    if ((arg0 != 0)) {
        if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
            return ret;
        }
        if (((long)(arg2) < 0)) {
            return ret;
        }
        if (((long)((int)(((unsigned long)((unsigned int)(arg1)) << 5))) < (long)(arg2))) {
            return ret;
        }
        whole = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) >> 5)));
        var9 = 0;
        if (((unsigned long)(32) <= (unsigned long)((unsigned long)((unsigned int)(arg2))))) {
            var11 = (((unsigned long)(2) <= (unsigned long)((unsigned long)((unsigned int)(whole)))) ? whole : 1);
            var12 = (unsigned long)((unsigned int)(*(int *)(((long)arg0))));
            var20 = (unsigned long)((unsigned int)((var12 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var12)) >> 1))) & 0x55555555))))));
            var29 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var20)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var20)) & 0x33333333)));
            var9 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var29)) >> 4))) + (unsigned long)((unsigned int)(var29))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
            if (((unsigned long)(64) <= (unsigned long)((unsigned long)((unsigned int)(arg2))))) {
                var42 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x4))));
                var50 = (unsigned long)((unsigned int)((var42 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var42)) >> 1))) & 0x55555555))))));
                var59 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var50)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var50)) & 0x33333333)));
                var73 = (var9 + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var59)) >> 4))) + (unsigned long)((unsigned int)(var59))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
                var74 = (unsigned long)((unsigned int)(var73));
                var9 = (unsigned long)((unsigned int)(var73));
                if (((unsigned long)((unsigned int)(var11)) != 2)) {
                    var75 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x8))));
                    var83 = (unsigned long)((unsigned int)((var75 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var75)) >> 1))) & 0x55555555))))));
                    var92 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var83)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var83)) & 0x33333333)));
                    var106 = (var74 + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var92)) >> 4))) + (unsigned long)((unsigned int)(var92))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
                    var107 = (unsigned long)((unsigned int)(var106));
                    var9 = (unsigned long)((unsigned int)(var106));
                    if (((unsigned long)((unsigned int)(var11)) != 3)) {
                        var108 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0xc))));
                        var116 = (unsigned long)((unsigned int)((var108 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var108)) >> 1))) & 0x55555555))))));
                        var125 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var116)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var116)) & 0x33333333)));
                        var139 = (var107 + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var125)) >> 4))) + (unsigned long)((unsigned int)(var125))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
                        var140 = (unsigned long)((unsigned int)(var139));
                        var9 = (unsigned long)((unsigned int)(var139));
                        if (((unsigned long)((unsigned int)(var11)) != 4)) {
                            var141 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x10))));
                            var149 = (unsigned long)((unsigned int)((var141 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var141)) >> 1))) & 0x55555555))))));
                            var158 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var149)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var149)) & 0x33333333)));
                            var172 = (var140 + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var158)) >> 4))) + (unsigned long)((unsigned int)(var158))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
                            var173 = (unsigned long)((unsigned int)(var172));
                            var9 = (unsigned long)((unsigned int)(var172));
                            if (((unsigned long)((unsigned int)(var11)) != 5)) {
                                var174 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x14))));
                                var182 = (unsigned long)((unsigned int)((var174 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var174)) >> 1))) & 0x55555555))))));
                                var191 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var182)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var182)) & 0x33333333)));
                                var205 = (var173 + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var191)) >> 4))) + (unsigned long)((unsigned int)(var191))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
                                var206 = (unsigned long)((unsigned int)(var205));
                                var9 = (unsigned long)((unsigned int)(var205));
                                if (((unsigned long)((unsigned int)(var11)) != 6)) {
                                    var207 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x18))));
                                    var215 = (unsigned long)((unsigned int)((var207 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var207)) >> 1))) & 0x55555555))))));
                                    var224 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var215)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var215)) & 0x33333333)));
                                    var238 = (var206 + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var224)) >> 4))) + (unsigned long)((unsigned int)(var224))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
                                    var239 = (unsigned long)((unsigned int)(var238));
                                    var9 = (unsigned long)((unsigned int)(var238));
                                    if (((unsigned long)((unsigned int)(var11)) != 7)) {
                                        var240 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x1c))));
                                        var248 = (unsigned long)((unsigned int)((var240 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var240)) >> 1))) & 0x55555555))))));
                                        var257 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var248)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var248)) & 0x33333333)));
                                        var9 = (unsigned long)((unsigned int)((var239 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var257)) >> 4))) + (unsigned long)((unsigned int)(var257))))) & 0xf0f0f0f))) * 0x1010101))) >> 24))))));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        var277 = (arg2 - (unsigned int)((((0 <= (long)(arg2)) ? arg2 : (unsigned long)((unsigned int)((arg2 + 31)))) & -32)));
        var278 = (unsigned long)((unsigned int)(var277));
        ret = var9;
        if (((unsigned long)((unsigned int)(var277)) == 0)) {
            return ret;
        }
        ret = var9;
        if ((whole < arg1)) {
            var286 = (unsigned long)((unsigned int)(((~(unsigned long)((unsigned int)((0xffffffff << ((unsigned long)((unsigned int)(var278)) & 31))))) & arg0[(unsigned long)((unsigned int)(whole))])));
            var294 = (unsigned long)((unsigned int)((var286 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var286)) >> 1))) & 0x55555555))))));
            var303 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var294)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var294)) & 0x33333333)));
            ret = (unsigned long)((unsigned int)((var9 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var303)) >> 4))) + (unsigned long)((unsigned int)(var303))))) & 0xf0f0f0f))) * 0x1010101))) >> 24))))));
        }
    }
    return ret;
}
bitset_select pass 55 lines
// glaurung: bitset_select @ 0x1620
int32_t bitset_select(const uint32_t * arg0, int32_t arg1, int32_t arg2) {
    int index;
    int seen;
    unsigned int word;
    long ret;
    long var1;
    long var13;
    long var7;
    int var8;
    long var9;
    ret = 0xffffffff;
    if ((arg0 == 0)) {
        return ret;
    }
    if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return ret;
    }
    if (((long)(arg2) < 0)) {
        return ret;
    }
    ret = 0xfffffffe;
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        return ret;
    }
    var1 = (unsigned long)((unsigned int)((arg1 << 5)));
    index = 0;
    var7 = 0;
    goto L_1659;
    L_1650: ;
    var8 = (index + 2);
    index = (unsigned long)((unsigned int)(var8));
    var7 = var9;
    if (((unsigned int)(var1) == (unsigned int)(var8))) {
        return ret;
    }
    L_1659: ;
    var13 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(index)) >> 5)));
    var9 = var7;
    if (((((unsigned long)((unsigned int)(*(int *)(((long)arg0 + var13 * 4)))) >> ((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(index)) & 30))) & 31)) & 1) != 0)) {
        if (((unsigned int)(var7) == (unsigned int)(arg2))) {
            return (unsigned int)(index);
        }
        var9 = (unsigned long)((unsigned int)((var7 + 1)));
    }
    if (((((unsigned long)((unsigned int)(*(int *)(((long)arg0 + var13 * 4)))) >> ((unsigned int)((unsigned char)(((unsigned long)((unsigned int)((index + 1))) & 255))) & 31)) & 1) == 0)) {
        goto L_1650;
    }
    if (((unsigned int)(var9) == (unsigned int)(arg2))) {
        index = (unsigned long)((unsigned int)((index + 1)));
        return (unsigned int)(index);
    }
    var9 = (unsigned long)((unsigned int)((var9 + 1)));
    goto L_1650;
}

gcc -O0

3/3
bitset_population pass 27 lines
// glaurung: bitset_population @ 0x114e
uint32_t bitset_population(const uint32_t * arg0, int32_t arg1) {
    extern unsigned int popcount32(unsigned int);
    unsigned int total;
    int index;
    unsigned int var7;
    // x86-64 prologue: save rbp, frame 32 bytes
    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++) {
        var7 = popcount32((unsigned long)((unsigned int)(arg0[(long)(index)])));
        total = (total + var7);
    }
    // x86-64 epilogue: restore rbp
    return total;
}
bitset_rank pass 50 lines
// glaurung: bitset_rank @ 0x11bc
int32_t bitset_rank(const uint32_t * arg0, int32_t arg1, int32_t arg2) {
    extern unsigned int popcount32(unsigned int);
    unsigned int total;
    int whole;
    int index;
    unsigned int mask;
    unsigned int var16;
    long var2;
    long var26;
    unsigned int var48;
    // x86-64 prologue: save rbp, frame 32 bytes
    total = 0;
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((long)(arg1) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((long)(arg2) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    var2 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) << 5)));
    if (((((unsigned int)(arg2) == (unsigned int)(var2)) | ((long)(arg2) < (long)((int)(var2)))) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    whole = ((int)((((long)(arg2) < 0) ? (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) + 31))) : (unsigned long)((unsigned int)(arg2)))) >> 5);
    for (index = 0; (index < whole); index++) {
        var16 = popcount32((unsigned long)((unsigned int)(arg0[(long)(index)])));
        total = (total + var16);
    }
    if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) & 31))) != 0)) {
        if ((whole < arg1)) {
            var26 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((((unsigned long)((long)(arg2)) >> 32) & 0xffffffff))) >> 27)));
            mask = ((unsigned int)((1 << ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) + var26))) & 31))) - var26))) & 31))) - 1);
            var48 = popcount32((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(whole)])) & mask))));
            total = (total + var48);
        }
    }
    // x86-64 epilogue: restore rbp
    return total;
}
bitset_select pass 39 lines
// glaurung: bitset_select @ 0x12a6
int32_t bitset_select(const uint32_t * arg0, int32_t arg1, int32_t arg2) {
    int seen;
    int index;
    unsigned int word;
    long var15;
    seen = 0;
    if ((arg0 != 0)) {
        if ((0 <= (long)(arg1))) {
            if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) != 0)) {
                if ((0 <= (long)(arg2))) {
                    goto L_12df;
                }
            }
        }
    }
    // x86-64 epilogue: restore rbp
    return 0xffffffff;
    L_12df: ;
    index = 0;
    goto L_133f;
    L_12e8: ;
    word = arg0[(long)((int)(((int)((((long)(index) < 0) ? (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(index)) + 31))) : (unsigned long)((unsigned int)(index)))) >> 5)))];
    var15 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((((unsigned long)((long)(index)) >> 32) & 0xffffffff))) >> 27)));
    if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(word) >> ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(index)) + var15))) & 31))) - var15))) & 31)))) & 1))) != 0)) {
        if (((unsigned int)(seen) == (unsigned int)(arg2))) {
            // x86-64 epilogue: restore rbp
            return (unsigned int)(index);
        }
        seen = (seen + 1);
    }
    index = (index + 1);
    L_133f: ;
    if (((long)(index) < (long)((int)(((unsigned long)((unsigned int)(arg1)) << 5))))) {
        goto L_12e8;
    }
    // x86-64 epilogue: restore rbp
    return 0xfffffffe;
}

gcc -O2

3/3
bitset_population pass 32 lines
// glaurung: bitset_population @ 0x1100
uint32_t bitset_population(const uint32_t * arg0, int32_t arg1) {
    int index;
    unsigned int total;
    long var1;
    long var15;
    int var24;
    long var3;
    long var4;
    long var5;
    long var6;
    long var7;
    var1 = 0;
    if ((arg0 == 0)) {
        return (unsigned int)(var1);
    }
    var3 = (unsigned long)((unsigned int)((arg1 - 1)));
    if (((unsigned long)(7) < (unsigned long)((unsigned long)((unsigned int)(var3))))) {
        return (unsigned int)(var1);
    }
    var4 = (long)((((long)arg0 + (var3 * 4)) + 4));
    var5 = 0;
    var6 = (long)arg0;
    do {
        var7 = (unsigned long)((unsigned int)(*(int *)((var6))));
        var6 = (var6 + 4);
        var15 = (unsigned long)((unsigned int)((var7 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var7)) >> 1))) & 0x55555555))))));
        var24 = ((unsigned int)(((unsigned long)((unsigned int)(var15)) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var15)) >> 2))) & 0x33333333)));
        var5 = (unsigned long)((unsigned int)((var5 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var24)) >> 4))) + (unsigned long)((unsigned int)(var24))))) & 0xf0f0f0f))) * 0x1010101))) >> 24))))));
    } while ((var4 != var6));
    return (unsigned int)(var5);
}
bitset_rank pass 64 lines
// glaurung: bitset_rank @ 0x1170
int32_t bitset_rank(const uint32_t * arg0, int32_t arg1, int32_t arg2) {
    int whole;
    unsigned int total;
    int index;
    long ret;
    long var0;
    long var1;
    long var12;
    long var13;
    long var16;
    long var17;
    long var25;
    int var34;
    int var49;
    long var50;
    long var57;
    long var65;
    int var7;
    int var74;
    var0 = (unsigned long)((unsigned int)(arg1));
    var1 = (unsigned long)((unsigned int)(arg2));
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    if (((long)(arg2) < 0)) {
        return 0xffffffff;
    }
    if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return 0xffffffff;
    }
    if (((long)((int)(((unsigned long)((unsigned int)(arg1)) << 5))) < (long)(arg2))) {
        return 0xffffffff;
    }
    var7 = ((int)(arg2) >> 5);
    whole = (unsigned long)((unsigned int)(var7));
    if (((unsigned long)((unsigned int)(var7)) == 0)) {
        ret = 0;
    } else {
        var12 = (long)arg0;
        var13 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((whole - 1))) * 4)) + 4));
        var16 = 0;
        do {
            var17 = (unsigned long)((unsigned int)(*(int *)((var12))));
            var12 = (var12 + 4);
            var25 = (unsigned long)((unsigned int)((var17 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var17)) >> 1))) & 0x55555555))))));
            var34 = ((unsigned int)(((unsigned long)((unsigned int)(var25)) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var25)) >> 2))) & 0x33333333)));
            total = (var16 + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var34)) >> 4))) + (unsigned long)((unsigned int)(var34))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)));
            var16 = (unsigned long)(total);
            ret = (unsigned long)(total);
        } while ((var13 != var12));
    }
    var49 = (var1 & 31);
    var50 = (unsigned long)((unsigned int)(var49));
    if (((unsigned long)((unsigned int)(var49)) != 0)) {
        if (((((unsigned int)(var0) == (unsigned int)(whole)) | ((long)((int)(var0)) < (long)(whole))) == 0)) {
            var57 = (unsigned long)((unsigned int)(((~(unsigned long)((unsigned int)((0xffffffff << (var50 & 31))))) & arg0[(long)(whole)])));
            var65 = (unsigned long)((unsigned int)((var57 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var57)) >> 1))) & 0x55555555))))));
            var74 = ((unsigned int)(((unsigned long)((unsigned int)(var65)) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var65)) >> 2))) & 0x33333333)));
            return (unsigned int)((ret + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var74)) >> 4))) + (unsigned long)((unsigned int)(var74))))) & 0xf0f0f0f))) * 0x1010101))) >> 24)))));
        }
    }
    return ret;
}
bitset_select pass 34 lines
// glaurung: bitset_select @ 0x1280
int32_t bitset_select(const uint32_t * arg0, int32_t arg1, int32_t arg2) {
    int index;
    int seen;
    long ret;
    int var16;
    long var2;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    if (((long)(arg2) < 0)) {
        return 0xffffffff;
    }
    if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return 0xffffffff;
    }
    var2 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) << 5)));
    if (((unsigned long)((unsigned int)(arg1)) != 0)) {
        index = 0;
        seen = 0;
        do {
            if (((((unsigned long)((unsigned int)(arg0[(long)((int)(((int)(index) >> 5)))])) >> (index & 31)) & 1) != 0)) {
                ret = (unsigned long)((unsigned int)(index));
                if (((unsigned int)(arg2) == (unsigned int)(seen))) {
                    return ret;
                }
                seen = (unsigned long)((unsigned int)((seen + 1)));
            }
            var16 = (index + 1);
            index = (unsigned long)((unsigned int)(var16));
        } while (((unsigned int)(var16) != (unsigned int)(var2)));
    }
    return 0xfffffffe;
}

← 213 fixtures