Fixture 79

segment tree

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

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

An iterative segment tree over a flat array: build, point update, and range sum. Index arithmetic climbs by halving and descends by doubling, so the recovered loop must keep the parent/child relation exact.

tests/decompiler_fixtures/src/79_segment_tree.c source
#include <stdint.h>

/* An iterative segment tree over a flat array: build, point update, and range
 * sum.  Index arithmetic climbs by halving and descends by doubling, so the
 * recovered loop must keep the parent/child relation exact. */

#define SEG_LEAVES 8
#define SEG_NODES (2 * SEG_LEAVES)

__attribute__((noinline)) int32_t
segment_build(const int32_t *values, int32_t count, int32_t *tree) {
    int32_t index;
    if (values == 0 || tree == 0 || count < 0 || count > SEG_LEAVES) {
        return -1;
    }
    for (index = 0; index < SEG_NODES; ++index) {
        tree[index] = 0;
    }
    for (index = 0; index < count; ++index) {
        tree[SEG_LEAVES + index] = values[index];
    }
    for (index = SEG_LEAVES - 1; index >= 1; --index) {
        tree[index] = tree[2 * index] + tree[2 * index + 1];
    }
    return tree[1];
}

__attribute__((noinline)) int32_t
segment_update(int32_t *tree, int32_t position, int32_t value) {
    int32_t node;
    if (tree == 0 || position < 0 || position >= SEG_LEAVES) {
        return -1;
    }
    node = SEG_LEAVES + position;
    tree[node] = value;
    for (node /= 2; node >= 1; node /= 2) {
        tree[node] = tree[2 * node] + tree[2 * node + 1];
    }
    return tree[1];
}

__attribute__((noinline)) int32_t
segment_range_sum(const int32_t *tree, int32_t low, int32_t high) {
    int32_t total = 0;
    int32_t left;
    int32_t right;
    if (tree == 0 || low < 0 || high > SEG_LEAVES || low > high) {
        return -1;
    }
    left = low + SEG_LEAVES;
    right = high + SEG_LEAVES;
    while (left < right) {
        if ((left & 1) != 0) {
            total += tree[left];
            left += 1;
        }
        if ((right & 1) != 0) {
            right -= 1;
            total += tree[right];
        }
        left /= 2;
        right /= 2;
    }
    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

3/3
segment_build pass 40 lines
// glaurung: segment_build @ 0x1100
int32_t segment_build(const int32_t * arg0, int32_t arg1, int32_t * arg2) {
    int index;
    int local_4;
    // x86-64 prologue: save rbp
    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 (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    for (index = 0; ((long)(index) < 16); index++) {
        arg2[(long)(index)] = 0;
    }
    for (index = 0; (index < arg1); index++) {
        arg2[(long)((int)(((unsigned long)((unsigned int)(index)) + 8)))] = arg0[(long)(index)];
    }
    index = 7;
    while ((1 <= (long)(index))) {
        arg2[(long)(index)] = ((unsigned long)((unsigned int)(arg2[(long)((int)(((unsigned long)((unsigned int)(index)) << 1)))])) + arg2[(long)((int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(index)) << 1))) + 1)))]);
        index = ((unsigned int)(index) - 1);
    }
    local_4 = *(int *)(((long)arg2 + 0x4));
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
segment_range_sum pass 46 lines
// glaurung: segment_range_sum @ 0x12d0
int32_t segment_range_sum(const int32_t * arg0, int32_t arg1, int32_t arg2) {
    int total;
    int left;
    int right;
    int local_4;
    // x86-64 prologue: save rbp
    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)(arg2)) == 8) | ((long)(arg2) < 8)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned int)(arg1) == (unsigned int)(arg2)) | (arg1 < arg2)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    left = ((unsigned int)(arg1) + 8);
    right = ((unsigned int)(arg2) + 8);
    while ((left < right)) {
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(left)) & 1))) != 0)) {
            total = ((unsigned int)(arg0[(long)(left)]) + total);
            left = ((unsigned int)(left) + 1);
        }
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(right)) & 1))) != 0)) {
            right = ((unsigned int)(right) - 1);
            total = ((unsigned int)(arg0[(long)(right)]) + total);
        }
        left = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(left))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(left)))) / (int)(2)));
        right = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(right))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(right)))) / (int)(2)));
    }
    local_4 = total;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
