Fixture 74

moving statistics

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

One lane has a function that returns a different result after decompilation: clang-O2 (2/3).

Simple and exponential moving averages plus a population variance, all in Q16.16. Variance accumulates squares in a 64-bit total and divides once at the end, a common width-narrowing failure point.

tests/decompiler_fixtures/src/74_moving_statistics.c source
#include <stdint.h>

/* Simple and exponential moving averages plus a population variance, all in
 * Q16.16.  Variance accumulates squares in a 64-bit total and divides once at
 * the end, a common width-narrowing failure point. */

#define SERIES_MAX 16

static int32_t stat_mul_q16(int32_t left, int32_t right) {
    return (int32_t)(((int64_t)left * (int64_t)right) >> 16);
}

__attribute__((noinline)) int32_t
simple_moving_average(const int32_t *series, int32_t count, int32_t window,
                      int32_t *output) {
    int32_t index;
    if (series == 0 || output == 0 || count < 0 || count > SERIES_MAX ||
        window < 1 || window > SERIES_MAX) {
        return -1;
    }
    for (index = 0; index < count; ++index) {
        int64_t total = 0;
        int32_t taken = 0;
        int32_t back;
        for (back = 0; back < window && index - back >= 0; ++back) {
            total += series[index - back];
            taken += 1;
        }
        output[index] = (taken > 0) ? (int32_t)(total / taken) : 0;
    }
    return count;
}

__attribute__((noinline)) int32_t
exponential_moving_average(const int32_t *series, int32_t count, int32_t alpha) {
    int32_t average;
    int32_t index;
    if (series == 0 || count < 1 || count > SERIES_MAX || alpha < 0 ||
        alpha > 65536) {
        return 0;
    }
    average = series[0];
    for (index = 1; index < count; ++index) {
        int32_t difference = series[index] - average;
        average += stat_mul_q16(alpha, difference);
    }
    return average;
}

__attribute__((noinline)) int32_t
population_variance(const int32_t *series, int32_t count) {
    int64_t total = 0;
    int64_t squares = 0;
    int32_t mean;
    int32_t index;
    if (series == 0 || count < 1 || count > SERIES_MAX) {
        return 0;
    }
    for (index = 0; index < count; ++index) {
        total += series[index];
    }
    mean = (int32_t)(total / count);
    for (index = 0; index < count; ++index) {
        int64_t deviation = (int64_t)series[index] - (int64_t)mean;
        squares += (deviation * deviation) >> 16;
    }
    return (int32_t)(squares / count);
}

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 -O2

