Fixture 11

call shapes

C · 13 functions · 4 lanes · 52 of 52 function-lanes behave identically

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

Call-boundary fixture: what a function's *signature* means when values flow through it. 06_calling_conventions.c proves arguments arrive in the right order; this file proves the recovered widths and the call result survive.

The corpus previously had almost no function whose declared parameter width mattered across a call, so a decompiler that widened, narrowed, or dropped a call result kept passing. Every function here consumes a callee's return value in a way that changes the answer if the width is wrong: a 64-bit product of two 32-bit arguments, a byte that must wrap at 8 bits, a result compared against a boundary, an accumulator fed by a call inside a loop.

All parameters and returns are integer and all callees are external symbols, so every function is differential-testable and portable across SysV x86-64, Win64, x86-32 cdecl and AAPCS64. Deterministic, terminating, no libc.

Targets review #20 (call-heavy corpus gap).

tests/decompiler_fixtures/src/11_call_shapes.c source
/* 11_call_shapes.c
 *
 * Call-boundary fixture: what a function's *signature* means when values flow
 * through it. `06_calling_conventions.c` proves arguments arrive in the right
 * order; this file proves the recovered widths and the call result survive.
 *
 * The corpus previously had almost no function whose declared parameter width
 * mattered across a call, so a decompiler that widened, narrowed, or dropped a
 * call result kept passing. Every function here consumes a callee's return value
 * in a way that changes the answer if the width is wrong: a 64-bit product of
 * two 32-bit arguments, a byte that must wrap at 8 bits, a result compared
 * against a boundary, an accumulator fed by a call inside a loop.
 *
 * All parameters and returns are integer and all callees are external symbols,
 * so every function is differential-testable and portable across SysV x86-64,
 * Win64, x86-32 cdecl and AAPCS64. Deterministic, terminating, no libc.
 *
 * Targets review #20 (call-heavy corpus gap).
 */
#include <stdint.h>

/* --- callees ----------------------------------------------------------- */
/* Not `static`: the harness drives functions by exported symbol, and a callee
 * that is itself checked is a callee whose own recovery is proven. */

/* Widening callee: the product genuinely needs 64 bits. A caller that keeps
 * this result in 32 bits loses the high half. */
uint64_t widen_mul(uint32_t a, uint32_t b) {
    return (uint64_t)a * (uint64_t)b;
}

/* Narrowing callee: wraps at 8 bits. A caller that treats the result as 32-bit
 * sees values this function can never return. */
uint8_t wrap_byte(uint32_t x) {
    return (uint8_t)(x * 31u + 7u);
}

/* Sign-extending callee: negative results must stay negative through the ABI's
 * 64-bit return register. */
int32_t signed_step(int32_t x) {
    return x - 1000;
}

/* A callee with stack arguments under every ABI here, returning a combination
 * that changes if any argument is dropped or reordered. */
int spill_combine(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7) {
    return a0 + 2 * a1 + 3 * a2 + 4 * a3 + 5 * a4 + 6 * a5 + 7 * a6 + 8 * a7;
}

/* --- callers ----------------------------------------------------------- */

/* The call result is 64 bits wide; folding both halves detects a caller that
 * truncated it to the 32-bit return register view. */
int call_fold_wide_result(uint32_t a, uint32_t b) {
    uint64_t r = widen_mul(a, b);
    return (int)((r >> 32) ^ (r & 0xFFFFFFFFu));
}

/* The result must wrap at 8 bits *before* it is widened: a caller that keeps
 * the callee's full 32-bit register value gets a different sum. */
int call_accumulate_bytes(uint32_t seed, int count) {
    uint32_t acc = 0;
    int n = count & 15;                 /* bounded: the verdict cannot depend on time */
    for (int i = 0; i < n; i++) {
        acc += wrap_byte(seed + (uint32_t)i);
    }
    return (int)acc;
}

/* A negative call result compared against a boundary. Zero-extending the
 * callee's 32-bit return into 64 bits makes every comparison take the wrong arm. */
int call_result_drives_branch(int32_t x) {
    int32_t r = signed_step(x);
    if (r < 0) {
        return -r;
    }
    return r + 1;
}

/* Nested calls: the inner result is an argument to the outer call, so an
 * argument/return mix-up is visible in the answer. */
int call_nested(uint32_t a, uint32_t b) {
    uint64_t r = widen_mul(wrap_byte(a), wrap_byte(b));
    return (int)(r & 0xFFFFFFFFu);
}