segment_update pass 31 lines
// glaurung: segment_update @ 0x1210
int32_t segment_update(int32_t * arg0, int32_t arg1, int32_t arg2) {
    int node;
    int local_4;
    // x86-64 prologue: save rbp
    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 ((8 <= (long)(arg1))) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    node = ((unsigned int)(arg1) + 8);
    arg0[(long)(node)] = arg2;
    node = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(node))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(node)))) / (int)(2)));
    while ((1 <= (long)(node))) {
        arg0[(long)(node)] = ((unsigned long)((unsigned int)(arg0[(long)((int)(((unsigned long)((unsigned int)(node)) << 1)))])) + arg0[(long)((int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(node)) << 1))) + 1)))]);
        node = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(node))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(node)))) / (int)(2)));
    }
    local_4 = *(int *)(((long)arg0 + 0x4));
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}

clang -O2

3/3
segment_build pass 83 lines
// glaurung: segment_build @ 0x1100
int32_t segment_build(const int32_t * arg0, int32_t arg1, int32_t * arg2) {
    int index;
    long ret;
    long var10;
    long var12;
    int var29;
    int var31;
    int var33;
    long var6;
    long var8;
    ret = 0xffffffff;
    if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return ret;
    }
    if ((arg0 == 0)) {
        return ret;
    }
    if ((arg2 == 0)) {
        return ret;
    }
    *(int *)(((long)arg2 + 0x30)) = 0;
    *(int *)(((long)arg2 + 0x34)) = 0;
    *(int *)(((long)arg2 + 0x38)) = 0;
    *(int *)(((long)arg2 + 0x3c)) = 0;
    *(int *)(((long)arg2 + 0x20)) = 0;
    *(int *)(((long)arg2 + 0x24)) = 0;
    *(int *)(((long)arg2 + 0x28)) = 0;
    *(int *)(((long)arg2 + 0x2c)) = 0;
    *(int *)(((long)arg2 + 0x10)) = 0;
    *(int *)(((long)arg2 + 0x14)) = 0;
    *(int *)(((long)arg2 + 0x18)) = 0;
    *(int *)(((long)arg2 + 0x1c)) = 0;
    *(int *)(((long)arg2)) = 0;
    *(int *)(((long)arg2 + 0x4)) = 0;
    *(int *)(((long)arg2 + 0x8)) = 0;
    *(int *)(((long)arg2 + 0xc)) = 0;
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        var6 = 0;
        var8 = 0;
        var10 = 0;
        var12 = 0;
    } else {
        *(int *)(((long)arg2 + 0x20)) = *(int *)(((long)arg0));
        if (((unsigned long)((unsigned int)(arg1)) != 1)) {
            *(int *)(((long)arg2 + 0x24)) = *(int *)(((long)arg0 + 0x4));
            if (((unsigned long)((unsigned int)(arg1)) != 2)) {
                *(int *)(((long)arg2 + 0x28)) = *(int *)(((long)arg0 + 0x8));
                if (((unsigned long)((unsigned int)(arg1)) != 3)) {
                    *(int *)(((long)arg2 + 0x2c)) = *(int *)(((long)arg0 + 0xc));
                    if (((unsigned long)((unsigned int)(arg1)) != 4)) {
                        *(int *)(((long)arg2 + 0x30)) = *(int *)(((long)arg0 + 0x10));
                        if (((unsigned long)((unsigned int)(arg1)) != 5)) {
                            *(int *)(((long)arg2 + 0x34)) = *(int *)(((long)arg0 + 0x14));
                            if (((unsigned long)((unsigned int)(arg1)) != 6)) {
                                *(int *)(((long)arg2 + 0x38)) = *(int *)(((long)arg0 + 0x18));
                                if (((unsigned long)((unsigned int)(arg1)) != 7)) {
                                    *(int *)(((long)arg2 + 0x3c)) = *(int *)(((long)arg0 + 0x1c));
                                }
                            }
                        }
                    }
                }
            }
        }
        var6 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)(((long)arg2 + 0x3c)))) + *(int *)(((long)arg2 + 0x38)))));
        var8 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)(((long)arg2 + 0x34)))) + *(int *)(((long)arg2 + 0x30)))));
        var10 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)(((long)arg2 + 0x2c)))) + *(int *)(((long)arg2 + 0x28)))));
        var12 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)(((long)arg2 + 0x24)))) + *(int *)(((long)arg2 + 0x20)))));
    }
    *(int *)(((long)arg2 + 0x1c)) = var6;
    *(int *)(((long)arg2 + 0x18)) = var8;
    *(int *)(((long)arg2 + 0x14)) = var10;
    *(int *)(((long)arg2 + 0x10)) = var12;
    var29 = (var6 + var8);
    *(int *)(((long)arg2 + 0xc)) = var29;
    var31 = (var10 + var12);
    *(int *)(((long)arg2 + 0x8)) = var31;
    var33 = ((unsigned int)(var31) + (unsigned int)(var29));
    ret = (unsigned long)((unsigned int)(var33));
    *(int *)(((long)arg2 + 0x4)) = var33;
    return (unsigned int)(var33);
}
segment_range_sum pass 55 lines
// glaurung: segment_range_sum @ 0x1220
int32_t segment_range_sum(const int32_t * arg0, int32_t arg1, int32_t arg2) {
    int right;
    int left;
    int total;
    long ret;
    long var10;
    long var11;
    long var15;
    long var27;
    long var36;
    long var9;
    ret = 0xffffffff;
    if (((((unsigned int)(arg1) == (unsigned int)(arg2)) | (arg1 < arg2)) != 0)) {
        ret = 0xffffffff;
        if ((arg0 == 0)) {
            return ret;
        }
        ret = 0xffffffff;
        if (((long)(arg1) < 0)) {
            return ret;
        }
        ret = 0xffffffff;
        if (((((unsigned long)((unsigned int)(arg2)) == 8) | ((long)(arg2) < 8)) == 0)) {
            return ret;
        }
        ret = 0;
        if ((arg2 <= arg1)) {
            return ret;
        }
        right = (unsigned long)((unsigned int)((arg2 + 8)));
        left = (unsigned long)((unsigned int)((arg1 + 8)));
        var9 = 0;
        do {
            var10 = var9;
            var11 = (unsigned long)((unsigned int)(left));
            if (((unsigned long)((unsigned char)((left & 1))) != 0)) {
                var10 = (unsigned long)((unsigned int)((var9 + arg0[(long)(left)])));
                var11 = (unsigned long)((unsigned int)((left + 1)));
            }
            var15 = (unsigned long)((unsigned int)(right));
            if (((unsigned long)((unsigned char)((right & 1))) != 0)) {
                var15 = (unsigned long)((unsigned int)((right - 1)));
                var10 = (unsigned long)((unsigned int)((var10 + *(int *)((((long)arg0 + ((long)(right) * 4)) - 4)))));
            }
            var27 = (unsigned long)((unsigned int)(((int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var11)) >> 31))) + var11)) >> 1)));
            var36 = (unsigned long)((unsigned int)(((int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var15)) >> 31))) + var15)) >> 1)));
            var9 = var10;
            right = (unsigned long)((unsigned int)(var36));
            left = (unsigned long)((unsigned int)(var27));
            ret = var10;
        } while (((long)((int)(var27)) < (long)((int)(var36))));
    }
    return ret;
}
segment_update pass 32 lines
// glaurung: segment_update @ 0x11d0
int32_t segment_update(int32_t * arg0, int32_t arg1, int32_t arg2) {
    int node;
    long of_10;
    long ret;
    long t157;
    long var12;
    long var2;
    long var20;
    int var7;
    long zf_10;
    ret = 0xffffffff;
    if ((arg0 == 0)) {
        return ret;
    }
    if (((unsigned long)(7) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return ret;
    }
    var2 = (unsigned long)((unsigned int)((arg1 + 8)));
    *(int *)((((long)arg0 + ((unsigned long)((unsigned int)(arg1)) * 4)) + 32)) = arg2;
    do {
        var7 = ((unsigned int)(((unsigned long)((unsigned int)(var2)) >> 31)) + var2);
        var12 = (long)((int)(((unsigned long)((unsigned int)(var7)) & -2)));
        var20 = (unsigned long)((unsigned int)(((int)(var7) >> 1)));
        arg0[(long)((int)(var20))] = ((unsigned long)((unsigned int)(arg0[(long)((int)((var12 + 1)))])) + *(int *)(((long)arg0 + var12 * 4)));
        t157 = (var2 - 3);
        zf_10 = ((unsigned long)((unsigned int)(var2)) == 3);
        of_10 = (((long)((int)(var2)) < 3) ^ ((long)((int)(t157)) < 0));
        var2 = (unsigned long)((unsigned int)(var20));
    } while (((zf_10 | (((long)((int)(t157)) < 0) ^ of_10)) == 0));
    return (unsigned int)(*(int *)(((long)arg0 + 0x4)));
}

gcc -O0

3/3
segment_build pass 34 lines
// glaurung: segment_build @ 0x10f9
int32_t segment_build(const int32_t * arg0, int32_t arg1, int32_t * arg2) {
    int index;
    // x86-64 prologue: save rbp
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if ((arg2 == 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;
    }
    for (index = 0; ((((unsigned long)((unsigned int)(index)) == 15) | ((long)(index) < 15)) != 0); index++) {
        arg2[(long)(index)] = 0;
    }
    for (index = 0; (index < arg1); index++) {
        arg2[(long)((int)(((unsigned long)((unsigned int)(index)) + 8)))] = arg0[(long)(index)];
    }
    index = 7;
    while (((((unsigned long)((unsigned int)(index)) == 0) | ((long)(index) < 0)) == 0)) {
        arg2[(long)(index)] = ((unsigned long)((unsigned int)(arg2[((long)((int)(((unsigned long)((unsigned int)(index)) + (unsigned long)((unsigned int)(index))))) + 1)])) + (unsigned long)((unsigned int)(arg2[(long)((int)(((unsigned long)((unsigned int)(index)) + (unsigned long)((unsigned int)(index)))))])));
        index = (index - 1);
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(*(int *)(((long)arg2 + 0x4)));
}
segment_range_sum pass 40 lines
// glaurung: segment_range_sum @ 0x12d6
int32_t segment_range_sum(const int32_t * arg0, int32_t arg1, int32_t arg2) {
    int total;
    int left;
    int right;
    // x86-64 prologue: save rbp
    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)(arg2)) == 8) | ((long)(arg2) < 8)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned int)(arg1) == (unsigned int)(arg2)) | (arg1 < arg2)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    left = ((unsigned int)(arg1) + 8);
    right = ((unsigned int)(arg2) + 8);
    while ((left < right)) {
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(left)) & 1))) != 0)) {
            total = (total + (unsigned int)(arg0[(long)(left)]));
            left = (left + 1);
        }
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(right)) & 1))) != 0)) {
            right = (right - 1);
            total = (total + (unsigned int)(arg0[(long)(right)]));
        }
        left = ((int)(((unsigned long)((unsigned int)(left)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(left)) >> 31))))) >> 1);
        right = ((int)(((unsigned long)((unsigned int)(right)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(right)) >> 31))))) >> 1);
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(total);
}
segment_update pass 26 lines
// glaurung: segment_update @ 0x120a
int32_t segment_update(int32_t * arg0, int32_t arg1, int32_t arg2) {
    int node;
    // x86-64 prologue: save rbp
    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)) == 7) | ((long)(arg1) < 7)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    node = ((unsigned int)(arg1) + 8);
    arg0[(long)(node)] = arg2;
    node = ((int)(((unsigned long)((unsigned int)(node)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(node)) >> 31))))) >> 1);
    while (((((unsigned long)((unsigned int)(node)) == 0) | ((long)(node) < 0)) == 0)) {
        arg0[(long)(node)] = ((unsigned long)((unsigned int)(arg0[((long)((int)(((unsigned long)((unsigned int)(node)) + (unsigned long)((unsigned int)(node))))) + 1)])) + (unsigned long)((unsigned int)(arg0[(long)((int)(((unsigned long)((unsigned int)(node)) + (unsigned long)((unsigned int)(node)))))])));
        node = ((int)(((unsigned long)((unsigned int)(node)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(node)) >> 31))))) >> 1);
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(*(int *)(((long)arg0 + 0x4)));
}

