Fixture 12

loop rotation

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

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

Loop SHAPE fixture. 03_loop_shapes.c covers what a loop computes; this file covers how the compiler lays one out, because the two disagree across toolchains and our structurer was built against only one of them.

gcc -O0 emits a bottom-tested loop: fall into the body, test at the bottom, conditional branch back. clang -O0 emits a ROTATED loop: test at the top with a conditional branch OUT, and an unconditional jump back at the bottom. We structure the first correctly and the second wrongly — loops.c:factorial at clang -O0 came out as

while ((n <= 1)) { ...; n = n - 1; goto L; } return f; L: ;

with the machine's EXIT test used as the CONTINUE condition and the back-edge jumping to a label placed after the return, so the body can never repeat. The function returns the wrong value for every input.

Every function here returns a value that differs if the loop runs the wrong number of times, exits on the wrong polarity, or fails to iterate at all — a decompiler that drops the back-edge returns the first iteration's value and is caught. All parameters and returns are integer; deterministic; terminating; every trip count is masked so no verdict depends on machine speed. No libc.

Targets review #31 (clang rotated loops), and gives #13 (interval/SESE structurer) something to be proven against.

tests/decompiler_fixtures/src/12_loop_rotation.c source
/* 12_loop_rotation.c
 *
 * Loop SHAPE fixture. `03_loop_shapes.c` covers what a loop computes; this file
 * covers how the compiler lays one out, because the two disagree across
 * toolchains and our structurer was built against only one of them.
 *
 * gcc -O0 emits a bottom-tested loop: fall into the body, test at the bottom,
 * conditional branch back. clang -O0 emits a ROTATED loop: test at the top with
 * a conditional branch OUT, and an unconditional jump back at the bottom. We
 * structure the first correctly and the second wrongly — `loops.c:factorial` at
 * clang -O0 came out as
 *
 *     while ((n <= 1)) { ...; n = n - 1; goto L; }
 *     return f;
 *     L: ;
 *
 * with the machine's EXIT test used as the CONTINUE condition and the back-edge
 * jumping to a label placed after the return, so the body can never repeat. The
 * function returns the wrong value for every input.
 *
 * Every function here returns a value that differs if the loop runs the wrong
 * number of times, exits on the wrong polarity, or fails to iterate at all — a
 * decompiler that drops the back-edge returns the first iteration's value and is
 * caught. All parameters and returns are integer; deterministic; terminating;
 * every trip count is masked so no verdict depends on machine speed. No libc.
 *
 * Targets review #31 (clang rotated loops), and gives #13 (interval/SESE
 * structurer) something to be proven against.
 */
#include <stdint.h>

/* The exact shape that broke: a top-tested `while` whose body decrements. If the
 * back-edge is lost this returns 1 (the initial value) instead of n!. */
long factorial_while(int n) {
    long f = 1;
    int k = n & 15;                 /* bounded */
    while (k > 1) {
        f *= k;
        k--;
    }
    return f;
}

/* Same shape, opposite polarity: the test that continues is `<`, so an inverted
 * condition runs zero times instead of n. */
long count_up(int n) {
    long acc = 0;
    int i = 0;
    int lim = n & 15;
    while (i < lim) {
        acc += i * 3 + 1;
        i++;
    }
    return acc;
}

/* A `for` with the increment in the header — clang rotates this too, and the
 * increment must stay on the back-edge rather than migrating into the body. */
long for_accumulate(int n) {
    long acc = 0;
    for (int i = 0; i < (n & 15); i++) {
        acc = acc * 2 + i;
    }
    return acc;
}

/* A do-while: bottom-tested in BOTH compilers, so this is the control. If it
 * regresses while the others improve, the fix broke the shape that worked. */
long do_while_control(int n) {
    long acc = 0;
    int k = n & 15;
    do {
        acc += k;
        k--;
    } while (k > 0);
    return acc;
}

/* An early `return` out of a rotated loop: two exits, so the structurer cannot
 * assume the only way out is the loop test. */