/* Two calls whose results are combined. A caller that reuses one call's result
 * register for both — the classic "a call defines nothing" bug — returns twice
 * the second value instead of a mix. */
int call_twice_and_combine(int32_t x, int32_t y) {
    int32_t p = signed_step(x);
    int32_t q = signed_step(y);
    return p * 3 + q;
}

/* A call result feeding a stack-argument call: the return value must survive
 * being spilled and reloaded across the argument setup. */
int call_into_spill(int a0, int a1) {
    int r = signed_step(a0);
    return spill_combine(r, a1, r + 1, a1 + 2, r + 3, a1 + 4, r + 5, a1 + 6);
}

/* A call inside a loop whose result feeds the next iteration's argument, so the
 * result cannot be hoisted, folded, or read from a stale register. */
int call_chain_in_loop(int32_t seed, int rounds) {
    int32_t v = seed;
    int n = rounds & 7;                 /* bounded */
    for (int i = 0; i < n; i++) {
        v = signed_step(v) + i;
    }
    return v;
}

/* The call result is used exactly once, as a return value. A decompiler that
 * drops the call entirely still has to produce this number. */
int call_forward_result(int32_t x) {
    return signed_step(x);
}

/* The first call's result is deliberately UNUSED. `signed_step` is pure, so an
 * optimising build is free to delete the call outright — which is the point: the
 * returned value must be the same whether the call survives or not, and nothing
 * may attribute the *second* call's result to the first. */
int call_result_unused(int32_t x) {
    signed_step(x);
    return signed_step(x + 1);
}

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

