Fixture 211

irreducible loops

C · 4 functions · 4 lanes · 16 of 16 function-lanes behave identically

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

Loops with MORE THAN ONE entry point — the graphs no schema matcher can express, and the ones a region-based structurer exists to handle.

WHY THIS IS DIFFERENT FROM EVERY OTHER LOOP FIXTURE. 03_loop_shapes, 12_loop_rotation, 13_loop_early_exit and 125_loop_shapes are all REDUCIBLE: one header dominates the whole body, so natural_loop_body finds it from a single back edge. An irreducible loop has two headers and no dominating entry, so detect_natural_loop cannot fire at all and build_full reaches its Region::Unstructured fallback — the lossless whole-function bailout that labels every block.

That fallback is correct: Region::{While,DoWhile} carry exactly one exit, so a multi-entry loop is UNREPRESENTABLE in the region algebra, and inventing a header would move blocks across an edge the machine does not have. The three refusals at the top of build_full exist precisely to detect this before a shape can guess. So the fixture's near-term expectation is a faithful goto rendering, and its long-term purpose is to be the acceptance test for the region analysis that replaces the matcher: when Region grows owned multi-exits, these functions are how you find out whether it worked.

145_control_flow_flattening is an OLLVM dispatch loop — flattened, but still reducible, with one header and one dispatcher. 102_duffs_device interleaves a switch with a loop but enters at exactly one place. Neither is irreducible.

A goto into a loop body is the only portable way to write one in C, so unlike 209/210 this fixture's source DOES contain goto, and goto_free is deliberately NOT asserted. What is asserted is that the recovery is non-empty and executes identically — a bailout must stay faithful.

tests/decompiler_fixtures/src/211_irreducible_loops.c source
#include <stdint.h>

/* Loops with MORE THAN ONE entry point — the graphs no schema matcher can
 * express, and the ones a region-based structurer exists to handle.
 *
 * WHY THIS IS DIFFERENT FROM EVERY OTHER LOOP FIXTURE. `03_loop_shapes`,
 * `12_loop_rotation`, `13_loop_early_exit` and `125_loop_shapes` are all
 * REDUCIBLE: one header dominates the whole body, so `natural_loop_body` finds
 * it from a single back edge. An irreducible loop has two headers and no
 * dominating entry, so `detect_natural_loop` cannot fire at all and
 * `build_full` reaches its `Region::Unstructured` fallback — the lossless
 * whole-function bailout that labels every block.
 *
 * That fallback is correct: `Region::{While,DoWhile}` carry exactly one `exit`,
 * so a multi-entry loop is UNREPRESENTABLE in the region algebra, and inventing
 * a header would move blocks across an edge the machine does not have. The
 * three refusals at the top of `build_full` exist precisely to detect this
 * before a shape can guess. So the fixture's near-term expectation is a
 * faithful goto rendering, and its long-term purpose is to be the acceptance
 * test for the region analysis that replaces the matcher: when `Region` grows
 * owned multi-exits, these functions are how you find out whether it worked.
 *
 * `145_control_flow_flattening` is an OLLVM dispatch loop — flattened, but
 * still reducible, with one header and one dispatcher. `102_duffs_device`
 * interleaves a switch with a loop but enters at exactly one place. Neither is
 * irreducible.
 *
 * A `goto` into a loop body is the only portable way to write one in C, so
 * unlike `209`/`210` this fixture's source DOES contain goto, and `goto_free`
 * is deliberately NOT asserted. What is asserted is that the recovery is
 * non-empty and executes identically — a bailout must stay faithful.
 */

/* The canonical two-entry loop. Which header the loop is entered through
 * depends on a runtime value, so no static choice of header is correct. */
__attribute__((noinline)) int32_t two_entry_loop(int32_t seed, int32_t count) {
    int32_t acc = 0;
    int32_t i = 0;
    if (count < 0 || count > 32) {
        return -1;
    }
    if (seed & 1) {
        goto odd_entry;
    }

even_entry:
    if (i >= count) {
        return acc;
    }
    acc += i * 2;
    i++;

odd_entry:
    if (i >= count) {
        return acc + 1;
    }
    acc ^= (i + seed) & 0xff;
    i++;
    goto even_entry;
}