/* HOIST TRAP — measured, do not "simplify" this loop's lowering.
 *
 * This function is one of exactly four the loop-header hoist fallback protects. The
 * verbose `while (1) { pre; if (!cond) break; }` form it decompiles to is NOT an
 * accident to be tidied away: hoisting the header above the loop lets constant
 * propagation substitute the initial value that dominates at the hoist position, which
 * freezes the loop-carried value and the loop stops making progress.
 *
 * Measured on branch `recover-ged-cells` (see docs/design/ged-recovery-measured-trade.md):
 * always-hoisting recovers 50.32 GED points, 46% of a regression — and breaks exactly
 * these four functions across six lanes:
 *     03_loop_shapes:gcc:O2:while_prefix
 *     12_loop_rotation:gcc:O2:find_first_set
 *     13_loop_early_exit:{clang,gcc}:O2:classify_run
 *     14_flag_effects:{clang,gcc}:O0:countdown
 * So the compact form is worth real score, and it is wrong. That is the trade.
 *
 * FOUR predicates have been tried and all four failed, each differently: a copy-chain
 * rule, a loop-invariance rule, a use-count rule, and a post-fold check requiring only a
 * nonempty read/write intersection (which passes `find_first_set`, whose body reassigns
 * its flag lower down while the frozen value sits inside the hoisted expression). If a
 * post-fold check is attempted again it must preserve EVERY original loop-carried
 * dependency, not one overlapping register.
 *
 * The real fix is typed value identity plus dominance, where "may this expression move
 * here" is a query rather than a guess — value-model-root-cause-and-plan.md Phase 2.
 */
int find_first_set(unsigned x) {
    for (int i = 0; i < 32; i++) {
        if ((x >> i) & 1u) {
            return i;
        }
    }
    return -1;
}

/* A `continue` inside a rotated loop: the back-edge is reached from two places,
 * which is where a goto-based lowering tends to duplicate or drop one. */
long skip_odd_sum(int n) {
    long acc = 0;
    int lim = n & 15;
    for (int i = 0; i < lim; i++) {
        if (i & 1) {
            continue;
        }
        acc += i;
    }
    return acc;
}

/* Nested rotated loops: the inner back-edge must not be confused with the
 * outer's. Returns a value sensitive to both trip counts. */
long nested_rotated(int a, int b) {
    long acc = 0;
    int la = a & 7, lb = b & 7;
    int i = 0;
    while (i < la) {
        int j = 0;
        while (j < lb) {
            acc = acc * 3 + (i ^ j);
            j++;
        }
        i++;
    }
    return acc;
}

/* A loop whose counter decrements by a NEGATIVE immediate — `add $-1` is what
 * clang emits, and reading that imm8 unsigned made the counter climb. Kept here
 * so the lifter fix has a differential test at the loop level too. */
long down_by_negative_imm(int n) {
    long acc = 0;
    int k = n & 15;
    while (k != 0) {
        acc = acc * 2 + k;
        k += -1;
    }
    return acc;
}

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