13/13
call_accumulate_bytes pass 17 lines
// glaurung: call_accumulate_bytes @ 0x1240
int call_accumulate_bytes(uint32_t arg0, int arg1) {
    extern unsigned char wrap_byte(unsigned int);
    unsigned int acc;
    int n;
    int i;
    unsigned char var6;
    // x86-64 prologue: save rbp, frame 32 bytes
    acc = 0;
    n = ((unsigned int)(arg1) & 15);
    for (i = 0; (i < n); i++) {
        var6 = wrap_byte((unsigned long)((unsigned int)((arg0 + i))));
        acc = ((unsigned int)((unsigned char)((var6 & 255))) + acc);
    }
    // x86-64 epilogue: restore rbp
    return acc;
}
call_chain_in_loop pass 17 lines
// glaurung: call_chain_in_loop @ 0x13d0
int call_chain_in_loop(int32_t arg0, int arg1) {
    extern int signed_step(int);
    int v;
    int n;
    int i;
    int var5;
    // x86-64 prologue: save rbp, frame 32 bytes
    v = arg0;
    n = ((unsigned int)(arg1) & 7);
    for (i = 0; (i < n); i++) {
        var5 = signed_step((unsigned long)((unsigned int)(v)));
        v = (var5 + i);
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(v);
}
call_fold_wide_result pass 11 lines
// glaurung: call_fold_wide_result @ 0x1200
int call_fold_wide_result(uint32_t arg0, uint32_t arg1) {
    extern unsigned long widen_mul(unsigned int, unsigned int);
    unsigned long r;
    unsigned long var0;
    // x86-64 prologue: save rbp, frame 16 bytes
    var0 = widen_mul(arg0, arg1);
    r = var0;
    // x86-64 epilogue: restore rbp
    return (((unsigned long)(r) >> 32) ^ (0xffffffff & r));
}
call_forward_result pass 9 lines
// glaurung: call_forward_result @ 0x1430
int call_forward_result(int32_t arg0) {
    extern int signed_step(int);
    int ret;
    // x86-64 prologue: save rbp, frame 16 bytes
    ret = signed_step((unsigned long)((unsigned int)(arg0)));
    // x86-64 epilogue: restore rbp
    return ret;
}
call_into_spill pass 14 lines
// glaurung: call_into_spill @ 0x1370
int call_into_spill(int arg0, int arg1) {
    extern int signed_step(int);
    extern int spill_combine(int, int, int, int, int, int, int, int);
    int r;
    int ret;
    int var0;
    // x86-64 prologue: save rbp, frame 32 bytes
    var0 = signed_step((unsigned long)((unsigned int)(arg0)));
    r = var0;
    ret = ((int (*)(long, long, long, long, long, long, long, long))spill_combine)((unsigned long)((unsigned int)(r)), (unsigned long)((unsigned int)(arg1)), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(r)) + 1))), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + 2))), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(r)) + 3))), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + 4))), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(r)) + 5))), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + 6))));
    // x86-64 epilogue: restore rbp
    return ret;
}
call_nested pass 18 lines
// glaurung: call_nested @ 0x12e0
int call_nested(uint32_t arg0, uint32_t arg1) {
    extern unsigned long widen_mul(unsigned int, unsigned int);
    extern unsigned char wrap_byte(unsigned int);
    unsigned long r;
    int local_14;
    unsigned char var0;
    unsigned char var3;
    unsigned long var5;
    // x86-64 prologue: save rbp, frame 32 bytes
    var0 = wrap_byte(arg0);
    local_14 = (unsigned char)((var0 & 255));
    var3 = wrap_byte(arg1);
    var5 = widen_mul((unsigned long)((unsigned int)(local_14)), (unsigned int)((unsigned char)((var3 & 255))));
    r = var5;
    // x86-64 epilogue: restore rbp
    return (0xffffffff & r);
}
call_result_drives_branch pass 14 lines
// glaurung: call_result_drives_branch @ 0x12a0
int call_result_drives_branch(int32_t arg0) {
    extern int signed_step(int);
    int r;
    int var0;
    // x86-64 prologue: save rbp, frame 16 bytes
    var0 = signed_step((unsigned long)((unsigned int)(arg0)));
    r = var0;
    if ((0 <= (long)(r))) {
        return (unsigned int)(((unsigned long)((unsigned int)(r)) + 1));
    } else {
        return (unsigned int)((0 - r));
    }
}
call_result_unused pass 11 lines
// glaurung: call_result_unused @ 0x1450
int call_result_unused(int32_t arg0) {
    extern int signed_step(int);
    int ret;
    int var0;
    // x86-64 prologue: save rbp, frame 16 bytes
    var0 = signed_step((unsigned long)((unsigned int)(arg0)));
    ret = signed_step((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + 1))));
    // x86-64 epilogue: restore rbp
    return ret;
}
call_twice_and_combine pass 15 lines
// glaurung: call_twice_and_combine @ 0x1330
int call_twice_and_combine(int32_t arg0, int32_t arg1) {
    extern int signed_step(int);
    int p;
    int q;
    int var0;
    int var2;
    // x86-64 prologue: save rbp, frame 16 bytes
    var0 = signed_step((unsigned long)((unsigned int)(arg0)));
    p = var0;
    var2 = signed_step((unsigned long)((unsigned int)(arg1)));
    q = var2;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((p * 3) + q));
}
signed_step pass 6 lines
// glaurung: signed_step @ 0x1180
int32_t signed_step(int32_t arg0) {
    // x86-64 prologue: save rbp
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned long)((unsigned int)(arg0)) - 1000));
}
spill_combine pass 6 lines
// glaurung: spill_combine @ 0x11a0
int spill_combine(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) {
    // x86-64 prologue: save rbp
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) << 1)))))) + (arg2 * 3)))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg3)) << 2)))))) + (arg4 * 5)))) + (arg5 * 6)))) + (arg6 * 7)))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg7)) << 3)))));
}
widen_mul pass 6 lines
// glaurung: widen_mul @ 0x1140
uint64_t widen_mul(uint32_t arg0, uint32_t arg1) {
    // x86-64 prologue: save rbp
    // x86-64 epilogue: restore rbp
    return ((unsigned long)(arg0) * (unsigned long)(arg1));
}
wrap_byte pass 6 lines
// glaurung: wrap_byte @ 0x1160
uint8_t wrap_byte(uint32_t arg0) {
    // x86-64 prologue: save rbp
    // x86-64 epilogue: restore rbp
    return (unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((arg0 * 31) + 7))) & 255)));
}

clang -O2