/* Two loops sharing a body region, entered from different predecessors — the
 * shape a compiler produces from tail-merged loop bodies. */
__attribute__((noinline)) int32_t shared_body_loops(int32_t mode,
                                                    int32_t count) {
    int32_t acc = 0;
    int32_t i = 0;
    if (count < 0 || count > 32) {
        return -1;
    }
    if (mode > 0) {
        acc = 100;
        goto body;
    }
    acc = 200;

top:
    if (i >= count) {
        return acc;
    }

body:
    acc += (i * 3) & 0x3f;
    i++;
    if (i < count) {
        goto top;
    }
    return acc;
}

/* An irreducible loop NESTED inside a reducible one: the outer loop must still
 * be recovered even though the inner region cannot be. A structurer that bails
 * on the whole function loses the outer loop too, which is the difference
 * between a local and a global refusal. */
__attribute__((noinline)) int32_t irreducible_inside_reducible(int32_t outer,
                                                               int32_t inner) {
    int32_t acc = 0;
    if (outer < 0 || outer > 8 || inner < 0 || inner > 8) {
        return -1;
    }
    for (int32_t o = 0; o < outer; o++) {
        int32_t i = 0;
        if (o & 1) {
            goto second;
        }
    first:
        if (i >= inner) {
            continue;
        }
        acc += i;
        i++;
    second:
        if (i >= inner) {
            continue;
        }
        acc ^= i + o;
        i++;
        goto first;
    }
    return acc;
}

/* CONTROL: the identical arithmetic written as an ordinary reducible loop. It
 * must recover as a real loop with no goto; if it does not, the defect is in
 * loop recovery generally and not in irreducibility. */
__attribute__((noinline)) int32_t reducible_control(int32_t seed,
                                                    int32_t count) {
    int32_t acc = 0;
    if (count < 0 || count > 32) {
        return -1;
    }
    for (int32_t i = 0; i < count; i++) {
        acc += i * 2;
        acc ^= (i + seed) & 0xff;
    }
    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

4/4
irreducible_inside_reducible pass 54 lines
// glaurung: irreducible_inside_reducible @ 0x1270
int32_t irreducible_inside_reducible(int32_t arg0, int32_t arg1) {
    int acc;
    int o;
    int i;
    int local_4;
    // x86-64 prologue: save rbp
    acc = 0;
    if (((long)(arg0) < 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg0)) == 8) | ((long)(arg0) < 8)) == 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);
    }
    o = 0;
    while ((o < arg0)) {
        i = 0;
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(o)) & 1))) == 0)) {
            L_12e8: ;
            if ((i < arg1)) {
                acc = ((unsigned int)(i) + acc);
                i = ((unsigned int)(i) + 1);
                L_130b: ;
                if ((i < arg1)) {
                    acc = ((unsigned int)(((unsigned long)((unsigned int)(i)) + o)) ^ acc);
                    i = ((unsigned int)(i) + 1);
                    goto L_12e8;
                } else {
                }
            } else {
            }
        } else {
            goto L_130b;
        }
        o = ((unsigned int)(o) + 1);
    }
    local_4 = acc;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
reducible_control pass 25 lines
// glaurung: reducible_control @ 0x1350
int32_t reducible_control(int32_t arg0, int32_t arg1) {
    int acc;
    int i;
    int local_4;
    // x86-64 prologue: save rbp
    acc = 0;
    if (((long)(arg1) < 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 32) | ((long)(arg1) < 32)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    for (i = 0; (i < arg1); i++) {
        acc = ((unsigned int)(((unsigned long)((unsigned int)(i)) << 1)) + acc);
        acc = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) + arg0))) & 255)) ^ acc);
    }
    local_4 = acc;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