8/8
count_up pass 16 lines
// glaurung: count_up @ 0x1150
long count_up(int arg0) {
    long acc;
    int i;
    int lim;
    // x86-64 prologue: save rbp
    acc = 0;
    i = 0;
    lim = ((unsigned int)(arg0) & 15);
    while ((i < lim)) {
        acc = ((long)((int)(((i * 3) + 1))) + acc);
        i = ((unsigned int)(i) + 1);
    }
    // x86-64 epilogue: restore rbp
    return acc;
}
do_while_control pass 14 lines
// glaurung: do_while_control @ 0x11f0
long do_while_control(int arg0) {
    long acc;
    int k;
    // x86-64 prologue: save rbp
    acc = 0;
    k = ((unsigned int)(arg0) & 15);
    do {
        acc = ((long)(k) + acc);
        k = ((unsigned int)(k) - 1);
    } while (((((unsigned long)((unsigned int)(k)) == 0) | ((long)(k) < 0)) == 0));
    // x86-64 epilogue: restore rbp
    return acc;
}
down_by_negative_imm pass 14 lines
// glaurung: down_by_negative_imm @ 0x1380
long down_by_negative_imm(int arg0) {
    long acc;
    int k;
    // x86-64 prologue: save rbp
    acc = 0;
    k = ((unsigned int)(arg0) & 15);
    while (((unsigned long)((unsigned int)(k)) != 0)) {
        acc = ((acc << 1) + (long)(k));
        k = ((unsigned int)(k) - 1);
    }
    // x86-64 epilogue: restore rbp
    return acc;
}
factorial_while pass 14 lines
// glaurung: factorial_while @ 0x1100
long factorial_while(int arg0) {
    long f;
    int k;
    // x86-64 prologue: save rbp
    f = 1;
    k = ((unsigned int)(arg0) & 15);
    while (((((unsigned long)((unsigned int)(k)) == 1) | ((long)(k) < 1)) == 0)) {
        f = ((long)(k) * f);
        k = ((unsigned int)(k) - 1);
    }
    // x86-64 epilogue: restore rbp
    return f;
}
find_first_set pass 23 lines
// glaurung: find_first_set @ 0x1230
int find_first_set(unsigned int arg0) {
    int i;
    int local_4;
    i = 0;
    L_123e: ;
    if ((32 <= (long)(i))) {
        goto L_127a;
    }
    if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(arg0) >> ((unsigned long)((unsigned int)(i)) & 31)))) & 1))) != 0)) {
        local_4 = i;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    goto L_126c;
    L_126c: ;
    i = ((unsigned int)(i) + 1);
    goto L_123e;
    L_127a: ;
    local_4 = -1;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
for_accumulate pass 12 lines
// glaurung: for_accumulate @ 0x11a0
long for_accumulate(int arg0) {
    long acc;
    int i;
    // x86-64 prologue: save rbp
    acc = 0;
    for (i = 0; ((long)(i) < (long)((int)(((unsigned long)((unsigned int)(arg0)) & 15)))); i++) {
        acc = ((acc << 1) + (long)(i));
    }
    // x86-64 epilogue: restore rbp
    return acc;
}
nested_rotated pass 21 lines
// glaurung: nested_rotated @ 0x12f0
long nested_rotated(int arg0, int arg1) {
    long acc;
    int la;
    int lb;
    int i;
    int j;
    // x86-64 prologue: save rbp
    acc = 0;
    la = ((unsigned int)(arg0) & 7);
    lb = ((unsigned int)(arg1) & 7);
    i = 0;
    while ((i < la)) {
        for (j = 0; (j < lb); j++) {
            acc = ((acc * 3) + (long)((int)(((unsigned long)((unsigned int)(i)) ^ j))));
        }
        i = ((unsigned int)(i) + 1);
    }
    // x86-64 epilogue: restore rbp
    return acc;
}
skip_odd_sum pass 17 lines
// glaurung: skip_odd_sum @ 0x1290
long skip_odd_sum(int arg0) {
    long acc;
    int lim;
    int i;
    // x86-64 prologue: save rbp
    acc = 0;
    lim = ((unsigned int)(arg0) & 15);
    for (i = 0; (i < lim); i++) {
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) & 1))) == 0)) {
            acc = ((long)(i) + acc);
        } else {
        }
    }
    // x86-64 epilogue: restore rbp
    return acc;
}

clang -O2