13/13
call_accumulate_bytes pass 100 lines
// glaurung: call_accumulate_bytes @ 0x1190
int call_accumulate_bytes(uint32_t arg0, int arg1) {
    int n;
    int i;
    int var0;
    int var12;
    int var122;
    int var123;
    int var124;
    int var125;
    int var13;
    int var14;
    int var15;
    int var34;
    int var35;
    int var36;
    int var37;
    int var46;
    int var47;
    int var48;
    int var49;
    long var5;
    int var63;
    int var64;
    int var65;
    int var66;
    long var68;
    int var95;
    int var96;
    int var97;
    int var98;
    var0 = (arg1 & 15);
    if (((unsigned long)((unsigned int)(var0)) == 0)) {
        return 0;
    }
    var5 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) + 3))) & 28)));
    n = ((unsigned int)(var0) - 1);
    var12 = (unsigned long)((unsigned int)(n));
    var13 = (unsigned long)((unsigned int)(n));
    var14 = (unsigned long)((unsigned int)(n));
    var15 = (unsigned long)((unsigned int)(n));
    var34 = ((arg0 << 5) - arg0);
    var35 = ((arg0 << 5) - arg0);
    var36 = ((arg0 << 5) - arg0);
    var37 = ((arg0 << 5) - arg0);
    var46 = ((7 + var34) & 255);
    var47 = ((38 + var35) & 255);
    var48 = ((69 + var36) & 255);
    var49 = ((100 + var37) & 255);
    if (((unsigned long)((unsigned int)(var5)) != 4)) {
        var63 = (((131 + var34) & 255) + var46);
        var64 = (((162 + var35) & 255) + var47);
        var65 = (((193 + var36) & 255) + var48);
        var66 = (((224 + var37) & 255) + var49);
        var68 = 4;
        if (((unsigned long)((unsigned int)(var5)) != 8)) {
            var46 = (((255 + var34) & 255) + var63);
            var47 = (((286 + var35) & 255) + var64);
            var48 = (((317 + var36) & 255) + var65);
            var49 = (((348 + var37) & 255) + var66);
            var68 = 8;
            if (((unsigned long)((unsigned int)(var5)) != 12)) {
                var68 = 12;
                var95 = var46;
                var96 = var47;
                var97 = var48;
                var98 = var49;
                var46 = (((var34 + 379) & 255) + var46);
                var47 = (((var35 + 410) & 255) + var47);
                var48 = (((var36 + 441) & 255) + var48);
                var49 = (((var37 + 472) & 255) + var49);
            } else {
                var95 = var63;
                var96 = var64;
                var97 = var65;
                var98 = var66;
            }
        } else {
            var95 = var46;
            var96 = var47;
            var97 = var48;
            var98 = var49;
            var46 = var63;
            var47 = var64;
            var48 = var65;
            var49 = var66;
        }
    } else {
        var95 = 0;
        var96 = 0;
        var97 = 0;
        var98 = 0;
        var68 = 0;
    }
    var122 = (-((var12 ^ 0x80000000) < (var68 | 0x80000000)));
    var123 = (-((var13 ^ 0x80000000) < (var68 | 0x80000001)));
    var124 = (-((var14 ^ 0x80000000) < (var68 | 0x80000002)));
    var125 = (-((var15 ^ 0x80000000) < (var68 | 0x80000003)));
    return (unsigned int)((((((~var125) & var49) | (var98 & var125)) + (((~var123) & var47) | (var96 & var123))) + ((((~var124) & var48) | (var97 & var124)) + (((~var122) & var46) | (var95 & var122)))));
}
call_chain_in_loop pass 14 lines
// glaurung: call_chain_in_loop @ 0x1310
int call_chain_in_loop(int32_t arg0, int arg1) {
    int n;
    int i;
    long ret;
    int var0;
    ret = (unsigned long)((unsigned int)(arg0));
    var0 = (arg1 & 7);
    n = (unsigned long)((unsigned int)(var0));
    if (((unsigned long)((unsigned int)(var0)) != 0)) {
        ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((n * -999) + (unsigned long)((unsigned int)((((unsigned long)(((unsigned long)((unsigned int)((n - 2))) * (unsigned long)((unsigned int)((n - 1))))) >> 1) + ret)))))) - 1)));
    }
    return ret;
}
call_fold_wide_result pass 6 lines
// glaurung: call_fold_wide_result @ 0x1170
int call_fold_wide_result(uint32_t arg0, uint32_t arg1) {
    unsigned long r;
    r = ((unsigned long)(arg1) * (unsigned long)(arg0));
    return (unsigned int)((((unsigned long)(r) >> 32) ^ r));
}
call_forward_result pass 4 lines
// glaurung: call_forward_result @ 0x1340
int call_forward_result(int32_t arg0) {
    return (unsigned int)((arg0 - 1000));
}
call_into_spill pass 6 lines
// glaurung: call_into_spill @ 0x12f0
int call_into_spill(int arg0, int arg1) {
    long var1;
    var1 = (unsigned long)((unsigned int)((arg0 + (arg0 * 4))));
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var1 + (var1 * 2)))) + arg0))) + ((unsigned long)((unsigned int)((arg1 + (arg1 * 4)))) * 4)))) - 0x3dfb));
}
call_nested pass 4 lines
// glaurung: call_nested @ 0x12c0
int call_nested(uint32_t arg0, uint32_t arg1) {
    return (unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(arg1) << 5))) - arg1))) + 7))) & 255))) * (unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(arg0) << 5))) - arg0))) + 7))) & 255)))));
}
call_result_drives_branch pass 4 lines
// glaurung: call_result_drives_branch @ 0x12a0
int call_result_drives_branch(int32_t arg0) {
    return (((long)(arg0) < 1000) ? (-(unsigned long)((unsigned int)((arg0 - 1000)))) : (unsigned long)((unsigned int)((arg0 - 999))));
}
call_result_unused pass 4 lines
// glaurung: call_result_unused @ 0x1350
int call_result_unused(int32_t arg0) {
    return (unsigned int)((arg0 - 999));
}
call_twice_and_combine pass 4 lines
// glaurung: call_twice_and_combine @ 0x12e0
int call_twice_and_combine(int32_t arg0, int32_t arg1) {
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + (arg0 * 2)))) + arg1))) - 4000));
}
signed_step pass 4 lines
// glaurung: signed_step @ 0x1120
int32_t signed_step(int32_t arg0) {
    return (unsigned int)((arg0 - 1000));
}
spill_combine pass 4 lines
// glaurung: spill_combine @ 0x1130
int spill_combine(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) {
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg6)) * 8))) - (unsigned long)((unsigned int)(arg6))))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg4 + (arg4 * 4)))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg2 + (arg2 * 2)))) + (unsigned long)((unsigned int)((arg0 + (arg1 * 2))))))) + (arg3 * 4))))))) + ((unsigned long)((unsigned int)((arg5 + (arg5 * 2)))) * 2))))))) + ((unsigned long)((unsigned int)(arg7)) * 8)));
}
widen_mul pass 4 lines
// glaurung: widen_mul @ 0x1100
uint64_t widen_mul(uint32_t arg0, uint32_t arg1) {
    return ((unsigned long)(arg1) * (unsigned long)(arg0));
}
wrap_byte pass 6 lines
// glaurung: wrap_byte @ 0x1110
uint8_t wrap_byte(uint32_t arg0) {
    long var4;
    var4 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 << 5))) - arg0)));
    return ((var4 & -256) | (((var4 & 255) + 7) & 255));
}