shared_body_loops pass 40 lines
// glaurung: shared_body_loops @ 0x11c0
int32_t shared_body_loops(int32_t arg0, int32_t arg1) {
    int acc;
    int i;
    int local_4;
    // x86-64 prologue: save rbp
    acc = 0;
    i = 0;
    if (((long)(arg1) < 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 32) | ((long)(arg1) < 32)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if ((((unsigned long)((unsigned int)(arg0)) == 0) | ((long)(arg0) < 0))) {
        acc = 200;
        L_1215: ;
        if ((i < arg1)) {
            L_1231: ;
            acc = ((unsigned int)(((i * 3) & 63)) + acc);
            i = ((unsigned int)(i) + 1);
            if ((arg1 <= i)) {
                local_4 = acc;
            } else {
                goto L_1215;
            }
        } else {
            local_4 = acc;
        }
    } else {
        acc = 100;
        goto L_1231;
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
two_entry_loop pass 40 lines
// glaurung: two_entry_loop @ 0x1100
int32_t two_entry_loop(int32_t arg0, int32_t arg1) {
    int acc;
    int i;
    int local_4;
    // x86-64 prologue: save rbp
    acc = 0;
    i = 0;
    if (((long)(arg1) < 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 32) | ((long)(arg1) < 32)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 1))) == 0)) {
        L_1151: ;
        if ((i < arg1)) {
            acc = ((unsigned int)(((unsigned long)((unsigned int)(i)) << 1)) + acc);
            i = ((unsigned int)(i) + 1);
            L_117d: ;
            if ((i < arg1)) {
                acc = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) + arg0))) & 255)) ^ acc);
                i = ((unsigned int)(i) + 1);
                goto L_1151;
            } else {
                local_4 = ((unsigned int)(acc) + 1);
            }
        } else {
            local_4 = acc;
        }
    } else {
        goto L_117d;
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}

clang -O2