2/3
exponential_moving_average pass 55 lines
// glaurung: exponential_moving_average @ 0x1370
int32_t exponential_moving_average(const int32_t * arg0, int32_t arg1, int32_t arg2) {
    int index;
    int average;
    int difference;
    long ret;
    long var10;
    int var16;
    int var23;
    long var26;
    long var27;
    long var28;
    long var3;
    long var5;
    long var8;
    ret = 0;
    if (((unsigned long)((unsigned long)((unsigned int)(arg2))) <= (unsigned long)(0x10000))) {
        ret = 0;
        if ((arg0 == 0)) {
            return ret;
        }
        ret = 0;
        if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 17)))) < (unsigned long)(0xfffffff0))) {
            return ret;
        }
        ret = (unsigned long)((unsigned int)(*(int *)(((long)arg0))));
        if (((unsigned long)((unsigned long)((unsigned int)(arg1))) < (unsigned long)(2))) {
            return ret;
        }
        var3 = (unsigned long)((unsigned int)(arg2));
        var5 = ((unsigned long)((unsigned int)(arg1)) - 1);
        if (((unsigned long)((unsigned int)(arg1)) != 2)) {
            var8 = (-(var5 & -2));
            index = 1;
            var10 = ret;
            do {
                var16 = ((long)((int)(var10)) + ((unsigned long)((((long)((int)(*(int *)(((long)arg0 + index * 4)))) - (long)((int)(var10))) * var3)) >> 16));
                var23 = ((long)((int)(var16)) + ((unsigned long)((((long)((int)(*(int *)(((long)arg0 + index * 4 + 0x4)))) - (long)((int)(var16))) * var3)) >> 16));
                var26 = ((var8 + (unsigned long)((unsigned int)(index))) + 2);
                index = (index + 2);
                var10 = (unsigned long)((unsigned int)(var23));
                var27 = (unsigned long)((unsigned int)(var23));
                var28 = (unsigned long)((unsigned int)(index));
            } while ((var26 != 1));
        } else {
            var27 = ret;
            var28 = 1;
        }
        ret = var27;
        if (((unsigned long)((unsigned char)((var5 & 1))) != 0)) {
            ret = (unsigned long)((unsigned int)(((long)((int)(var27)) + ((unsigned long)((((long)((int)(*(int *)(((long)arg0 + var28 * 4)))) - (long)((int)(var27))) * var3)) >> 16))));
        }
    }
    return ret;
}
population_variance pass 232 lines
// glaurung: population_variance @ 0x1430
int32_t population_variance(const int32_t * arg0, int32_t arg1) {
    long total;
    int index;
    long squares;
    long deviation;
    long ret;
    long t110;
    long t113;
    long t330;
    long t331;
    long t332;
    long t333;
    long t334;
    long t335;
    long t336;
    long t351;
    long t352;
    long t353;
    long t354;
    long t355;
    long t356;
    int var106;
    int var107;
    long var11;
    int var119;
    int var12;
    int var120;
    int var124;
    int var125;
    int var13;
    int var142;
    int var143;
    long var164;
    long var165;
    int var17;
    long var170;
    long var177;
    int var18;
    long var183;
    long var187;
    long var192;
    long var193;
    long var196;
    long var198;
    long var2;
    long var201;
    long var203;
    long var208;
    long var213;
    long var218;
    long var222;
    long var224;
    long var227;
    int var30;
    int var31;
    int var32;
    int var33;
    int var34;
    int var35;
    int var47;
    int var48;
    int var52;
    int var53;
    long var7;
    int var70;
    int var71;
    long var8;
    int var83;
    int var84;
    int var88;
    int var89;
    ret = 0;
    if ((arg0 == 0)) {
        return ret;
    }
    if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 17)))) < (unsigned long)(0xfffffff0))) {
        return ret;
    }
    var2 = (unsigned long)((unsigned int)(arg1));
    if (((unsigned long)((unsigned long)((unsigned int)(arg1))) < (unsigned long)(2))) {
        var7 = 0;
        var8 = 0;
        goto L_1540;
    }
    var11 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var2)) & -2)));
    var12 = *(int *)(((long)arg0));
    var13 = *(int *)(((long)arg0 + 0x4));
    var17 = 0;
    var18 = 0;
    var30 = var12;
    var31 = (-(var12 < 0));
    var32 = var13;
    var33 = (-(var13 < 0));
    if ((var11 != 2)) {
        var34 = *(int *)(((long)arg0 + 0x8));
        var35 = *(int *)(((long)arg0 + 0xc));
        t110 = (((unsigned long)((unsigned int)(var31)) | (unsigned long)((unsigned int)(var30))) + ((-(var34 < var17)) | (unsigned long)((unsigned int)(var34))));
        var30 = (unsigned int)(t110);
        var31 = (((unsigned long)(t110) >> 32) & 0xffffffff);
        t113 = (((unsigned long)((unsigned int)(var33)) | (unsigned long)((unsigned int)(var32))) + ((-(var35 < var18)) | (unsigned long)((unsigned int)(var35))));
        var32 = (unsigned int)(t113);
        var33 = (((unsigned long)(t113) >> 32) & 0xffffffff);
        if (((unsigned long)((unsigned int)(var11)) != 4)) {
            var47 = *(int *)(((long)arg0 + 0x10));
            var48 = *(int *)(((long)arg0 + 0x14));
            var52 = 0;
            var53 = 0;
            t330 = (((unsigned long)((unsigned int)(var31)) | (unsigned long)((unsigned int)(var30))) + ((-(var47 < 0)) | (unsigned long)((unsigned int)(var47))));
            var30 = (unsigned int)(t330);
            var31 = (((unsigned long)(t330) >> 32) & 0xffffffff);
            t351 = (((unsigned long)((unsigned int)(var33)) | (unsigned long)((unsigned int)(var32))) + ((-(var48 < 0)) | (unsigned long)((unsigned int)(var48))));
            var32 = (unsigned int)(t351);
            var33 = (((unsigned long)(t351) >> 32) & 0xffffffff);
            if (((unsigned long)((unsigned int)(var11)) != 6)) {
                var70 = *(int *)(((long)arg0 + 0x18));
                var71 = *(int *)(((long)arg0 + 0x1c));
                t331 = (((unsigned long)((unsigned int)(var31)) | (unsigned long)((unsigned int)(var30))) + ((-(var70 < var52)) | (unsigned long)((unsigned int)(var70))));
                var30 = (unsigned int)(t331);
                var31 = (((unsigned long)(t331) >> 32) & 0xffffffff);
                t352 = (((unsigned long)((unsigned int)(var33)) | (unsigned long)((unsigned int)(var32))) + ((-(var71 < var53)) | (unsigned long)((unsigned int)(var71))));
                var32 = (unsigned int)(t352);
                var33 = (((unsigned long)(t352) >> 32) & 0xffffffff);
                if (((unsigned long)((unsigned int)(var11)) != 8)) {
                    var83 = *(int *)(((long)arg0 + 0x20));
                    var84 = *(int *)(((long)arg0 + 0x24));
                    var88 = 0;
                    var89 = 0;
                    t332 = (((unsigned long)((unsigned int)(var31)) | (unsigned long)((unsigned int)(var30))) + ((-(var83 < 0)) | (unsigned long)((unsigned int)(var83))));
                    var30 = (unsigned int)(t332);
                    var31 = (((unsigned long)(t332) >> 32) & 0xffffffff);
                    t353 = (((unsigned long)((unsigned int)(var33)) | (unsigned long)((unsigned int)(var32))) + ((-(var84 < 0)) | (unsigned long)((unsigned int)(var84))));
                    var32 = (unsigned int)(t353);
                    var33 = (((unsigned long)(t353) >> 32) & 0xffffffff);
                    if (((unsigned long)((unsigned int)(var11)) != 10)) {
                        var106 = *(int *)(((long)arg0 + 0x28));
                        var107 = *(int *)(((long)arg0 + 0x2c));
                        t333 = (((unsigned long)((unsigned int)(var31)) | (unsigned long)((unsigned int)(var30))) + ((-(var106 < var88)) | (unsigned long)((unsigned int)(var106))));
                        var30 = (unsigned int)(t333);
                        var31 = (((unsigned long)(t333) >> 32) & 0xffffffff);
                        t354 = (((unsigned long)((unsigned int)(var33)) | (unsigned long)((unsigned int)(var32))) + ((-(var107 < var89)) | (unsigned long)((unsigned int)(var107))));
                        var32 = (unsigned int)(t354);
                        var33 = (((unsigned long)(t354) >> 32) & 0xffffffff);
                        if (((unsigned long)((unsigned int)(var11)) != 12)) {
                            var119 = *(int *)(((long)arg0 + 0x30));
                            var120 = *(int *)(((long)arg0 + 0x34));
                            var124 = 0;
                            var125 = 0;
                            t334 = (((unsigned long)((unsigned int)(var31)) | (unsigned long)((unsigned int)(var30))) + ((-(var119 < 0)) | (unsigned long)((unsigned int)(var119))));
                            var30 = (unsigned int)(t334);
                            var31 = (((unsigned long)(t334) >> 32) & 0xffffffff);
                            t355 = (((unsigned long)((unsigned int)(var33)) | (unsigned long)((unsigned int)(var32))) + ((-(var120 < 0)) | (unsigned long)((unsigned int)(var120))));
                            var32 = (unsigned int)(t355);
                            var33 = (((unsigned long)(t355) >> 32) & 0xffffffff);
                            if (((unsigned long)((unsigned int)(var11)) != 14)) {
                                var142 = *(int *)(((long)arg0 + 0x38));
                                var143 = *(int *)(((long)arg0 + 0x3c));
                                t335 = (((unsigned long)((unsigned int)(var31)) | (unsigned long)((unsigned int)(var30))) + ((-(var142 < var124)) | (unsigned long)((unsigned int)(var142))));
                                var30 = (unsigned int)(t335);
                                var31 = (((unsigned long)(t335) >> 32) & 0xffffffff);
                                t356 = (((unsigned long)((unsigned int)(var33)) | (unsigned long)((unsigned int)(var32))) + ((-(var143 < var125)) | (unsigned long)((unsigned int)(var143))));
                                var32 = (unsigned int)(t356);
                                var33 = (((unsigned long)(t356) >> 32) & 0xffffffff);
                            }
                        }
                    }
                }
            }
        }
    }
    t336 = (((unsigned long)((unsigned int)(var33)) | (unsigned long)((unsigned int)(var32))) + ((unsigned long)((unsigned int)(var31)) | (unsigned long)((unsigned int)(var30))));
    var164 = ((((unsigned long)(t336) >> 32) & 0xffffffff) | (unsigned int)(t336));
    var7 = var164;
    var8 = var11;
    var165 = var164;
    if ((var11 == var2)) {
        goto L_1550;
    }
    L_1540: ;
    total = (var7 + (long)((int)(*(int *)(((long)arg0 + var8 * 4)))));
    index = (var8 + 1);
    var7 = total;
    var8 = (unsigned long)((unsigned int)(index));
    var165 = total;
    if ((var2 != index)) {
        goto L_1540;
    }
    L_1550: ;
    var170 = (long)(arg1);
    if ((((unsigned long)((var165 | (long)(arg1))) >> 32) != 0)) {
        var177 = ((long)((((__int128)(long)(((long)(var165) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(var165)) / (long)(var170)));
        goto L_156a;
    }
    var177 = ((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)(var165)) / (unsigned int)(arg1))));
    L_156a: ;
    var183 = (long)((int)(var177));
    var187 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var2)) & 3)));
    if (((unsigned long)((var2 - 1)) < (unsigned long)(3))) {
        var192 = 0;
        var193 = 0;
        goto L_15e4;
    }
    var196 = (unsigned long)((unsigned int)((var2 & -4)));
    var198 = 0;
    var201 = 0;
    do {
        var203 = ((long)((int)(*(int *)(((long)arg0 + var198 * 4)))) - var183);
        var208 = ((long)((int)(*(int *)(((long)arg0 + var198 * 4 + 0x4)))) - var183);
        var213 = ((long)((int)(*(int *)(((long)arg0 + var198 * 4 + 0x8)))) - var183);
        var218 = ((long)((int)(*(int *)(((long)arg0 + var198 * 4 + 0xc)))) - var183);
        var192 = (((unsigned long)((var218 * var218)) >> 16) + (((unsigned long)((var213 * var213)) >> 16) + (((unsigned long)((var208 * var208)) >> 16) + (((unsigned long)((var203 * var203)) >> 16) + var201))));
        var198 = (var198 + 4);
        var201 = var192;
        var193 = var198;
    } while ((var196 != var198));
    L_15e4: ;
    if ((var187 != 0)) {
        var222 = (long)(((long)arg0 + (var193 * 4)));
        var224 = 0;
        squares = var192;
        while ((var187 != var224)) {
            var227 = ((long)((int)(*(int *)((var222 + var224 * 4)))) - var183);
            squares = (squares + ((unsigned long)((var227 * var227)) >> 16));
            var224 = (var224 + 1);
            var192 = squares;
        }
    }
    if ((((unsigned long)((var192 | var170)) >> 32) == 0)) {
        return ((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)(var192)) / (unsigned int)(arg1))));
    }
    return ((long)((((__int128)(long)(((long)(var192) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(var192)) / (long)(var170)));
}
simple_moving_average fail 222 lines
// glaurung: simple_moving_average @ 0x1100
int32_t simple_moving_average(const int32_t * arg0, int32_t arg1, int32_t arg2, int32_t * arg3) {
    int index;
    int back;
    int taken;
    long total;
    long local_10;
    long local_18;
    long local_20;
    long local_28;
    long local_30;
    long ret;
    long t110;
    long t113;
    long t181;
    long t311;
    long t312;
    long t313;
    long t320;
    long t321;
    long var0;
    long var1;
    int var104;
    int var105;
    long var125;
    long var13;
    int var130;
    int var131;
    long var14;
    long var147;
    long var15;
    long var160;
    long var171;
    long var18;
    long var19;
    long var2;
    long var20;
    long var28;
    long var3;
    long var31;
    long var33;
    long var34;
    long var36;
    long var38;
    long var4;
    long var40;
    long var41;
    long var47;
    long var53;
    long var56;
    int var58;
    int var59;
    int var60;
    int var61;
    long var64;
    long var67;
    int var72;
    int var73;
    int var89;
    int var90;
    int var91;
    int var92;
    long var94;
    long var98;
    long var99;
    local_10 = var0;
    local_18 = var1;
    local_20 = var2;
    local_28 = var3;
    local_30 = var4;
    ret = 0xffffffff;
    if (((unsigned long)((unsigned long)((unsigned int)((arg2 - 17)))) < (unsigned long)(0xfffffff0))) {
        // x86-64 epilogue: tear down frame
        return ret;
    }
    if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        // x86-64 epilogue: tear down frame
        return ret;
    }
    if ((arg0 == 0)) {
        // x86-64 epilogue: tear down frame
        return ret;
    }
    if ((arg3 == 0)) {
        // x86-64 epilogue: tear down frame
        return ret;
    }
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        return 0;
    } else {
        var13 = (unsigned long)((unsigned int)(arg2));
        var14 = (unsigned long)((unsigned int)(arg1));
        var15 = 1;
        var18 = ((((unsigned long)(2) <= (unsigned long)((unsigned long)((unsigned int)(arg2)))) ? (unsigned long)((unsigned int)(arg2)) : 1) - 1);
        var19 = -2;
        var20 = -1;
        index = 0;
        do {
            var28 = ((var18 == 0) ? var15 : ((((unsigned long)(index) < (unsigned long)(var18)) ? (unsigned long)((unsigned int)(index)) : var18) + 1));
            var31 = ((var18 == 0) ? var18 : (((unsigned long)(index) < (unsigned long)(var18)) ? (unsigned long)((unsigned int)(index)) : var18));
            if ((((unsigned long)(var28) < (unsigned long)(2)) || ((unsigned long)((unsigned long)((unsigned int)(index))) < (unsigned long)((unsigned long)((unsigned int)(var31)))))) {
                var33 = 0;
                var34 = (unsigned long)((unsigned int)(index));
                var36 = 0;
                L_12c8: ;
                var38 = (var20 - var33);
                var40 = var36;
                var41 = var33;
                while (1) {
                    var40 = ((long)((int)(arg0[(unsigned long)((unsigned int)(var34))])) + var40);
                    back = (var41 + 1);
                    taken = back;
                    var47 = var40;
                    if (((unsigned long)(var13) <= (unsigned long)(back))) {
                        break;
                    }
                    var34 = var38;
                    var38 = (var38 - 1);
                    t181 = ((unsigned long)(index) <= (unsigned long)(var41));
                    var41 = (unsigned long)((unsigned int)(back));
                    taken = back;
                    var47 = var40;
                    if ((t181 != 0)) {
                        break;
                    }
                }
            } else {
                var33 = 0;
                var36 = 0;
                var34 = (unsigned long)((unsigned int)(index));
                if ((((unsigned long)(var31) >> 32) != 0)) {
                    goto L_12c8;
                } else {
                    var33 = (var28 & 0x7ffffffffffffffe);
                    var53 = (var33 - 2);
                    var56 = (((unsigned long)(var53) >> 1) + 1);
                    if ((var53 == 0)) {
                        var58 = 0;
                        var59 = 0;
                        var60 = 0;
                        var61 = 0;
                        var64 = 0;
                        if (((unsigned long)((unsigned char)((var56 & 1))) != 0)) {
                            L_1271: ;
                            var67 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(index)) - var64)));
                            var72 = *(int *)(((long)arg0 + var67 * 4));
                            var73 = *(int *)(((long)arg0 + var67 * 4 - 0x4));
                            t312 = (((unsigned long)((unsigned int)(var59)) | (unsigned long)((unsigned int)(var58))) + ((-(var72 < 0)) | (unsigned long)((unsigned int)(var72))));
                            var89 = (unsigned int)(t312);
                            var90 = (((unsigned long)(t312) >> 32) & 0xffffffff);
                            t321 = (((unsigned long)((unsigned int)(var61)) | (unsigned long)((unsigned int)(var60))) + ((-(var73 < 0)) | (unsigned long)((unsigned int)(var73))));
                            var91 = (unsigned int)(t321);
                            var92 = (((unsigned long)(t321) >> 32) & 0xffffffff);
                        } else {
                            var89 = var58;
                            var90 = var59;
                            var91 = var60;
                            var92 = var61;
                        }
                    } else {
                        var94 = (var56 & -2);
                        var58 = 0;
                        var59 = 0;
                        var60 = 0;
                        var61 = 0;
                        var98 = 0;
                        do {
                            var99 = (unsigned long)((unsigned int)((index + var98)));
                            var104 = *(int *)(((long)arg0 + var99 * 4));
                            var105 = *(int *)(((long)arg0 + var99 * 4 - 0x4));
                            t110 = (((-(var104 < 0)) | (unsigned long)((unsigned int)(var104))) + ((unsigned long)((unsigned int)(var59)) | (unsigned long)((unsigned int)(var58))));
                            t113 = (((-(var105 < 0)) | (unsigned long)((unsigned int)(var105))) + ((unsigned long)((unsigned int)(var61)) | (unsigned long)((unsigned int)(var60))));
                            var125 = (unsigned long)((unsigned int)((var19 + var98)));
                            var130 = *(int *)(((long)arg0 + var125 * 4));
                            var131 = *(int *)(((long)arg0 + var125 * 4 - 0x4));
                            t311 = (((-(var130 < 0)) | (unsigned long)((unsigned int)(var130))) + ((((unsigned long)(t110) >> 32) & 0xffffffff) | (unsigned int)(t110)));
                            var58 = (unsigned int)(t311);
                            var59 = (((unsigned long)(t311) >> 32) & 0xffffffff);
                            t320 = (((-(var131 < 0)) | (unsigned long)((unsigned int)(var131))) + ((((unsigned long)(t113) >> 32) & 0xffffffff) | (unsigned int)(t113)));
                            var60 = (unsigned int)(t320);
                            var61 = (((unsigned long)(t320) >> 32) & 0xffffffff);
                            ret = ((unsigned long)((unsigned int)(var59)) | (unsigned int)(t311));
                            var147 = (var98 - 4);
                            var94 = (var94 - 2);
                            var98 = var147;
                        } while ((var94 != 0));
                        var64 = (-var147);
                        var89 = var58;
                        var90 = var59;
                        var91 = var60;
                        var92 = var61;
                        if (((unsigned long)((unsigned char)((var56 & 1))) == 0)) {
                            goto L_1291;
                        }
                        goto L_1271;
                    }
                    L_1291: ;
                    t313 = (((unsigned long)((unsigned int)(var92)) | (unsigned long)((unsigned int)(var91))) + ((unsigned long)((unsigned int)(var90)) | (unsigned long)((unsigned int)(var89))));
                    var36 = ((((unsigned long)(t313) >> 32) & 0xffffffff) | (unsigned int)(t313));
                    var15 = 1;
                    taken = var33;
                    var47 = var36;
                    if ((var28 != var33)) {
                        var34 = ((unsigned long)((unsigned int)(index)) - var33);
                        goto L_12c8;
                    }
                }
            }
            if (((unsigned long)((unsigned int)(taken)) == 0)) {
                var160 = 0;
            } else {
                var160 = ((((unsigned long)(var47) >> 32) == 0) ? ((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)(var47)) / (unsigned int)((unsigned long)((unsigned int)(taken)))))) : ((long)((((__int128)(long)(((long)(var47) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(var47)) / (long)((unsigned long)((unsigned int)(taken))))));
            }
            *(int *)(((long)arg3 + index * 4)) = var160;
            var171 = ((unsigned long)((unsigned int)(index)) + 1);
            var19 = (var19 + 1);
            var20 = (var20 + 1);
            index = var171;
        } while ((var171 != var14));
        return (unsigned int)(arg1);
    }
}