8/8
count_up pass 16 lines
// glaurung: count_up @ 0x1130
long count_up(int arg0) {
    long acc;
    int i;
    int lim;
    int var0;
    long var3;
    long var7;
    var0 = (arg0 & 15);
    if (((unsigned long)((unsigned int)(var0)) == 0)) {
        return 0;
    }
    var3 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) - 1)));
    var7 = ((unsigned long)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) - 2))) * var3)) >> 1);
    return (((var7 + (var7 * 2)) + (var3 * 4)) + 1);
}
do_while_control pass 11 lines
// glaurung: do_while_control @ 0x1200
long do_while_control(int arg0) {
    int k;
    long acc;
    long var6;
    long var9;
    k = (unsigned long)((unsigned int)((arg0 & 15)));
    var6 = ((unsigned long)((unsigned int)(k)) != 0);
    var9 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(k)) - var6)));
    return (((((unsigned long)((unsigned int)(k)) - 1) * var9) + (unsigned long)((unsigned int)(k))) - ((unsigned long)(((unsigned long)((unsigned int)(((~var6) + k))) * var9)) >> 1));
}
down_by_negative_imm pass 61 lines
// glaurung: down_by_negative_imm @ 0x1450
long down_by_negative_imm(int arg0) {
    long acc;
    int k;
    long ret;
    long var1;
    long var12;
    long var16;
    long var18;
    long var20;
    long var23;
    long var24;
    long var5;
    long var7;
    long var8;
    if (((unsigned long)((unsigned char)((arg0 & 15))) == 0)) {
        goto L_1472;
    }
    var1 = (unsigned long)((unsigned int)((arg0 & 15)));
    var5 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var1)) & 7)));
    if (((unsigned long)(7) <= (unsigned long)((var1 - 1)))) {
        goto L_1475;
    }
    ret = 0;
    var7 = 0;
    var8 = var1;
    if ((var5 != 0)) {
        goto L_14bb;
    }
    L_1471: ;
    return ret;
    L_1472: ;
    return 0;
    L_1475: ;
    var12 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var1)) & -8)));
    var16 = (((var1 << 8) - var1) + 1793);
    var18 = 0;
    var8 = var1;
    do {
        var20 = (var18 << 8);
        var18 = ((var16 + var20) - 2040);
        var8 = (var8 - 8);
        var16 = (var16 - 2040);
        var12 = (var12 - 8);
    } while ((var12 != 0));
    ret = (var20 + var16);
    var7 = ret;
    if ((var5 == 0)) {
        goto L_1471;
    }
    L_14bb: ;
    var23 = (~var8);
    do {
        var24 = var7;
        var7 = (var8 + (var7 * 2));
        var23 = (var23 + 1);
        var5 = (var5 - 1);
        var8 = (var8 - 1);
    } while ((var5 != 0));
    return ((var24 + var24) - var23);
}
factorial_while pass 17 lines
// glaurung: factorial_while @ 0x1100
long factorial_while(int arg0) {
    int k;
    long f;
    long t20;
    if (((unsigned long)((unsigned char)((arg0 & 14))) == 0)) {
        return 1;
    }
    k = (unsigned long)((unsigned int)((arg0 & 15)));
    f = 1;
    do {
        f = (f * (unsigned long)((unsigned int)(k)));
        t20 = ((unsigned long)(k) <= (unsigned long)(2));
        k = (k - 1);
    } while ((t20 == 0));
    return f;
}
find_first_set pass 23 lines
// glaurung: find_first_set @ 0x1230
int find_first_set(unsigned int arg0) {
    int i;
    int var7;
    i = 0;
    do {
        if ((((unsigned long)(arg0) >> (i & 31)) & 1)) {
            return i;
        }
        if ((((unsigned long)(arg0) >> ((unsigned int)((unsigned char)(((unsigned long)((unsigned int)((i + 1))) & 255))) & 31)) & 1)) {
            return (unsigned int)((i + 1));
        }
        if ((((unsigned long)(arg0) >> ((unsigned int)((unsigned char)(((unsigned long)((unsigned int)((i + 2))) & 255))) & 31)) & 1)) {
            return (unsigned int)((i + 2));
        }
        if ((((unsigned long)(arg0) >> ((unsigned int)((unsigned char)(((unsigned long)((unsigned int)((i + 3))) & 255))) & 31)) & 1)) {
            return (unsigned int)((i + 3));
        }
        var7 = (i + 4);
        i = (unsigned long)((unsigned int)(var7));
    } while (((unsigned long)((unsigned int)(var7)) != 32));
    return 0xffffffff;
}
for_accumulate pass 63 lines
// glaurung: for_accumulate @ 0x1160
long for_accumulate(int arg0) {
    int i;
    long acc;
    long ret;
    int var0;
    long var1;
    long var10;
    long var14;
    long var15;
    long var19;
    long var2;
    long var21;
    long var24;
    long var25;
    long var6;
    var0 = (arg0 & 15);
    var1 = (unsigned long)((unsigned int)(var0));
    if (((unsigned long)((unsigned int)(var0)) == 0)) {
        goto L_1182;
    }
    var2 = (unsigned long)((unsigned int)(var1));
    var6 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var1)) & 7)));
    if (((unsigned long)(7) <= (unsigned long)(((unsigned long)((unsigned int)(var1)) - 1)))) {
        goto L_1185;
    }
    ret = 0;
    var10 = 0;
    i = 0;
    if ((var6 != 0)) {
        goto L_11ca;
    }
    L_1181: ;
    return ret;
    L_1182: ;
    return 0;
    L_1185: ;
    var14 = (unsigned long)((unsigned int)((var2 & 8)));
    var15 = -1793;
    var19 = 0;
    i = 0;
    do {
        var21 = (var19 << 8);
        var19 = ((var15 + var21) + 2040);
        i = (i + 8);
        var15 = (var15 + 2040);
    } while ((var14 != i));
    ret = (var21 + var15);
    var10 = ret;
    if ((var6 == 0)) {
        goto L_1181;
    }
    L_11ca: ;
    var24 = (1 - (unsigned long)((unsigned int)(i)));
    do {
        var25 = var10;
        var10 = ((unsigned long)((unsigned int)(i)) + (var10 * 2));
        var24 = (var24 - 1);
        var6 = (var6 - 1);
        i = (i + 1);
    } while ((var6 != 0));
    return ((var25 + var25) - var24);
}
nested_rotated pass 60 lines
// glaurung: nested_rotated @ 0x13b0
long nested_rotated(int arg0, int arg1) {
    int la;
    int lb;
    int i;
    long acc;
    int j;
    long ret;
    long var13;
    long var18;
    int var2;
    long var23;
    long var28;
    long var33;
    long var38;
    int var44;
    long var9;
    var2 = (arg0 & 7);
    la = (unsigned long)((unsigned int)(var2));
    if (((unsigned long)((unsigned int)(var2)) == 0)) {
        return 0;
    }
    lb = (unsigned long)((unsigned int)((arg1 & 7)));
    var9 = 0;
    i = 0;
    do {
        ret = var9;
        if (((unsigned long)((unsigned int)(lb)) != 0)) {
            var13 = ((unsigned long)((unsigned int)(i)) + (var9 + (var9 * 2)));
            ret = var13;
            if (((unsigned long)((unsigned int)(lb)) != 1)) {
                var18 = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) ^ 1))) + (var13 + (var13 * 2)));
                ret = var18;
                if (((unsigned long)((unsigned int)(lb)) != 2)) {
                    var23 = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) ^ 2))) + (var18 + (var18 * 2)));
                    ret = var23;
                    if (((unsigned long)((unsigned int)(lb)) != 3)) {
                        var28 = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) ^ 3))) + (var23 + (var23 * 2)));
                        ret = var28;
                        if (((unsigned long)((unsigned int)(lb)) != 4)) {
                            var33 = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) ^ 4))) + (var28 + (var28 * 2)));
                            ret = var33;
                            if (((unsigned long)((unsigned int)(lb)) != 5)) {
                                var38 = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) ^ 5))) + (var33 + (var33 * 2)));
                                ret = var38;
                                if (((unsigned long)((unsigned int)(lb)) != 6)) {
                                    ret = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) ^ 6))) + (var38 + (var38 * 2)));
                                }
                            }
                        }
                    }
                }
            }
        }
        var44 = (i + 1);
        var9 = ret;
        i = (unsigned long)((unsigned int)(var44));
    } while (((unsigned int)(var44) != (unsigned int)(la)));
    return ret;
}
skip_odd_sum pass 120 lines
// glaurung: skip_odd_sum @ 0x1280
long skip_odd_sum(int arg0) {
    int lim;
    long ret;
    long t110;
    int var1;
    int var12;
    int var13;
    int var19;
    int var20;
    int var21;
    int var22;
    int var27;
    int var28;
    int var29;
    int var30;
    int var68;
    int var69;
    int var82;
    int var84;
    ret = 0;
    var1 = (arg0 & 15);
    if (((unsigned long)((unsigned int)(var1)) == 0)) {
        return ret;
    }
    lim = ((unsigned int)(var1) - 1);
    var12 = (unsigned long)((unsigned int)(lim));
    var13 = (unsigned long)((unsigned int)(lim));
    var19 = 0;
    var20 = 0;
    var21 = 0;
    var22 = 0;
    var27 = 0;
    var28 = 0;
    var29 = 0;
    var30 = 0;
    switch ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var1)) + 1))) & 30))) - 2)))) {
        case 0:
            break;
        case 2:
            var27 = 2;
            var28 = 0;
            var29 = 0;
            var30 = 0;
            ret = 2;
            break;
        case 4:
            var27 = 6;
            var28 = 0;
            var29 = 0;
            var30 = 0;
            var19 = 2;
            var20 = 0;
            var21 = 0;
            var22 = 0;
            ret = 4;
            break;
        case 6:
            var27 = 12;
            var28 = 0;
            var29 = 0;
            var30 = 0;
            var19 = 6;
            var20 = 0;
            var21 = 0;
            var22 = 0;
            ret = 6;
            break;
        case 8:
            var27 = 20;
            var28 = 0;
            var29 = 0;
            var30 = 0;
            var19 = 12;
            var20 = 0;
            var21 = 0;
            var22 = 0;
            ret = 8;
            break;
        case 10:
            var27 = 30;
            var28 = 0;
            var29 = 0;
            var30 = 0;
            var19 = 20;
            var20 = 0;
            var21 = 0;
            var22 = 0;
            ret = 10;
            break;
        case 12:
            var27 = 42;
            var28 = 0;
            var29 = 0;
            var30 = 0;
            var19 = 30;
            var20 = 0;
            var21 = 0;
            var22 = 0;
            ret = 12;
            break;
        default:
            var27 = 56;
            var28 = 0;
            var29 = 0;
            var30 = 0;
            var19 = 42;
            var20 = 0;
            var21 = 0;
            var22 = 0;
            ret = 14;
            break;
    }
    var68 = (-((var12 ^ 0x80000000) < (ret ^ 0x80000000)));
    var69 = (-((var13 ^ 0x80000000) < ((ret | 1) ^ 0x80000000)));
    var82 = (-(var68 < 0));
    var84 = (-(var69 < 0));
    t110 = (((((~(unsigned long)((unsigned int)(var84))) & (unsigned long)((unsigned int)(var30))) | ((unsigned long)((unsigned int)(var22)) & (unsigned long)((unsigned int)(var84)))) | (((~(unsigned long)((unsigned int)(var69))) & (unsigned long)((unsigned int)(var29))) | ((unsigned long)((unsigned int)(var21)) & (unsigned long)((unsigned int)(var69))))) + ((((~(unsigned long)((unsigned int)(var82))) & (unsigned long)((unsigned int)(var28))) | ((unsigned long)((unsigned int)(var20)) & (unsigned long)((unsigned int)(var82)))) | (((~(unsigned long)((unsigned int)(var68))) & (unsigned long)((unsigned int)(var27))) | ((unsigned long)((unsigned int)(var19)) & (unsigned long)((unsigned int)(var68))))));
    return ((((unsigned long)(t110) >> 32) & 0xffffffff) | (unsigned int)(t110));
}