4/4
irreducible_inside_reducible pass 253 lines
// glaurung: irreducible_inside_reducible @ 0x1180
int32_t irreducible_inside_reducible(int32_t arg0, int32_t arg1) {
    int acc;
    int i;
    int o;
    int var11;
    long var13;
    long var14;
    long var15;
    int var16;
    long var18;
    int var19;
    int var20;
    long var22;
    int var24;
    long var25;
    int var26;
    long var27;
    long var3;
    int var30;
    long var32;
    long var33;
    long var34;
    long var37;
    int var38;
    int var39;
    long var4;
    int var41;
    long var44;
    long var45;
    int var47;
    long var48;
    int var49;
    long var50;
    int var53;
    long var55;
    long var56;
    long var57;
    int var6;
    long var60;
    int var61;
    int var62;
    int var64;
    long var67;
    int var69;
    long var7;
    long var70;
    int var71;
    long var72;
    int var75;
    long var78;
    long var79;
    int var8;
    long var82;
    int var83;
    int var85;
    int var87;
    long var9;
    acc = 0xffffffff;
    if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg0))))) {
        return acc;
    }
    acc = 0xffffffff;
    if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return acc;
    }
    acc = 0;
    if (((unsigned long)((unsigned int)(arg0)) == 0)) {
        return acc;
    }
    var3 = 0;
    var4 = 0;
    if ((0 < (long)(arg1))) {
        do {
            var6 = (acc + var3);
            var7 = (unsigned long)((unsigned int)(var6));
            var8 = (var3 + 1);
            var9 = (unsigned long)((unsigned int)(var8));
            var4 = (unsigned long)((unsigned int)(var6));
            if ((arg1 <= var8)) {
                break;
            }
            acc = (unsigned long)((unsigned int)((var7 ^ var9)));
            var11 = (var9 + 1);
            var3 = (unsigned long)((unsigned int)(var11));
            var4 = acc;
        } while ((var11 < arg1));
    }
    acc = var4;
    if (((unsigned long)((unsigned int)(arg0)) == 1)) {
        return acc;
    }
    var13 = 0;
    if ((0 < (long)(arg1))) {
        var14 = var4;
        var15 = var13;
        do {
            var16 = (var15 + 1);
            var13 = (unsigned long)((unsigned int)(var16));
            var18 = (unsigned long)((unsigned int)((var14 ^ (unsigned long)((unsigned int)(var16)))));
            var4 = var18;
            if ((arg1 <= var16)) {
                break;
            }
            var19 = (var18 + var13);
            var14 = (unsigned long)((unsigned int)(var19));
            var20 = (var13 + 1);
            var13 = (unsigned long)((unsigned int)(var20));
            var15 = (unsigned long)((unsigned int)(var20));
            var4 = (unsigned long)((unsigned int)(var19));
        } while ((var20 < arg1));
    }
    acc = var4;
    if (((unsigned long)((unsigned int)(arg0)) == 2)) {
        return acc;
    }
    var22 = 0;
    acc = var4;
    if ((0 < (long)(arg1))) {
        do {
            var24 = (var4 + var22);
            var25 = (unsigned long)((unsigned int)(var24));
            var26 = (var22 + 1);
            var27 = (unsigned long)((unsigned int)(var26));
            acc = (unsigned long)((unsigned int)(var24));
            if ((arg1 <= var26)) {
                break;
            }
            var4 = (unsigned long)((unsigned int)((var25 ^ (unsigned long)((unsigned int)((var27 + 2))))));
            var30 = (var27 + 1);
            var22 = (unsigned long)((unsigned int)(var30));
            acc = var4;
        } while ((var30 < arg1));
    }
    if (((unsigned long)((unsigned int)(arg0)) == 3)) {
        return acc;
    }
    var32 = 0;
    if (((long)(arg1) <= 0)) {
        goto L_125b;
    }
    var33 = acc;
    var34 = var32;
    L_1240: ;
    var37 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var34 + 3))) ^ var33)));
    var38 = (var34 + 1);
    var32 = (unsigned long)((unsigned int)(var38));
    if ((var38 < arg1)) {
        var39 = (var37 + var32);
        var41 = (var32 + 1);
        var32 = (unsigned long)((unsigned int)(var41));
        acc = (unsigned long)((unsigned int)(var39));
        var33 = (unsigned long)((unsigned int)(var39));
        var34 = (unsigned long)((unsigned int)(var41));
        if ((var41 < arg1)) {
            goto L_1240;
        }
        goto L_125b;
    }
    acc = (unsigned long)((unsigned int)(var37));
    L_125b: ;
    if (((unsigned long)((unsigned int)(arg0)) == 4)) {
        return acc;
    }
    var44 = 0;
    var45 = acc;
    if ((0 < (long)(arg1))) {
        do {
            var47 = (acc + var44);
            var48 = (unsigned long)((unsigned int)(var47));
            var49 = (var44 + 1);
            var50 = (unsigned long)((unsigned int)(var49));
            var45 = (unsigned long)((unsigned int)(var47));
            if ((arg1 <= var49)) {
                break;
            }
            acc = (unsigned long)((unsigned int)((var48 ^ (unsigned long)((unsigned int)((var50 + 4))))));
            var53 = (var50 + 1);
            var44 = (unsigned long)((unsigned int)(var53));
            var45 = acc;
        } while ((var53 < arg1));
    }
    acc = var45;
    if (((unsigned long)((unsigned int)(arg0)) == 5)) {
        return acc;
    }
    var55 = 0;
    var56 = var45;
    var57 = 0;
    if (((long)(arg1) <= 0)) {
        goto L_12ab;
    }
    L_1290: ;
    var60 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var57 + 5))) ^ var56)));
    var61 = (var57 + 1);
    var55 = (unsigned long)((unsigned int)(var61));
    if ((var61 < arg1)) {
        var62 = (var60 + var55);
        var64 = (var55 + 1);
        var55 = (unsigned long)((unsigned int)(var64));
        var45 = (unsigned long)((unsigned int)(var62));
        var56 = (unsigned long)((unsigned int)(var62));
        var57 = (unsigned long)((unsigned int)(var64));
        if ((var64 < arg1)) {
            goto L_1290;
        }
        goto L_12ab;
    }
    var45 = (unsigned long)((unsigned int)(var60));
    L_12ab: ;
    acc = var45;
    if (((unsigned long)((unsigned int)(arg0)) != 6)) {
        var67 = 0;
        acc = var45;
        if ((0 < (long)(arg1))) {
            do {
                var69 = (var45 + var67);
                var70 = (unsigned long)((unsigned int)(var69));
                var71 = (var67 + 1);
                var72 = (unsigned long)((unsigned int)(var71));
                acc = (unsigned long)((unsigned int)(var69));
                if ((arg1 <= var71)) {
                    break;
                }
                var45 = (unsigned long)((unsigned int)((var70 ^ (unsigned long)((unsigned int)((var72 + 6))))));
                var75 = (var72 + 1);
                var67 = (unsigned long)((unsigned int)(var75));
                acc = var45;
            } while ((var75 < arg1));
        }
        if (((unsigned long)((unsigned int)(arg0)) == 7)) {
            return acc;
        }
        var78 = acc;
        var79 = 0;
        if (((long)(arg1) <= 0)) {
            return acc;
        }
        do {
            var82 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var79 + 7))) ^ var78)));
            var83 = (var79 + 1);
            if ((arg1 <= var83)) {
                return (unsigned int)(var82);
            }
            var85 = (var82 + (unsigned long)((unsigned int)(var83)));
            var87 = ((unsigned long)((unsigned int)(var83)) + 1);
            acc = (unsigned long)((unsigned int)(var85));
            var78 = (unsigned long)((unsigned int)(var85));
            var79 = (unsigned long)((unsigned int)(var87));
        } while ((var87 < arg1));
    }
    return acc;
}
reducible_control pass 55 lines
// glaurung: reducible_control @ 0x1300
int32_t reducible_control(int32_t arg0, int32_t arg1) {
    int i;
    int acc;
    long ret;
    long var10;
    long var13;
    long var47;
    int var48;
    long var5;
    long var50;
    long var56;
    long var58;
    int var65;
    long var7;
    ret = 0xffffffff;
    if (((unsigned long)((unsigned long)((unsigned int)(arg1))) <= (unsigned long)(32))) {
        if (((unsigned long)((unsigned int)(arg1)) == 0)) {
            return 0;
        }
        var5 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 3)));
        if (((unsigned long)(3) <= (unsigned long)((unsigned long)((unsigned int)((arg1 - 1)))))) {
            var7 = (unsigned long)((unsigned int)((arg1 & -4)));
            i = 0;
            var10 = 4;
            var13 = 0;
            do {
                var47 = (unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + i))) + 3))) & 255))) ^ (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + i))) + 2))) & 255))) ^ (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + i))) + 1))) & 255))) ^ (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var10 + (unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)((arg0 + i))) & 255))) ^ (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var10 + var13))) - 4))))))))) - 2)))))) + var10)))))) + var10))) + 2))))));
                var48 = (i + 4);
                i = (unsigned long)((unsigned int)(var48));
                var10 = (unsigned long)((unsigned int)((var10 + 8)));
                var13 = var47;
                var50 = (unsigned long)((unsigned int)(var48));
            } while (((unsigned int)(var7) != (unsigned int)(var48)));
        } else {
            var47 = 0;
            var50 = 0;
        }
        ret = var47;
        if (((unsigned long)((unsigned int)(var5)) == 0)) {
            return ret;
        }
        var56 = (unsigned long)((unsigned int)((arg0 + var50)));
        var58 = (unsigned long)((unsigned int)((var50 + var50)));
        do {
            var47 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var47 + var58))) ^ (unsigned int)((unsigned char)((var56 & 255))))));
            var56 = (unsigned long)((unsigned int)((var56 + 1)));
            var58 = (unsigned long)((unsigned int)((var58 + 2)));
            var65 = (var5 - 1);
            var5 = (unsigned long)((unsigned int)(var65));
            ret = var47;
        } while (((unsigned long)((unsigned int)(var65)) != 0));
    }
    return ret;
}
shared_body_loops pass 39 lines
// glaurung: shared_body_loops @ 0x1150
int32_t shared_body_loops(int32_t arg0, int32_t arg1) {
    int acc;
    int i;
    long ret;
    int var13;
    int var14;
    long var6;
    long var7;
    long var8;
    ret = 0xffffffff;
    if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return ret;
    }
    acc = 200;
    var6 = 0;
    var7 = 0;
    var8 = 100;
    if (((((unsigned long)((unsigned int)(arg0)) == 0) | ((long)(arg0) < 0)) == 0)) {
        goto L_1170;
    }
    L_116a: ;
    var7 = var6;
    var8 = (unsigned long)((unsigned int)(acc));
    ret = (unsigned long)((unsigned int)(acc));
    if (((long)(arg1) <= (long)((int)(var6)))) {
        return ret;
    }
    L_1170: ;
    var13 = ((unsigned int)(((unsigned long)((unsigned int)((var7 + (var7 * 2)))) & 63)) + var8);
    acc = (unsigned long)((unsigned int)(var13));
    var14 = (var7 + 1);
    var6 = (unsigned long)((unsigned int)(var14));
    ret = (unsigned long)((unsigned int)(var13));
    if ((var14 < arg1)) {
        goto L_116a;
    }
    return ret;
}
two_entry_loop pass 41 lines
// glaurung: two_entry_loop @ 0x1100
int32_t two_entry_loop(int32_t arg0, int32_t arg1) {
    int acc;
    int i;
    long ret;
    int var15;
    long var3;
    long var4;
    long var5;
    long var6;
    ret = 0xffffffff;
    if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return ret;
    }
    ret = 0;
    var3 = 0;
    var4 = 0;
    if (((unsigned long)((unsigned char)((arg0 & 1))) == 0)) {
        goto L_112f;
    }
    var5 = ret;
    var6 = ret;
    if (((long)(arg1) <= (long)((int)(var3)))) {
        return (unsigned int)((var6 + 1));
    }
    L_1120: ;
    ret = (unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)((var3 + arg0))) & 255))) ^ var5)));
    var4 = (unsigned long)((unsigned int)((var3 + 1)));
    L_112f: ;
    if (((long)(arg1) <= (long)((int)(var4)))) {
        return ret;
    }
    var5 = (unsigned long)((unsigned int)((ret + (var4 * 2))));
    var15 = (var4 + 1);
    var3 = (unsigned long)((unsigned int)(var15));
    var6 = var5;
    if ((var15 < arg1)) {
        goto L_1120;
    }
    return (unsigned int)((var6 + 1));
}