gcc -O0

13/13
call_accumulate_bytes pass 17 lines
// glaurung: call_accumulate_bytes @ 0x1268
int call_accumulate_bytes(uint32_t arg0, int arg1) {
    extern unsigned char wrap_byte(unsigned int);
    unsigned int acc;
    int n;
    int i;
    unsigned char var8;
    // x86-64 prologue: save rbp, frame 32 bytes
    acc = 0;
    n = ((unsigned int)(arg1) & 15);
    for (i = 0; (i < n); i++) {
        var8 = wrap_byte((unsigned long)((unsigned int)((arg0 + (unsigned long)((unsigned int)(i))))));
        acc = (acc + (unsigned int)((unsigned char)((var8 & 255))));
    }
    // x86-64 epilogue: restore rbp
    return acc;
}
call_chain_in_loop pass 17 lines
// glaurung: call_chain_in_loop @ 0x13c9
int call_chain_in_loop(int32_t arg0, int arg1) {
    extern int signed_step(int);
    int v;
    int n;
    int i;
    int var8;
    // x86-64 prologue: save rbp, frame 32 bytes
    v = arg0;
    n = ((unsigned int)(arg1) & 7);
    for (i = 0; (i < n); i++) {
        var8 = signed_step((unsigned long)((unsigned int)(v)));
        v = (var8 + (unsigned int)(i));
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(v);
}
call_fold_wide_result pass 11 lines
// glaurung: call_fold_wide_result @ 0x1231
int call_fold_wide_result(uint32_t arg0, uint32_t arg1) {
    extern unsigned long widen_mul(unsigned int, unsigned int);
    unsigned long r;
    unsigned long var2;
    // x86-64 prologue: save rbp, frame 32 bytes
    var2 = widen_mul(arg0, arg1);
    r = var2;
    // x86-64 epilogue: restore rbp
    return (unsigned int)((r ^ (unsigned long)((unsigned int)(((unsigned long)(r) >> 32)))));
}
call_forward_result pass 9 lines
// glaurung: call_forward_result @ 0x1416
int call_forward_result(int32_t arg0) {
    extern int signed_step(int);
    int ret;
    // x86-64 prologue: save rbp, frame 16 bytes
    ret = signed_step((unsigned long)((unsigned int)(arg0)));
    // x86-64 epilogue: restore rbp
    return ret;
}
call_into_spill pass 14 lines
// glaurung: call_into_spill @ 0x136a
int call_into_spill(int arg0, int arg1) {
    extern int signed_step(int);
    extern int spill_combine(int, int, int, int, int, int, int, int);
    int r;
    int ret;
    int var1;
    // x86-64 prologue: save rbp, frame 32 bytes
    var1 = signed_step((unsigned long)((unsigned int)(arg0)));
    r = var1;
    ret = ((int (*)(long, long, long, long, long, long, long, long))spill_combine)((unsigned long)((unsigned int)(r)), (unsigned long)((unsigned int)(arg1)), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(r)) + 1))), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + 2))), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(r)) + 3))), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + 4))), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(r)) + 5))), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + 6))));
    // x86-64 epilogue: restore rbp
    return ret;
}
call_nested pass 18 lines
// glaurung: call_nested @ 0x12ea
int call_nested(uint32_t arg0, uint32_t arg1) {
    extern unsigned long widen_mul(unsigned int, unsigned int);
    extern unsigned char wrap_byte(unsigned int);
    unsigned long r;
    unsigned char var1;
    int var3;
    unsigned char var5;
    unsigned long var8;
    // x86-64 prologue: save rbp, frame 8 bytes
    var1 = wrap_byte(arg1);
    var3 = (unsigned int)((unsigned char)((var1 & 255)));
    var5 = wrap_byte(arg0);
    var8 = widen_mul((unsigned long)((unsigned int)((unsigned char)((var5 & 255)))), (unsigned long)((unsigned int)(var3)));
    r = var8;
    // x86-64 epilogue: restore rbp
    return r;
}
call_result_drives_branch pass 14 lines
// glaurung: call_result_drives_branch @ 0x12b9
int call_result_drives_branch(int32_t arg0) {
    extern int signed_step(int);
    int r;
    int var1;
    // x86-64 prologue: save rbp, frame 32 bytes
    var1 = signed_step((unsigned long)((unsigned int)(arg0)));
    r = var1;
    if ((0 <= (long)(r))) {
        return (unsigned int)(((unsigned long)((unsigned int)(r)) + 1));
    } else {
        return (-(unsigned long)((unsigned int)(r)));
    }
}
call_result_unused pass 11 lines
// glaurung: call_result_unused @ 0x1431
int call_result_unused(int32_t arg0) {
    extern int signed_step(int);
    int ret;
    int var1;
    // x86-64 prologue: save rbp, frame 16 bytes
    var1 = signed_step((unsigned long)((unsigned int)(arg0)));
    ret = signed_step((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + 1))));
    // x86-64 epilogue: restore rbp
    return ret;
}
call_twice_and_combine pass 15 lines
// glaurung: call_twice_and_combine @ 0x132e
int call_twice_and_combine(int32_t arg0, int32_t arg1) {
    extern int signed_step(int);
    int p;
    int q;
    int var1;
    int var4;
    // x86-64 prologue: save rbp, frame 32 bytes
    var1 = signed_step((unsigned long)((unsigned int)(arg0)));
    p = var1;
    var4 = signed_step((unsigned long)((unsigned int)(arg1)));
    q = var4;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned long)((unsigned int)(q)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(p)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(p)) + (unsigned long)((unsigned int)(p))))))))));
}
signed_step pass 6 lines
// glaurung: signed_step @ 0x11af
int32_t signed_step(int32_t arg0) {
    // x86-64 prologue: save rbp
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned long)((unsigned int)(arg0)) - 1000));
}
spill_combine pass 8 lines
// glaurung: spill_combine @ 0x11c4
int spill_combine(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) {
    int var27;
    // x86-64 prologue: save rbp
    var27 = ((unsigned int)(((unsigned long)((unsigned int)(arg5)) + (unsigned long)((unsigned int)(arg5)))) + (unsigned int)(arg5));
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg7)) << 3))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + (unsigned long)((unsigned int)(arg1))))) + (unsigned long)((unsigned int)(arg0))))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) + (unsigned long)((unsigned int)(arg2))))) + (unsigned long)((unsigned int)(arg2)))))))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg3)) << 2)))))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg4)) << 2))) + (unsigned long)((unsigned int)(arg4)))))))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var27)) + (unsigned long)((unsigned int)(var27)))))))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg6)) << 3))) - (unsigned long)((unsigned int)(arg6))))))))));
}
widen_mul pass 6 lines
// glaurung: widen_mul @ 0x1179
uint64_t widen_mul(uint32_t arg0, uint32_t arg1) {
    // x86-64 prologue: save rbp
    // x86-64 epilogue: restore rbp
    return ((unsigned long)(arg1) * (unsigned long)(arg0));
}
wrap_byte pass 6 lines
// glaurung: wrap_byte @ 0x1193
uint8_t wrap_byte(uint32_t arg0) {
    // x86-64 prologue: save rbp
    // x86-64 epilogue: restore rbp
    return (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(arg0) << 5))) - (unsigned long)(arg0)))) + 7)));
}