gcc -O2

3/3
segment_build pass 47 lines
// glaurung: segment_build @ 0x1100
int32_t segment_build(const int32_t * arg0, int32_t arg1, int32_t * arg2) {
    int index;
    long var14;
    long var6;
    long var8;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    if ((arg2 == 0)) {
        return 0xffffffff;
    }
    if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return 0xffffffff;
    }
    *(int *)(((long)arg2)) = 0;
    *(int *)(((long)arg2 + 0x4)) = 0;
    *(int *)(((long)arg2 + 0x8)) = 0;
    *(int *)(((long)arg2 + 0xc)) = 0;
    *(int *)(((long)arg2 + 0x10)) = 0;
    *(int *)(((long)arg2 + 0x14)) = 0;
    *(int *)(((long)arg2 + 0x18)) = 0;
    *(int *)(((long)arg2 + 0x1c)) = 0;
    *(int *)(((long)arg2 + 0x20)) = 0;
    *(int *)(((long)arg2 + 0x24)) = 0;
    *(int *)(((long)arg2 + 0x28)) = 0;
    *(int *)(((long)arg2 + 0x2c)) = 0;
    *(int *)(((long)arg2 + 0x30)) = 0;
    *(int *)(((long)arg2 + 0x34)) = 0;
    *(int *)(((long)arg2 + 0x38)) = 0;
    *(int *)(((long)arg2 + 0x3c)) = 0;
    if (((unsigned long)((unsigned int)(arg1)) != 0)) {
        var6 = 0;
        do {
            *(int *)(((long)arg2 + var6 * 4 + 0x20)) = *(int *)(((long)arg0 + var6 * 4));
            var8 = (var6 + 1);
            var6 = var8;
        } while (((((unsigned int)(arg1) == (unsigned int)(var8)) | ((long)(arg1) < (long)((int)(var8)))) == 0));
    }
    index = 7;
    do {
        *(int *)(((long)arg2 + index * 4)) = ((unsigned long)((unsigned int)(*(int *)(((long)arg2 + index * 8 + 0x4)))) + *(int *)(((long)arg2 + index * 8)));
        var14 = ((unsigned long)((unsigned int)(index)) - 1);
        index = var14;
    } while ((var14 != 0));
    return (unsigned int)(*(int *)(((long)arg2 + 0x4)));
}
segment_range_sum pass 55 lines
// glaurung: segment_range_sum @ 0x11b0
int32_t segment_range_sum(const int32_t * arg0, int32_t arg1, int32_t arg2) {
    int total;
    int left;
    int right;
    long of_4;
    long sf_4;
    long t178;
    long var1;
    long var26;
    long var31;
    long var7;
    if ((arg0 == 0)) {
        var1 = 0xffffffff;
        return 0xffffffff;
    }
    if (((long)(arg1) < 0)) {
        var1 = 0xffffffff;
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 8) | ((long)(arg2) < 8)) == 0)) {
        var1 = 0xffffffff;
        return 0xffffffff;
    }
    t178 = ((unsigned long)((unsigned int)(arg1)) - (unsigned long)((unsigned int)(arg2)));
    sf_4 = ((long)((int)(t178)) < 0);
    of_4 = ((arg1 < arg2) ^ ((long)((int)(t178)) < 0));
    if (((((unsigned int)(arg1) == (unsigned int)(arg2)) | (arg1 < arg2)) == 0)) {
        var1 = 0xffffffff;
        return 0xffffffff;
    }
    var1 = 0;
    if (((sf_4 ^ of_4) != 0)) {
        total = 0;
        left = (unsigned long)((unsigned int)((arg1 + 8)));
        right = (unsigned long)((unsigned int)((arg2 + 8)));
        do {
            var7 = (unsigned long)((unsigned int)(left));
            if (((unsigned long)((unsigned char)((left & 1))) != 0)) {
                var7 = (unsigned long)((unsigned int)((left + 1)));
                total = (unsigned long)((unsigned int)((total + arg0[(long)(left)])));
            }
            if (((unsigned long)((unsigned char)((right & 1))) != 0)) {
                right = (unsigned long)((unsigned int)((right - 1)));
                total = (unsigned long)((unsigned int)((total + arg0[(long)(right)])));
            }
            var26 = (unsigned long)((unsigned int)(((int)((var7 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var7)) >> 31))))) >> 1)));
            var31 = (unsigned long)((unsigned int)(((int)((right + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(right)) >> 31))))) >> 1)));
            left = var26;
            right = var31;
            var1 = (unsigned long)((unsigned int)(total));
        } while (((long)((int)(var26)) < (long)((int)(var31))));
    }
    return (unsigned int)(var1);
}
segment_update pass 25 lines
// glaurung: segment_update @ 0x1170
int32_t segment_update(int32_t * arg0, int32_t arg1, int32_t arg2) {
    int node;
    int var0;
    int var14;
    long var8;
    long var9;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    if (((unsigned long)(7) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return 0xffffffff;
    }
    var0 = (arg1 + 8);
    arg0[(long)((int)(var0))] = arg2;
    node = (unsigned long)((unsigned int)(((int)(var0) >> 1)));
    do {
        var8 = (long)(node);
        var9 = (long)((int)((node + node)));
        var14 = ((int)(node) >> 1);
        node = (unsigned long)((unsigned int)(var14));
        *(int *)(((long)arg0 + var8 * 4)) = ((unsigned long)((unsigned int)(*(int *)(((long)arg0 + var9 * 4)))) + *(int *)(((long)arg0 + var9 * 4 + 0x4)));
    } while (((unsigned long)((unsigned int)(var14)) != 0));
    return (unsigned int)(*(int *)(((long)arg0 + 0x4)));
}

← 213 fixtures