clang -O0

3/3
exponential_moving_average pass 39 lines
// glaurung: exponential_moving_average @ 0x1240
int32_t exponential_moving_average(const int32_t * arg0, int32_t arg1, int32_t arg2) {
    extern int stat_mul_q16(int, int);
    int average;
    int index;
    int difference;
    int local_4;
    int var8;
    // x86-64 prologue: save rbp, frame 48 bytes
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((long)(arg1) < 1)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((long)(arg2) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 0x10000) | ((long)(arg2) < 0x10000)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    average = *(int *)((long)arg0);
    for (index = 1; (index < arg1); index++) {
        difference = ((unsigned int)(arg0[(long)(index)]) - average);
        var8 = stat_mul_q16((unsigned long)((unsigned int)(arg2)), (unsigned long)((unsigned int)(difference)));
        average = (var8 + average);
    }
    local_4 = average;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
population_variance pass 35 lines
// glaurung: population_variance @ 0x1310
int32_t population_variance(const int32_t * arg0, int32_t arg1) {
    long total;
    long squares;
    int index;
    int mean;
    long deviation;
    int local_4;
    // x86-64 prologue: save rbp
    total = 0;
    squares = 0;
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((long)(arg1) < 1)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    for (index = 0; (index < arg1); index++) {
        total = ((long)((int)(arg0[(long)(index)])) + total);
    }
    mean = ((long)((((__int128)(long)(((long)(total) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(total)) / (long)((long)(arg1))));
    for (index = 0; (index < arg1); index++) {
        deviation = ((long)((int)(arg0[(long)(index)])) - (long)(mean));
        squares = (((long)((deviation * deviation)) >> 16) + squares);
    }
    local_4 = ((long)((((__int128)(long)(((long)(squares) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(squares)) / (long)((long)(arg1))));
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
simple_moving_average pass 60 lines
// glaurung: simple_moving_average @ 0x1100
int32_t simple_moving_average(const int32_t * arg0, int32_t arg1, int32_t arg2, int32_t * arg3) {
    int index;
    long total;
    int taken;
    int back;
    signed char local_39;
    int local_4;
    int local_40;
    if ((arg0 != 0)) {
        if ((arg3 != 0)) {
            if ((0 <= (long)(arg1))) {
                if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) != 0)) {
                    if ((1 <= (long)(arg2))) {
                        if ((((unsigned long)((unsigned int)(arg2)) == 16) | ((long)(arg2) < 16))) {
                            goto L_115c;
                        }
                    }
                }
            }
        }
    }
    local_4 = -1;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
    L_115c: ;
    index = 0;
    L_1163: ;
    if ((arg1 <= index)) {
        goto L_122a;
    }
    total = 0;
    taken = 0;
    back = 0;
    L_1185: ;
    local_39 = 0;
    if ((back < arg2)) {
        local_39 = (0 <= (long)((int)(((unsigned long)((unsigned int)(index)) - back))));
    }
    if (((unsigned long)((unsigned char)((local_39 & 1))) != 0)) {
        total = ((long)((int)(arg0[(long)((int)(((unsigned long)((unsigned int)(index)) - back)))])) + total);
        taken = ((unsigned int)(taken) + 1);
        back = ((unsigned int)(back) + 1);
        goto L_1185;
    }
    if (((((unsigned long)((unsigned int)(taken)) == 0) | ((long)(taken) < 0)) == 0)) {
        local_40 = ((long)((((__int128)(long)(((long)(total) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(total)) / (long)((long)(taken))));
        goto L_120e;
    }
    local_40 = 0;
    goto L_120e;
    L_120e: ;
    arg3[(long)(index)] = local_40;
    index = ((unsigned int)(index) + 1);
    goto L_1163;
    L_122a: ;
    local_4 = arg1;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}

gcc -O0

3/3
exponential_moving_average pass 37 lines
// glaurung: exponential_moving_average @ 0x1208
int32_t exponential_moving_average(const int32_t * arg0, int32_t arg1, int32_t arg2) {
    extern int stat_mul_q16(int, int);
    int average;
    int index;
    int difference;
    int var13;
    // x86-64 prologue: save rbp, frame 32 bytes
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((long)(arg2) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 0x10000) | ((long)(arg2) < 0x10000)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    average = *(int *)((long)arg0);
    for (index = 1; (index < arg1); index++) {
        difference = ((unsigned int)(arg0[(long)(index)]) - average);
        var13 = stat_mul_q16((unsigned long)((unsigned int)(arg2)), (unsigned long)((unsigned int)(difference)));
        average = (average + var13);
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(average);
}
population_variance pass 33 lines
// glaurung: population_variance @ 0x1298
int32_t population_variance(const int32_t * arg0, int32_t arg1) {
    long total;
    long squares;
    int index;
    int mean;
    long deviation;
    // x86-64 prologue: save rbp
    total = 0;
    squares = 0;
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0;
    }
    for (index = 0; (index < arg1); index++) {
        total = (total + (long)((int)(arg0[(long)(index)])));
    }
    mean = ((long)((((__int128)(long)(((long)(total) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(total)) / (long)((long)((int)((unsigned long)((unsigned int)(arg1)))))));
    for (index = 0; (index < arg1); index++) {
        deviation = ((long)((int)(arg0[(long)(index)])) - (long)(mean));
        squares = (squares + ((long)((deviation * deviation)) >> 16));
    }
    // x86-64 epilogue: restore rbp
    return ((long)((((__int128)(long)(((long)(squares) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(squares)) / (long)((long)((int)((unsigned long)((unsigned int)(arg1)))))));
}
simple_moving_average pass 50 lines
// glaurung: simple_moving_average @ 0x111c
int32_t simple_moving_average(const int32_t * arg0, int32_t arg1, int32_t arg2, int32_t * arg3) {
    int index;
    long total;
    int taken;
    int back;
    // x86-64 prologue: save rbp
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if ((arg3 == 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)) == 16) | ((long)(arg1) < 16)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if ((((unsigned long)((unsigned int)(arg2)) == 0) | ((long)(arg2) < 0))) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 16) | ((long)(arg2) < 16)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    index = 0;
    while ((index < arg1)) {
        total = 0;
        taken = 0;
        back = 0;
        while ((back < arg2)) {
            if (((long)((int)(((unsigned long)((unsigned int)(index)) - back))) < 0)) {
                break;
            }
            total = (total + (long)((int)(arg0[(long)((int)(((unsigned long)((unsigned int)(index)) - back)))])));
            taken = (taken + 1);
            back = (back + 1);
        }
        arg3[(long)(index)] = ((((unsigned long)((unsigned int)(taken)) == 0) | ((long)(taken) < 0)) ? 0 : (unsigned long)((unsigned int)(((long)((((__int128)(long)(((long)(total) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(total)) / (long)((long)((int)((unsigned long)((unsigned int)(taken))))))))));
        index = (index + 1);
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(arg1);
}

gcc -O2

3/3
exponential_moving_average pass 37 lines
// glaurung: exponential_moving_average @ 0x1190
int32_t exponential_moving_average(const int32_t * arg0, int32_t arg1, int32_t arg2) {
    int average;
    int difference;
    int index;
    long var3;
    long var5;
    long var6;
    long var7;
    long var9;
    var3 = 0;
    if (((unsigned long)(15) < (unsigned long)((unsigned long)((unsigned int)((arg1 - 1)))))) {
        return (unsigned int)(var3);
    }
    var3 = 0;
    if ((arg0 == 0)) {
        return (unsigned int)(var3);
    }
    var3 = 0;
    if (((unsigned long)(0x10000) < (unsigned long)((unsigned long)((unsigned int)(arg2))))) {
        return (unsigned int)(var3);
    }
    var3 = (unsigned long)((unsigned int)(*(int *)(((long)arg0))));
    if (((unsigned long)((unsigned int)(arg1)) == 1)) {
        return (unsigned int)(var3);
    }
    var5 = (long)(arg2);
    var6 = (long)((arg0 + 1));
    var7 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 2))) * 4)) + 8));
    average = var3;
    do {
        var9 = (unsigned long)((unsigned int)(*(int *)((var6))));
        var6 = (var6 + 4);
        average = (unsigned long)((unsigned int)((average + ((long)(((long)((int)((var9 - average))) * var5)) >> 16))));
    } while ((var7 != var6));
    return (unsigned int)(average);
}
population_variance pass 41 lines
// glaurung: population_variance @ 0x11f0
int32_t population_variance(const int32_t * arg0, int32_t arg1) {
    long total;
    long squares;
    long deviation;
    int index;
    long var1;
    long var10;
    long var13;
    long var16;
    long var2;
    long var20;
    long var5;
    long var9;
    var1 = (long)arg0;
    var2 = (unsigned long)((unsigned int)(arg1));
    if (((unsigned long)(15) < (unsigned long)((unsigned long)((unsigned int)((arg1 - 1)))))) {
        return 0;
    }
    if ((arg0 == 0)) {
        return 0;
    }
    var5 = 0;
    total = 0;
    do {
        var9 = (long)((int)(*(int *)((var1 + var5 * 4))));
        var5 = (var5 + 1);
        total = (total + var9);
    } while (((((unsigned int)(var2) == (unsigned int)(var5)) | ((long)((int)(var2)) < (long)((int)(var5)))) == 0));
    var10 = (long)((int)(var2));
    var13 = 0;
    var16 = (long)((int)(((long)((((__int128)(long)(((long)(total) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(total)) / (long)((long)((int)(var2)))))));
    squares = 0;
    do {
        var20 = (long)((int)(*(int *)((var1 + var13 * 4))));
        var13 = (var13 + 1);
        deviation = (var20 - var16);
        squares = (squares + ((long)((deviation * deviation)) >> 16));
    } while (((((unsigned int)(var2) == (unsigned int)(var13)) | ((long)((int)(var2)) < (long)((int)(var13)))) == 0));
    return ((long)((((__int128)(long)(((long)(squares) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(squares)) / (long)(var10)));
}
simple_moving_average pass 65 lines
// glaurung: simple_moving_average @ 0x1100
int32_t simple_moving_average(const int32_t * arg0, int32_t arg1, int32_t arg2, int32_t * arg3) {
    int index;
    long total;
    int back;
    long var0;
    long var1;
    long var13;
    long var14;
    int var18;
    long var2;
    long var3;
    long var6;
    long var8;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    var0 = (long)arg3;
    if ((arg3 == 0)) {
        return 0xffffffff;
    }
    var1 = (unsigned long)((unsigned int)((arg2 - 1)));
    var2 = (unsigned long)((unsigned int)(arg2));
    if (((unsigned long)(15) < (unsigned long)((unsigned long)((unsigned int)(var1))))) {
        return 0xffffffff;
    }
    var3 = (unsigned long)((unsigned int)(arg1));
    if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return 0xffffffff;
    }
    index = 0;
    var6 = (unsigned long)((unsigned int)((arg1 - 1)));
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        // x86-64 epilogue: tear down frame
        return (unsigned int)(var3);
    }
    L_1130: ;
    var8 = (unsigned long)((unsigned int)(index));
    var13 = 0;
    var14 = 0;
    goto L_1148;
    L_1140: ;
    var8 = (var8 - 1);
    var13 = total;
    var14 = (unsigned long)((unsigned int)(back));
    if (((long)((int)(var8)) < 0)) {
        goto L_1157;
    }
    L_1148: ;
    var18 = (var14 + 1);
    back = (unsigned long)((unsigned int)(var18));
    total = (var13 + (long)((int)(*(int *)(((long)arg0 + var8 * 4)))));
    if (((((unsigned int)(var2) == (unsigned int)(var18)) | ((long)((int)(var2)) < (long)((int)(var18)))) == 0)) {
        goto L_1140;
    }
    L_1157: ;
    *(int *)((var0 + index * 4)) = ((long)((((__int128)(long)(((long)(total) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(total)) / (long)((long)(back))));
    var1 = ((unsigned long)((unsigned int)(index)) + 1);
    if ((var6 == index)) {
        // x86-64 epilogue: tear down frame
        return (unsigned int)(var3);
    }
    index = var1;
    goto L_1130;
}

← 213 fixtures