gcc -O0

4/4
irreducible_inside_reducible pass 48 lines
// glaurung: irreducible_inside_reducible @ 0x11eb
int32_t irreducible_inside_reducible(int32_t arg0, int32_t arg1) {
    int acc;
    int o;
    int i;
    // x86-64 prologue: save rbp
    acc = 0;
    if (((long)(arg0) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg0)) == 8) | ((long)(arg0) < 8)) == 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;
    }
    o = 0;
    while ((o < arg0)) {
        i = 0;
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(o)) & 1))) != 0)) {
            L_124f: ;
            if ((arg1 <= i)) {
            } else {
                acc = (acc ^ (unsigned int)(((unsigned long)((unsigned int)(o)) + (unsigned long)((unsigned int)(i)))));
                i = (i + 1);
                L_123a: ;
                if ((arg1 <= i)) {
                } else {
                    acc = (acc + (unsigned int)(i));
                    i = (i + 1);
                    goto L_124f;
                }
            }
        } else {
            goto L_123a;
        }
        o = (o + 1);
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(acc);
}
reducible_control pass 21 lines
// glaurung: reducible_control @ 0x127d
int32_t reducible_control(int32_t arg0, int32_t arg1) {
    int acc;
    int i;
    // x86-64 prologue: save rbp
    acc = 0;
    if (((long)(arg1) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 32) | ((long)(arg1) < 32)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    for (i = 0; (i < arg1); i++) {
        acc = (acc + (unsigned int)(((unsigned long)((unsigned int)(i)) + (unsigned long)((unsigned int)(i)))));
        acc = (acc ^ (unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + (unsigned long)((unsigned int)(i))))) & 255))));
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(acc);
}
shared_body_loops pass 38 lines
// glaurung: shared_body_loops @ 0x1175
int32_t shared_body_loops(int32_t arg0, int32_t arg1) {
    int acc;
    int i;
    long ret;
    // x86-64 prologue: save rbp
    acc = 0;
    i = 0;
    if (((long)(arg1) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 32) | ((long)(arg1) < 32)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if ((((unsigned long)((unsigned int)(arg0)) == 0) | ((long)(arg0) < 0))) {
        acc = 200;
        L_11bd: ;
        if ((i < arg1)) {
            L_11cb: ;
            acc = (acc + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) + (unsigned long)((unsigned int)(i))))) + (unsigned long)((unsigned int)(i))))) & 63)));
            i = (i + 1);
            if ((i < arg1)) {
                goto L_11bd;
            } else {
                ret = (unsigned long)((unsigned int)(acc));
            }
        } else {
            ret = (unsigned long)((unsigned int)(acc));
        }
    } else {
        acc = 100;
        goto L_11cb;
    }
    // x86-64 epilogue: restore rbp
    return ret;
}
two_entry_loop pass 38 lines
// glaurung: two_entry_loop @ 0x10f9
int32_t two_entry_loop(int32_t arg0, int32_t arg1) {
    int acc;
    int i;
    long ret;
    // x86-64 prologue: save rbp
    acc = 0;
    i = 0;
    if (((long)(arg1) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 32) | ((long)(arg1) < 32)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 1))) != 0)) {
        L_114f: ;
        if ((i < arg1)) {
            acc = (acc ^ (unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + (unsigned long)((unsigned int)(i))))) & 255))));
            i = (i + 1);
            L_1133: ;
            if ((i < arg1)) {
                acc = (acc + (unsigned int)(((unsigned long)((unsigned int)(i)) + (unsigned long)((unsigned int)(i)))));
                i = (i + 1);
                goto L_114f;
            } else {
                ret = (unsigned long)((unsigned int)(acc));
            }
        } else {
            ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(acc)) + 1)));
        }
    } else {
        goto L_1133;
    }
    // x86-64 epilogue: restore rbp
    return ret;
}