gcc -O2

13/13
call_accumulate_bytes pass 30 lines
// glaurung: call_accumulate_bytes @ 0x1210
int call_accumulate_bytes(uint32_t arg0, int arg1) {
    extern unsigned char wrap_byte(unsigned int);
    int n;
    unsigned int acc;
    int i;
    int var1;
    long var2;
    long var5;
    long var6;
    long var7;
    unsigned char var9;
    var1 = ((unsigned int)(arg1) & 15);
    n = (unsigned long)((unsigned int)(var1));
    if (((unsigned long)((unsigned int)(var1)) == 0)) {
        return n;
    }
    var2 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var1)) + arg0)));
    var5 = (unsigned long)(arg0);
    var6 = 0;
    do {
        var7 = (unsigned long)((unsigned int)(var5));
        var5 = (unsigned long)((unsigned int)((var5 + 1)));
        var9 = wrap_byte(var7);
        var6 = (unsigned long)((unsigned int)((var6 + (unsigned int)((unsigned char)((var9 & 255))))));
    } while (((unsigned int)(var2) != (unsigned int)(var5)));
    n = (unsigned long)((unsigned int)(var6));
    // x86-64 epilogue: tear down frame
    return (unsigned int)(var6);
}
call_chain_in_loop pass 28 lines
// glaurung: call_chain_in_loop @ 0x1310
int call_chain_in_loop(int32_t arg0, int arg1) {
    extern int signed_step(int);
    int n;
    int i;
    int v;
    int var0;
    int var10;
    long var6;
    int var7;
    long var9;
    var0 = (arg1 & 7);
    if (((unsigned long)((unsigned int)(var0)) == 0)) {
        return (unsigned int)(arg0);
    }
    n = (unsigned long)((unsigned int)(var0));
    i = 0;
    var6 = (unsigned long)((unsigned int)(arg0));
    do {
        var7 = signed_step(var6);
        var9 = (unsigned long)((unsigned int)((var7 + i)));
        var10 = (i + 1);
        i = (unsigned long)((unsigned int)(var10));
        var6 = var9;
    } while (((unsigned int)(n) != (unsigned int)(var10)));
    // x86-64 epilogue: tear down frame
    return (unsigned int)(var9);
}
call_fold_wide_result pass 8 lines
// glaurung: call_fold_wide_result @ 0x11f0
int call_fold_wide_result(uint32_t arg0, uint32_t arg1) {
    extern unsigned long widen_mul(unsigned int, unsigned int);
    unsigned long r;
    unsigned long var0;
    var0 = widen_mul(arg0, arg1);
    return (unsigned int)((((unsigned long)(var0) >> 32) ^ var0));
}
call_forward_result pass 7 lines
// glaurung: call_forward_result @ 0x1350
int call_forward_result(int32_t arg0) {
    extern int signed_step(int);
    int ret;
    ret = signed_step(arg0);
    return ret;
}
call_into_spill pass 14 lines
// glaurung: call_into_spill @ 0x12e0
int call_into_spill(int arg0, int arg1) {
    extern int signed_step(int);
    extern int spill_combine(int, int, int, int, int, int, int, int);
    int r;
    int ret;
    long var0;
    int var1;
    var0 = (unsigned long)((unsigned int)(arg1));
    var1 = signed_step(arg0);
    ret = ((int (*)(long, long, long, long, long, long, long, long))spill_combine)((unsigned long)((unsigned int)(var1)), (unsigned long)((unsigned int)(var0)), (unsigned long)((unsigned int)((var1 + 1))), (unsigned long)((unsigned int)((var0 + 2))), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var1)) + 3))), (unsigned long)((unsigned int)((var0 + 4))), (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var1)) + 5))), (unsigned long)((unsigned int)((var0 + 6))));
    // x86-64 epilogue: tear down frame
    return ret;
}
call_nested pass 18 lines
// glaurung: call_nested @ 0x1280
int call_nested(uint32_t arg0, uint32_t arg1) {
    extern unsigned long widen_mul(unsigned int, unsigned int);
    extern unsigned char wrap_byte(unsigned int);
    unsigned long r;
    unsigned long ret;
    long var0;
    unsigned char var1;
    long var3;
    unsigned char var4;
    var0 = (unsigned long)(arg0);
    var1 = wrap_byte(arg1);
    var3 = (unsigned long)((unsigned int)((unsigned int)(var1)));
    var4 = wrap_byte((unsigned long)((unsigned int)(var0)));
    ret = widen_mul((unsigned int)((unsigned char)((var4 & 255))), (unsigned int)((unsigned char)((var3 & 255))));
    // x86-64 epilogue: tear down frame
    return ret;
}
call_result_drives_branch pass 8 lines
// glaurung: call_result_drives_branch @ 0x1260
int call_result_drives_branch(int32_t arg0) {
    extern int signed_step(int);
    int r;
    int var0;
    var0 = signed_step(arg0);
    return ((0 <= (long)((int)(var0))) ? (unsigned long)((unsigned int)((var0 + 1))) : (unsigned long)((unsigned int)((-(unsigned long)((unsigned int)(var0))))));
}
call_result_unused pass 11 lines
// glaurung: call_result_unused @ 0x1360
int call_result_unused(int32_t arg0) {
    extern int signed_step(int);
    int ret;
    long var0;
    int var1;
    var0 = (unsigned long)((unsigned int)(arg0));
    var1 = signed_step(arg0);
    ret = signed_step((unsigned long)((unsigned int)((var0 + 1))));
    return ret;
}
call_twice_and_combine pass 14 lines
// glaurung: call_twice_and_combine @ 0x12b0
int call_twice_and_combine(int32_t arg0, int32_t arg1) {
    extern int signed_step(int);
    int p;
    int q;
    long var0;
    int var1;
    int var4;
    var0 = (unsigned long)((unsigned int)(arg1));
    var1 = signed_step(arg0);
    p = (unsigned long)((unsigned int)(var1));
    var4 = signed_step((unsigned long)((unsigned int)(var0)));
    return (unsigned int)(((unsigned long)((unsigned int)((p + (p * 2)))) + (unsigned long)((unsigned int)(var4))));
}
signed_step pass 4 lines
// glaurung: signed_step @ 0x11a0
int32_t signed_step(int32_t arg0) {
    return (unsigned int)((arg0 - 1000));
}
spill_combine pass 4 lines
// glaurung: spill_combine @ 0x11b0
int spill_combine(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) {
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + (arg1 * 2)))) + (unsigned long)((unsigned int)((arg2 + (arg2 * 2))))))) + ((unsigned long)((unsigned int)(arg3)) * 4)))) + (unsigned long)((unsigned int)((arg4 + (arg4 * 4))))))) + ((unsigned long)((unsigned int)((arg5 + (arg5 * 2)))) * 2)))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg6)) * 8))) - (unsigned long)((unsigned int)(arg6)))))))) + ((unsigned long)((unsigned int)(arg7)) * 8)));
}
widen_mul pass 4 lines
// glaurung: widen_mul @ 0x1180
uint64_t widen_mul(uint32_t arg0, uint32_t arg1) {
    return ((unsigned long)(arg0) * (unsigned long)(arg1));
}
wrap_byte pass 4 lines
// glaurung: wrap_byte @ 0x1190
uint8_t wrap_byte(uint32_t arg0) {
    return (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(arg0) << 5))) - arg0))) + 7)));
}

← 213 fixtures