gcc -O0

8/8
count_up pass 16 lines
// glaurung: count_up @ 0x1138
long int count_up(int arg0) {
    long acc;
    int i;
    int lim;
    // x86-64 prologue: save rbp
    acc = 0;
    i = 0;
    lim = ((unsigned int)(arg0) & 15);
    while ((i < lim)) {
        acc = (acc + (long)((int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) + (unsigned long)((unsigned int)(i))))) + (unsigned long)((unsigned int)(i))))) + 1))));
        i = (i + 1);
    }
    // x86-64 epilogue: restore rbp
    return acc;
}
do_while_control pass 14 lines
// glaurung: do_while_control @ 0x11c6
long int do_while_control(int arg0) {
    long acc;
    int k;
    // x86-64 prologue: save rbp
    acc = 0;
    k = ((unsigned int)(arg0) & 15);
    do {
        acc = (acc + (long)(k));
        k = (k - 1);
    } while (((((unsigned long)((unsigned int)(k)) == 0) | ((long)(k) < 0)) == 0));
    // x86-64 epilogue: restore rbp
    return acc;
}
down_by_negative_imm pass 14 lines
// glaurung: down_by_negative_imm @ 0x12f9
long int down_by_negative_imm(int arg0) {
    long acc;
    int k;
    // x86-64 prologue: save rbp
    acc = 0;
    k = ((unsigned int)(arg0) & 15);
    while (((unsigned long)((unsigned int)(k)) != 0)) {
        acc = ((long)(k) + (acc + acc));
        k = (k - 1);
    }
    // x86-64 epilogue: restore rbp
    return acc;
}
factorial_while pass 14 lines
// glaurung: factorial_while @ 0x10f9
long int factorial_while(int arg0) {
    long f;
    int k;
    // x86-64 prologue: save rbp
    f = 1;
    k = ((unsigned int)(arg0) & 15);
    while (((((unsigned long)((unsigned int)(k)) == 1) | ((long)(k) < 1)) == 0)) {
        f = ((long)(k) * f);
        k = (k - 1);
    }
    // x86-64 epilogue: restore rbp
    return f;
}
find_first_set pass 18 lines
// glaurung: find_first_set @ 0x11fb
int find_first_set(unsigned int arg0) {
    int i;
    i = 0;
    goto L_122b;
    L_120f: ;
    if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(arg0) >> ((unsigned long)((unsigned int)(i)) & 31)))) & 1))) != 0)) {
        // x86-64 epilogue: restore rbp
        return (unsigned int)(i);
    }
    i = (i + 1);
    L_122b: ;
    if ((((unsigned long)((unsigned int)(i)) == 31) | ((long)(i) < 31))) {
        goto L_120f;
    }
    // x86-64 epilogue: restore rbp
    return 0xffffffff;
}
for_accumulate pass 12 lines
// glaurung: for_accumulate @ 0x1181
long int for_accumulate(int arg0) {
    long acc;
    int i;
    // x86-64 prologue: save rbp
    acc = 0;
    for (i = 0; ((long)(i) < (long)((int)(((unsigned long)((unsigned int)(arg0)) & 15)))); i++) {
        acc = ((long)(i) + (acc + acc));
    }
    // x86-64 epilogue: restore rbp
    return acc;
}
nested_rotated pass 21 lines
// glaurung: nested_rotated @ 0x1285
long int nested_rotated(int arg0, int arg1) {
    long acc;
    int la;
    int lb;
    int i;
    int j;
    // x86-64 prologue: save rbp
    acc = 0;
    la = ((unsigned int)(arg0) & 7);
    lb = ((unsigned int)(arg1) & 7);
    i = 0;
    while ((i < la)) {
        for (j = 0; (j < lb); j++) {
            acc = ((long)((int)(((unsigned long)((unsigned int)(i)) ^ j))) + (acc + (acc + acc)));
        }
        i = (i + 1);
    }
    // x86-64 epilogue: restore rbp
    return acc;
}
skip_odd_sum pass 17 lines
// glaurung: skip_odd_sum @ 0x1238
long int skip_odd_sum(int arg0) {
    long acc;
    int lim;
    int i;
    // x86-64 prologue: save rbp
    acc = 0;
    lim = ((unsigned int)(arg0) & 15);
    for (i = 0; (i < lim); i++) {
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) & 1))) != 0)) {
        } else {
            acc = (acc + (long)(i));
        }
    }
    // x86-64 epilogue: restore rbp
    return acc;
}