gcc -O2

4/4
irreducible_inside_reducible pass 66 lines
// glaurung: irreducible_inside_reducible @ 0x11a0
int32_t irreducible_inside_reducible(int32_t arg0, int32_t arg1) {
    int o;
    int i;
    int acc;
    long ret;
    long var11;
    long var12;
    long var13;
    int var15;
    int var20;
    long var5;
    int var7;
    long var8;
    ret = (unsigned long)((unsigned int)(arg0));
    if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg0))))) {
        return 0xffffffff;
    }
    if (((unsigned long)(8) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return 0xffffffff;
    }
    if (((unsigned long)((unsigned int)(arg0)) == 0)) {
        return ret;
    }
    o = 0;
    var5 = 0;
    do {
        var7 = ((unsigned int)(o) & 1);
        var8 = (unsigned long)((unsigned int)(var7));
        if (((unsigned long)((unsigned int)(var7)) != 0)) {
            var11 = var5;
            var12 = 0;
            L_11c8: ;
            if (((long)(arg1) <= (long)((int)(var12)))) {
                goto L_11e0;
            }
            goto L_11cc;
        } else {
            var13 = var5;
            i = var8;
            var11 = var5;
            if (((long)(arg1) <= (long)((int)(var8)))) {
                goto L_11e0;
            }
            goto L_11c3;
        }
        L_11e0: ;
        var15 = (o + 1);
        o = (unsigned long)((unsigned int)(var15));
        var5 = var11;
    } while (((unsigned int)(ret) != (unsigned int)(var15)));
    return (unsigned int)(var11);
    L_11c3: ;
    var11 = (unsigned long)((unsigned int)((var13 + i)));
    var12 = (unsigned long)((unsigned int)((i + 1)));
    goto L_11c8;
    L_11cc: ;
    var20 = (var12 + 1);
    i = (unsigned long)((unsigned int)(var20));
    var13 = (unsigned long)((unsigned int)((var11 ^ (unsigned long)((unsigned int)((var12 + o))))));
    if ((var20 < arg1)) {
        goto L_11c3;
    }
    var11 = var13;
    goto L_11e0;
}
reducible_control pass 30 lines
// glaurung: reducible_control @ 0x1200
int32_t reducible_control(int32_t arg0, int32_t arg1) {
    int acc;
    int i;
    long ret;
    int var10;
    int var11;
    long var2;
    long var4;
    long var7;
    if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return 0xffffffff;
    }
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        return 0;
    }
    var2 = (unsigned long)((unsigned int)((arg1 + arg1)));
    var4 = 0;
    ret = 0;
    var7 = (unsigned long)((unsigned int)(arg0));
    do {
        acc = (ret + var4);
        var10 = (unsigned int)((unsigned char)((var7 & 255)));
        var11 = (var4 + 2);
        var4 = (unsigned long)((unsigned int)(var11));
        var7 = (unsigned long)((unsigned int)((var7 + 1)));
        ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(acc)) ^ var10)));
    } while (((unsigned int)(var11) != (unsigned int)(var2)));
    return ret;
}
shared_body_loops pass 35 lines
// glaurung: shared_body_loops @ 0x1150
int32_t shared_body_loops(int32_t arg0, int32_t arg1) {
    int acc;
    int i;
    long var0;
    long var1;
    long var3;
    long var4;
    if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg0)) == 0) | ((long)(arg0) < 0)) == 0)) {
        var1 = 1;
        var3 = 100;
        L_1175: ;
        var4 = var1;
        var0 = var3;
        if (((((unsigned int)(arg1) == (unsigned int)(var1)) | ((long)(arg1) < (long)((int)(var1)))) != 0)) {
            return (unsigned int)(var0);
        }
        L_1169: ;
        var3 = (unsigned long)((unsigned int)((var3 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var4 + (var4 * 2)))) & 63))))));
        var1 = (unsigned long)((unsigned int)((var4 + 1)));
        goto L_1175;
    } else {
        var0 = 200;
        if (((unsigned long)((unsigned int)(arg1)) == 0)) {
            return (unsigned int)(var0);
        }
        var3 = 200;
        var4 = 0;
        goto L_1169;
    }
    return (unsigned int)(var0);
}
two_entry_loop pass 48 lines
// glaurung: two_entry_loop @ 0x1100
int32_t two_entry_loop(int32_t arg0, int32_t arg1) {
    int i;
    int acc;
    long ret;
    int var3;
    long var5;
    int var6;
    long var7;
    long var8;
    if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        goto L_1128;
    }
    i = 0;
    var3 = ((unsigned int)(arg0) & 1);
    ret = (unsigned long)((unsigned int)(var3));
    if (((unsigned long)((unsigned int)(var3)) != 0)) {
        goto L_1130;
    }
    L_1112: ;
    if ((arg1 <= i)) {
        goto L_112d;
    }
    var5 = (unsigned long)((unsigned int)((ret + (i * 2))));
    var6 = (i + 1);
    var7 = (unsigned long)((unsigned int)(var6));
    var8 = var5;
    if ((var6 < arg1)) {
        goto L_1136;
    }
    L_1120: ;
    return (unsigned int)((var5 + 1));
    L_1128: ;
    ret = 0xffffffff;
    L_112d: ;
    return ret;
    L_1130: ;
    var5 = 0;
    var8 = 0;
    var7 = (unsigned long)((unsigned int)(i));
    if ((arg1 <= i)) {
        goto L_1120;
    }
    L_1136: ;
    ret = (unsigned long)((unsigned int)((var8 ^ (unsigned int)((unsigned char)(((unsigned long)((unsigned int)((var7 + arg0))) & 255))))));
    i = (unsigned long)((unsigned int)((var7 + 1)));
    goto L_1112;
}

← 213 fixtures