gcc -O2

8/8
count_up pass 23 lines
// glaurung: count_up @ 0x1150
long int count_up(int arg0) {
    long acc;
    int i;
    int lim;
    int var0;
    long var4;
    long var7;
    long var8;
    var0 = (arg0 & 15);
    if (((unsigned long)((unsigned int)(var0)) == 0)) {
        return 0;
    }
    var4 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) - 1)));
    var7 = ((var4 + (var4 * 2)) + 4);
    var8 = 1;
    acc = 0;
    do {
        acc = (acc + var8);
        var8 = (var8 + 3);
    } while ((var8 != var7));
    return acc;
}
do_while_control pass 14 lines
// glaurung: do_while_control @ 0x11d0
long int do_while_control(int arg0) {
    int k;
    long acc;
    long var4;
    k = (unsigned long)((unsigned int)((arg0 & 15)));
    acc = 0;
    do {
        acc = (acc + (unsigned long)((unsigned int)(k)));
        var4 = ((unsigned long)((unsigned int)(k)) - 1);
        k = var4;
    } while (((((unsigned long)((unsigned int)(var4)) == 0) | ((long)((int)(var4)) < 0)) == 0));
    return acc;
}
down_by_negative_imm pass 30 lines
// glaurung: down_by_negative_imm @ 0x12a0
long int down_by_negative_imm(int arg0) {
    long acc;
    int k;
    int var0;
    long var10;
    long var11;
    long var12;
    long var14;
    long var8;
    var0 = (arg0 & 15);
    if (((unsigned long)((unsigned int)(var0)) == 0)) {
        return 0;
    }
    var8 = ((long)((int)(var0)) - 1);
    var10 = (var8 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) - 1))));
    var11 = 0;
    var12 = (long)((int)(var0));
    while (1) {
        acc = (var12 + (var11 * 2));
        var14 = var8;
        if ((var8 == var10)) {
            break;
        }
        var8 = (var8 - 1);
        var11 = acc;
        var12 = var14;
    }
    return acc;
}
factorial_while pass 18 lines
// glaurung: factorial_while @ 0x1100
long int factorial_while(int arg0) {
    long f;
    int k;
    long var10;
    long var9;
    if (((unsigned long)((unsigned int)((arg0 & 14))) == 0)) {
        return 1;
    }
    f = 1;
    var9 = (long)((int)(((unsigned long)((unsigned int)(arg0)) & 15)));
    do {
        f = (f * var9);
        var10 = (var9 - 1);
        var9 = var10;
    } while (((((unsigned long)((unsigned int)(var10)) == 1) | ((long)((int)(var10)) < 1)) == 0));
    return f;
}
find_first_set pass 15 lines
// glaurung: find_first_set @ 0x11f0
int find_first_set(unsigned int arg0) {
    int i;
    long ret;
    int var2;
    ret = 0;
    while (((((unsigned long)(arg0) >> (ret & 31)) & 1) == 0)) {
        var2 = (ret + 1);
        ret = (unsigned long)((unsigned int)(var2));
        if (((unsigned long)((unsigned int)(var2)) == 32)) {
            return 0xffffffff;
        }
    }
    return ret;
}
for_accumulate pass 21 lines
// glaurung: for_accumulate @ 0x1190
long int for_accumulate(int arg0) {
    int i;
    long acc;
    int var0;
    long var10;
    long var4;
    var0 = (arg0 & 15);
    if (((unsigned long)((unsigned int)(var0)) == 0)) {
        return 0;
    }
    var4 = (long)((int)(var0));
    i = 0;
    acc = 0;
    do {
        acc = ((unsigned long)((unsigned int)(i)) + (acc * 2));
        var10 = ((unsigned long)((unsigned int)(i)) + 1);
        i = var10;
    } while ((var10 != var4));
    return acc;
}
nested_rotated pass 41 lines
// glaurung: nested_rotated @ 0x1260
long int nested_rotated(int arg0, int arg1) {
    int lb;
    long acc;
    int la;
    int i;
    int j;
    long var11;
    long var12;
    long var17;
    int var18;
    long var20;
    int var21;
    int var5;
    lb = (unsigned long)((unsigned int)((arg1 & 7)));
    acc = 0;
    var5 = (arg0 & 7);
    la = (unsigned long)((unsigned int)(var5));
    if (((unsigned long)((unsigned int)(var5)) != 0)) {
        i = 0;
        do {
            var11 = 0;
            if (((unsigned long)((unsigned int)(lb)) != 0)) {
                var12 = acc;
                j = var11;
                do {
                    var17 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) ^ j)));
                    var18 = (j + 1);
                    j = (unsigned long)((unsigned int)(var18));
                    var20 = ((long)((int)(var17)) + (var12 + (var12 * 2)));
                    var12 = var20;
                    acc = var20;
                    var11 = (unsigned long)((unsigned int)(var18));
                } while (((unsigned int)(lb) != (unsigned int)(var18)));
            }
            var21 = (i + 1);
            i = (unsigned long)((unsigned int)(var21));
        } while (((unsigned int)(la) != (unsigned int)(var21)));
    }
    return acc;
}
skip_odd_sum pass 21 lines
// glaurung: skip_odd_sum @ 0x1220
long int skip_odd_sum(int arg0) {
    int lim;
    int i;
    long acc;
    int var0;
    long var11;
    var0 = (arg0 & 15);
    if (((unsigned long)((unsigned int)(var0)) == 0)) {
        return 0;
    }
    lim = (long)((int)(var0));
    i = 0;
    acc = 0;
    do {
        acc = (((unsigned long)((unsigned char)((i & 1))) == 0) ? (acc + (unsigned long)((unsigned int)(i))) : acc);
        var11 = ((unsigned long)((unsigned int)(i)) + 1);
        i = var11;
    } while ((var11 != lim));
    return acc;
}

← 213 fixtures