Fixture 143

dynamic frames

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

4 of 4 lanes have a function that returns a different result after decompilation: clang-O0 (1/3), clang-O2 (1/3), gcc-O0 (1/3), gcc-O2 (1/3).

alloca moves the stack pointer at runtime, so the frame has no fixed size and locals below it are addressed through a saved base. __attribute__((cleanup)) generates a destructor-like call on every exit path, including early returns, which is control flow the source never spells out.

tests/decompiler_fixtures/src/143_dynamic_frames.c source
#include <stdint.h>
#include <alloca.h>

/* alloca moves the stack pointer at runtime, so the frame has no fixed size and
 * locals below it are addressed through a saved base. __attribute__((cleanup))
 * generates a destructor-like call on every exit path, including early returns,
 * which is control flow the source never spells out. */

static void record_cleanup(int32_t *slot) {
    *slot += 1000;
}

__attribute__((noinline)) int32_t alloca_dynamic_frame(int32_t count,
                                                       int32_t seed) {
    int32_t *scratch;
    int32_t index;
    int32_t total = 0;
    if (count < 1 || count > 16) {
        return -1;
    }
    scratch = (int32_t *)alloca((size_t)count * sizeof(int32_t));
    for (index = 0; index < count; ++index) {
        scratch[index] = seed + index;
    }
    for (index = 0; index < count; ++index) {
        total += scratch[index];
    }
    return total;
}

__attribute__((noinline)) int32_t alloca_in_loop(int32_t rounds, int32_t width) {
    int32_t total = 0;
    int32_t round;
    if (rounds < 0 || rounds > 4 || width < 1 || width > 8) {
        return -1;
    }
    for (round = 0; round < rounds; ++round) {
        /* Each iteration extends the frame further; it is released once, at
         * function exit, not per iteration. */
        int32_t *chunk = (int32_t *)alloca((size_t)width * sizeof(int32_t));
        int32_t index;
        for (index = 0; index < width; ++index) {
            chunk[index] = round * width + index;
        }
        total += chunk[width - 1];
    }
    return total;
}

__attribute__((noinline)) int32_t cleanup_on_every_exit(int32_t *observed,
                                                        int32_t selector) {
    if (observed == 0) {
        return -1;
    }
    *observed = 0;
    {
        int32_t guarded __attribute__((cleanup(record_cleanup))) = 0;
        guarded = selector;
        if (selector & 1) {
            return guarded; /* cleanup still runs before returning */
        }
        if (selector & 2) {
            return guarded * 2;
        }
    }
    return selector * 3;
}

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

1/3
alloca_dynamic_frame fail 33 lines
// glaurung: alloca_dynamic_frame @ 0x1100
int32_t alloca_dynamic_frame(int32_t arg0, int32_t arg1) {
    int total;
    int * scratch;
    int index;
    int local_4;
    long rsp;
    long var4;
    // x86-64 prologue: save rbp, frame 32 bytes
    total = 0;
    if (((long)(arg0) < 1)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg0)) == 16) | ((long)(arg0) < 16)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    var4 = (rsp - ((((long)(arg0) * 4) + 15) & -16));
    rsp = var4;
    scratch = (int *)(var4);
    for (index = 0; (index < arg0); index++) {
        scratch[(long)(index)] = ((unsigned long)((unsigned int)(arg1)) + index);
    }
    for (index = 0; (index < arg0); index++) {
        total = ((unsigned int)(scratch[(long)(index)]) + total);
    }
    local_4 = total;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
alloca_in_loop fail 46 lines
// glaurung: alloca_in_loop @ 0x11d0
int32_t alloca_in_loop(int32_t arg0, int32_t arg1) {
    int total;
    int round;
    int * chunk;
    int index;
    int local_4;
    long rsp;
    long var5;
    // x86-64 prologue: save rbp, frame 48 bytes
    total = 0;
    if (((long)(arg0) < 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg0)) == 4) | ((long)(arg0) < 4)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg1) < 1)) {
        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);
    }
    round = 0;
    while ((round < arg0)) {
        var5 = (rsp - ((((long)(arg1) * 4) + 15) & -16));
        rsp = var5;
        chunk = (int *)(var5);
        for (index = 0; (index < arg1); index++) {
            chunk[(long)(index)] = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(round)) * arg1))) + index);
        }
        total = ((unsigned int)(chunk[(long)((int)(((unsigned long)((unsigned int)(arg1)) - 1)))]) + total);
        round = ((unsigned int)(round) + 1);
    }
    local_4 = total;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
cleanup_on_every_exit pass 33 lines
// glaurung: cleanup_on_every_exit @ 0x12c0
__attribute__((no_stack_protector)) int32_t cleanup_on_every_exit(int32_t * arg0, int32_t arg1) {
    extern void record_cleanup(int *);
    unsigned char guarded[4];
    int local_1c;
    int local_4;
    // x86-64 prologue: save rbp, frame 32 bytes
    if ((arg0 != 0)) {
        *(int *)((long)arg0) = 0;
        *(int *)(&guarded[0]) = 0;
        *(int *)(&guarded[0]) = arg1;
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 1))) == 0)) {
            if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 2))) == 0)) {
                local_1c = 0;
            } else {
                local_4 = ((unsigned long)((unsigned int)(*(int *)(&guarded[0]))) << 1);
                local_1c = 1;
            }
        } else {
            local_4 = *(int *)(&guarded[0]);
            local_1c = 1;
        }
        record_cleanup((int *)(&guarded[0]));
        if (((unsigned long)((unsigned int)(local_1c)) == 0)) {
            local_4 = (arg1 * 3);
        } else {
        }
    } else {
        local_4 = -1;
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}

clang -O2

1/3
alloca_dynamic_frame fail 169 lines
// glaurung: alloca_dynamic_frame @ 0x1100
int32_t alloca_dynamic_frame(int32_t arg0, int32_t arg1) {
    int index;
    int total;
    long ret;
    long rsp;
    int var100;
    int var101;
    int var102;
    int var103;
    int var106;
    int var107;
    int var108;
    int var109;
    long var110;
    long var111;
    long var113;
    long var131;
    long var134;
    int var14;
    int var15;
    int var16;
    int var17;
    long var2;
    long var46;
    long var48;
    long var55;
    long var56;
    long var59;
    long var6;
    long var62;
    long var63;
    int var65;
    int var66;
    int var67;
    int var68;
    long var70;
    long var9;
    long var99;
    // x86-64 prologue: save rbp
    ret = 0xffffffff;
    if (((unsigned long)((unsigned long)((unsigned int)((arg0 - 17)))) < (unsigned long)(0xfffffff0))) {
        // x86-64 epilogue: restore rbp
        return ret;
    }
    var2 = (unsigned long)((unsigned int)(arg0));
    var6 = (rsp - ((((unsigned long)((unsigned int)(arg0)) * 4) + 15) & -16));
    rsp = var6;
    if (((unsigned long)(4) <= (unsigned long)((unsigned long)((unsigned int)(arg0))))) {
        var9 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var2)) & -4)));
        var14 = arg1;
        var15 = arg1;
        var16 = arg1;
        var17 = arg1;
        ret = (unsigned long)((unsigned int)(arg1));
        *(int *)((var6)) = arg1;
        *(int *)((var6 + 0x4)) = (1 + arg1);
        *(int *)((var6 + 0x8)) = (2 + arg1);
        *(int *)((var6 + 0xc)) = (3 + arg1);
        if ((var9 != 4)) {
            *(int *)((var6 + 0x10)) = (4 + var14);
            *(int *)((var6 + 0x14)) = (5 + var15);
            *(int *)((var6 + 0x18)) = (6 + var16);
            *(int *)((var6 + 0x1c)) = (7 + var17);
            if (((unsigned long)((unsigned int)(var9)) != 8)) {
                *(int *)((var6 + 0x20)) = (8 + var14);
                *(int *)((var6 + 0x24)) = (9 + var15);
                *(int *)((var6 + 0x28)) = (10 + var16);
                *(int *)((var6 + 0x2c)) = (11 + var17);
                if (((unsigned long)((unsigned int)(var9)) != 12)) {
                    *(int *)((var6 + 0x30)) = (var14 + 12);
                    *(int *)((var6 + 0x34)) = (var15 + 13);
                    *(int *)((var6 + 0x38)) = (var16 + 14);
                    *(int *)((var6 + 0x3c)) = (var17 + 15);
                }
            }
        }
        var46 = var9;
        var48 = (unsigned long)((unsigned int)(arg1));
        if ((var9 == var2)) {
            goto L_11af;
        }
        goto L_1199;
    } else {
        var46 = 0;
        L_1199: ;
        var48 = (unsigned long)((unsigned int)(arg1));
        index = var46;
        do {
            *(int *)((var6 + index * 4)) = (var48 + index);
            index = (index + 1);
        } while ((var2 != index));
    }
    L_11af: ;
    if (((unsigned long)(4) <= (unsigned long)((unsigned long)((unsigned int)(arg0))))) {
        var55 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var2)) & -4)));
        var56 = (var55 - 4);
        var59 = (((unsigned long)(var56) >> 2) + 1);
        var62 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var59)) & 7)));
        if (((unsigned long)(28) <= (unsigned long)(var56))) {
            var63 = (var59 & -8);
            var65 = 0;
            var66 = 0;
            var67 = 0;
            var68 = 0;
            var70 = 0;
            do {
                var65 = ((((((((var65 + *(int *)((var6 + var70 * 4))) + *(int *)((var6 + var70 * 4 + 0x10))) + *(int *)((var6 + var70 * 4 + 0x20))) + *(int *)((var6 + var70 * 4 + 0x30))) + *(int *)((var6 + var70 * 4 + 0x40))) + *(int *)((var6 + var70 * 4 + 0x50))) + *(int *)((var6 + var70 * 4 + 0x60))) + *(int *)((var6 + var70 * 4 + 0x70)));
                var66 = ((((((((var66 + *(int *)((var6 + var70 * 4 + 0x4))) + *(int *)((var6 + var70 * 4 + 0x14))) + *(int *)((var6 + var70 * 4 + 0x24))) + *(int *)((var6 + var70 * 4 + 0x34))) + *(int *)((var6 + var70 * 4 + 0x44))) + *(int *)((var6 + var70 * 4 + 0x54))) + *(int *)((var6 + var70 * 4 + 0x64))) + *(int *)((var6 + var70 * 4 + 0x74)));
                var67 = ((((((((var67 + *(int *)((var6 + var70 * 4 + 0x8))) + *(int *)((var6 + var70 * 4 + 0x18))) + *(int *)((var6 + var70 * 4 + 0x28))) + *(int *)((var6 + var70 * 4 + 0x38))) + *(int *)((var6 + var70 * 4 + 0x48))) + *(int *)((var6 + var70 * 4 + 0x58))) + *(int *)((var6 + var70 * 4 + 0x68))) + *(int *)((var6 + var70 * 4 + 0x78)));
                var68 = ((((((((var68 + *(int *)((var6 + var70 * 4 + 0xc))) + *(int *)((var6 + var70 * 4 + 0x1c))) + *(int *)((var6 + var70 * 4 + 0x2c))) + *(int *)((var6 + var70 * 4 + 0x3c))) + *(int *)((var6 + var70 * 4 + 0x4c))) + *(int *)((var6 + var70 * 4 + 0x5c))) + *(int *)((var6 + var70 * 4 + 0x6c))) + *(int *)((var6 + var70 * 4 + 0x7c)));
                ret = ((unsigned long)((unsigned int)(var66)) | (unsigned long)((unsigned int)(var65)));
                var70 = (var70 + 32);
                var63 = (var63 - 8);
                var99 = var70;
                var100 = var65;
                var101 = var66;
                var102 = var67;
                var103 = var68;
            } while ((var63 != 0));
        } else {
            var100 = 0;
            var101 = 0;
            var102 = 0;
            var103 = 0;
            var99 = 0;
        }
        var106 = var100;
        var107 = var101;
        var108 = var102;
        var109 = var103;
        if ((var62 != 0)) {
            var110 = (var6 + (var99 * 4));
            var111 = (var62 << 4);
            var113 = 0;
            do {
                var100 = (var100 + *(int *)((var110 + var113)));
                var101 = (var101 + *(int *)((var110 + var113 + 0x4)));
                var102 = (var102 + *(int *)((var110 + var113 + 0x8)));
                var103 = (var103 + *(int *)((var110 + var113 + 0xc)));
                var113 = (var113 + 16);
                var106 = var100;
                var107 = var101;
                var108 = var102;
                var109 = var103;
            } while ((var111 != var113));
        }
        var131 = (unsigned long)((unsigned int)(((var109 + var107) + (var108 + var106))));
        ret = var131;
        if ((var55 == var2)) {
            // x86-64 epilogue: restore rbp
            return ret;
        }
        L_1280: ;
        do {
            total = (var131 + *(int *)((var6 + var55 * 4)));
            var134 = (var55 + 1);
            var131 = (unsigned long)((unsigned int)(total));
            var55 = var134;
            ret = (unsigned long)((unsigned int)(total));
        } while ((var2 != var134));
    } else {
        var131 = 0;
        var55 = 0;
        goto L_1280;
    }
    // x86-64 epilogue: restore rbp
    return ret;
}
alloca_in_loop fail 170 lines
// glaurung: alloca_in_loop @ 0x12a0
__attribute__((no_stack_protector)) int32_t alloca_in_loop(int32_t arg0, int32_t arg1) {
    int * chunk;
    int index;
    int round;
    int total;
    long rbp;
    long ret;
    long rsp;
    unsigned char stack_0[8];
    long var0;
    long var10;
    long var12;
    long var13;
    long var15;
    int var23;
    long var24;
    long var25;
    long var27;
    long var28;
    int var39;
    long var40;
    long var41;
    long var43;
    long var44;
    long var5;
    long var8;
    rsp = (rsp - 8);
    *(long *)(&stack_0[0]) = rbp;
    rbp = (long)(&stack_0[0]);
    var0 = 0xffffffff;
    ret = 0xffffffff;
    if (((unsigned long)(4) < (unsigned long)((unsigned long)((unsigned int)(arg0))))) {
        // x86-64 epilogue: restore rbp
        return ret;
    }
    ret = var0;
    if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 9)))) < (unsigned long)(0xfffffff8))) {
        // x86-64 epilogue: restore rbp
        return ret;
    }
    if (((unsigned long)((unsigned int)(arg0)) == 0)) {
        return 0;
    } else {
        var5 = (unsigned long)((unsigned int)((arg1 - 1)));
        var8 = ((((unsigned long)((unsigned int)(arg1)) * 4) + 15) & -16);
        var10 = (long)((&stack_0[0] - var8));
        rsp = var10;
        var12 = (-var8);
        *(int *)((&stack_0[0] + var12)) = 0;
        if (((unsigned long)((unsigned int)(arg1)) != 1)) {
            *(int *)((var10 + 0x4)) = 1;
            if (((unsigned long)((unsigned int)(arg1)) != 2)) {
                *(int *)((var10 + 0x8)) = 2;
                if (((unsigned long)((unsigned int)(arg1)) != 3)) {
                    *(int *)((var10 + 0xc)) = 3;
                    if (((unsigned long)((unsigned int)(arg1)) != 4)) {
                        *(int *)((var10 + 0x10)) = 4;
                        if (((unsigned long)((unsigned int)(arg1)) != 5)) {
                            *(int *)((var10 + 0x14)) = 5;
                            if (((unsigned long)((unsigned int)(arg1)) != 6)) {
                                *(int *)((var10 + 0x18)) = 6;
                                if (((unsigned long)((unsigned int)(arg1)) != 7)) {
                                    *(int *)((var10 + 0x1c)) = 7;
                                }
                            }
                        }
                    }
                }
            }
        }
        ret = (unsigned long)((unsigned int)(*(int *)((var10 + var5 * 4))));
        if (((unsigned long)((unsigned int)(arg0)) == 1)) {
            // x86-64 epilogue: restore rbp
            return ret;
        }
        var13 = rsp;
        var15 = (rsp - var8);
        rsp = var15;
        *(int *)((var13 + var12)) = arg1;
        if (((unsigned long)((unsigned int)(arg1)) != 1)) {
            *(int *)((var15 + 0x4)) = (arg1 + 1);
            if (((unsigned long)((unsigned int)(arg1)) != 2)) {
                *(int *)((var15 + 0x8)) = (arg1 + 2);
                if (((unsigned long)((unsigned int)(arg1)) != 3)) {
                    *(int *)((var15 + 0xc)) = (arg1 + 3);
                    if (((unsigned long)((unsigned int)(arg1)) != 4)) {
                        *(int *)((var15 + 0x10)) = (arg1 + 4);
                        if (((unsigned long)((unsigned int)(arg1)) != 5)) {
                            *(int *)((var15 + 0x14)) = (arg1 + 5);
                            if (((unsigned long)((unsigned int)(arg1)) != 6)) {
                                *(int *)((var15 + 0x18)) = (arg1 + 6);
                                if (((unsigned long)((unsigned int)(arg1)) != 7)) {
                                    *(int *)((var15 + 0x1c)) = (arg1 + 7);
                                }
                            }
                        }
                    }
                }
            }
        }
        var23 = (ret + *(int *)((var15 + var5 * 4)));
        var24 = (unsigned long)((unsigned int)(var23));
        ret = (unsigned long)((unsigned int)(var23));
        if (((unsigned long)((unsigned int)(arg0)) == 2)) {
            // x86-64 epilogue: restore rbp
            return ret;
        }
        var25 = rsp;
        var27 = (rsp - var8);
        rsp = var27;
        var28 = (unsigned long)((unsigned int)((arg1 + arg1)));
        *(int *)((var25 + var12)) = var28;
        if (((unsigned long)((unsigned int)(arg1)) != 1)) {
            *(int *)((var27 + 0x4)) = ((unsigned long)((unsigned int)(var28)) | 1);
            if (((unsigned long)((unsigned int)(arg1)) != 2)) {
                *(int *)((var27 + 0x8)) = (var28 + 2);
                if (((unsigned long)((unsigned int)(arg1)) != 3)) {
                    *(int *)((var27 + 0xc)) = (var28 + 3);
                    if (((unsigned long)((unsigned int)(arg1)) != 4)) {
                        *(int *)((var27 + 0x10)) = (var28 + 4);
                        if (((unsigned long)((unsigned int)(arg1)) != 5)) {
                            *(int *)((var27 + 0x14)) = (var28 + 5);
                            if (((unsigned long)((unsigned int)(arg1)) != 6)) {
                                *(int *)((var27 + 0x18)) = (var28 + 6);
                                if (((unsigned long)((unsigned int)(arg1)) != 7)) {
                                    *(int *)((var27 + 0x1c)) = (var28 + 7);
                                }
                            }
                        }
                    }
                }
            }
        }
        var39 = (var24 + *(int *)((var27 + var5 * 4)));
        var40 = (unsigned long)((unsigned int)(var39));
        ret = (unsigned long)((unsigned int)(var39));
        if (((unsigned long)((unsigned int)(arg0)) == 3)) {
            // x86-64 epilogue: restore rbp
            return ret;
        }
        var41 = rsp;
        var43 = (rsp - var8);
        rsp = var43;
        var44 = (unsigned long)((unsigned int)((arg1 + (arg1 * 2))));
        *(int *)((var41 + var12)) = var44;
        if (((unsigned long)((unsigned int)(arg1)) != 1)) {
            *(int *)((var43 + 0x4)) = (var44 + 1);
            if (((unsigned long)((unsigned int)(arg1)) != 2)) {
                *(int *)((var43 + 0x8)) = (var44 + 2);
                if (((unsigned long)((unsigned int)(arg1)) != 3)) {
                    *(int *)((var43 + 0xc)) = (var44 + 3);
                    if (((unsigned long)((unsigned int)(arg1)) != 4)) {
                        *(int *)((var43 + 0x10)) = (var44 + 4);
                        if (((unsigned long)((unsigned int)(arg1)) != 5)) {
                            *(int *)((var43 + 0x14)) = (var44 + 5);
                            if (((unsigned long)((unsigned int)(arg1)) != 6)) {
                                *(int *)((var43 + 0x18)) = (var44 + 6);
                                if (((unsigned long)((unsigned int)(arg1)) != 7)) {
                                    *(int *)((var43 + 0x1c)) = (var44 + 7);
                                }
                            }
                        }
                    }
                }
            }
        }
        return (unsigned int)((var40 + *(int *)((var43 + var5 * 4))));
    }
}
cleanup_on_every_exit pass 17 lines
// glaurung: cleanup_on_every_exit @ 0x14a0
int32_t cleanup_on_every_exit(int32_t * arg0, int32_t arg1) {
    long var0;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    var0 = (unsigned long)((unsigned int)(arg1));
    *(int *)(((long)arg0)) = 0;
    if (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(arg1)) & 1))) == 0)) {
        if (((unsigned long)((unsigned char)((var0 & 2))) != 0)) {
            return (unsigned int)((var0 + var0));
        } else {
            return (unsigned int)((var0 + (var0 * 2)));
        }
    }
    return (unsigned int)(arg1);
}

gcc -O0

1/3
alloca_dynamic_frame fail 43 lines
// glaurung: alloca_dynamic_frame @ 0x113a
int32_t alloca_dynamic_frame(int32_t arg0, int32_t arg1) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    int total;
    int * scratch;
    int index;
    long local_8;
    long ret;
    long rsp;
    long var14;
    long var18;
    long var28;
    // x86-64 prologue: save rbp, frame 48 bytes
    local_8 = (long)(0x28);
    total = 0;
    if (((((unsigned long)((unsigned int)(arg0)) == 0) | ((long)(arg0) < 0)) || (((unsigned long)((unsigned int)(arg0)) != 16) && (16 <= (long)(arg0))))) {
        ret = 0xffffffff;
    } else {
        var14 = (((unsigned long)(((((unsigned __int128)(unsigned long)(0) << 64) | (unsigned long)(((16 - 1) + (((long)((int)((unsigned long)((unsigned int)(arg0)))) << 2) + 8)))) / (unsigned long)(16)))) * 16);
        var18 = (rsp - (var14 & -4096));
        while ((rsp != var18)) {
            rsp = (rsp - 4096);
        }
        rsp = (rsp - (unsigned long)((unsigned int)((var14 & 4095))));
        if (((unsigned long)((unsigned int)((var14 & 4095))) != 0)) {
            var28 = (((unsigned long)((unsigned int)((var14 & 4095))) - 8) + rsp);
            *(long *)((var28)) = *(long *)((var28));
        }
        scratch = (int *)((((unsigned long)((rsp + 15)) >> 4) << 4));
        for (index = 0; (index < arg0); index++) {
            scratch[(long)(index)] = ((unsigned long)((unsigned int)(index)) + (unsigned long)((unsigned int)(arg1)));
        }
        for (index = 0; (index < arg0); index++) {
            total = (total + (unsigned int)(scratch[(long)(index)]));
        }
        ret = (unsigned long)((unsigned int)(total));
    }
    if ((local_8 != 0x28)) {
        __stack_chk_fail();
    }
    // x86-64 epilogue: restore rbp
    return ret;
}
alloca_in_loop fail 46 lines
// glaurung: alloca_in_loop @ 0x1280
int32_t alloca_in_loop(int32_t arg0, int32_t arg1) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    int total;
    int round;
    int * chunk;
    int index;
    long local_8;
    long ret;
    long rsp;
    long var15;
    long var19;
    long var29;
    // x86-64 prologue: save rbp, frame 48 bytes
    local_8 = (long)(0x28);
    total = 0;
    if ((((((long)(arg0) < 0) || ((((unsigned long)((unsigned int)(arg0)) == 4) | ((long)(arg0) < 4)) == 0)) || (((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) || (((unsigned long)((unsigned int)(arg1)) != 8) && (8 <= (long)(arg1))))) {
        ret = 0xffffffff;
    } else {
        round = 0;
        while ((round < arg0)) {
            var15 = (((unsigned long)(((((unsigned __int128)(unsigned long)(0) << 64) | (unsigned long)(((16 - 1) + (((long)((int)((unsigned long)((unsigned int)(arg1)))) << 2) + 8)))) / (unsigned long)(16)))) * 16);
            var19 = (rsp - (var15 & -4096));
            while ((rsp != var19)) {
                rsp = (rsp - 4096);
            }
            rsp = (rsp - (unsigned long)((unsigned int)((var15 & 4095))));
            if (((unsigned long)((unsigned int)((var15 & 4095))) != 0)) {
                var29 = (((unsigned long)((unsigned int)((var15 & 4095))) - 8) + rsp);
                *(long *)((var29)) = *(long *)((var29));
            }
            chunk = (int *)((((unsigned long)((rsp + 15)) >> 4) << 4));
            for (index = 0; (index < arg1); index++) {
                chunk[(long)(index)] = ((unsigned long)((unsigned int)(index)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(round)) * arg1))));
            }
            total = (total + (unsigned int)(*(int *)(((long)chunk + (((long)(arg1) << 2) - 4)))));
            round = (round + 1);
        }
        ret = (unsigned long)((unsigned int)(total));
    }
    if ((local_8 != 0x28)) {
        __stack_chk_fail();
    }
    // x86-64 epilogue: restore rbp
    return ret;
}
cleanup_on_every_exit pass 43 lines
// glaurung: cleanup_on_every_exit @ 0x13df
int32_t cleanup_on_every_exit(int32_t * arg0, int32_t arg1) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    extern void record_cleanup(int *);
    unsigned char guarded[12];
    long ret;
    int var11;
    long var12;
    long var13;
    long var14;
    // x86-64 prologue: save rbp, frame 8 bytes
    *(long *)((&guarded[0] + 4)) = (long)((long)(0x28));
    if ((arg0 != 0)) {
        *(int *)((long)arg0) = 0;
        *(int *)(&guarded[0]) = 0;
        *(int *)(&guarded[0]) = arg1;
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 1))) == 0)) {
            if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 2))) == 0)) {
                var11 = 1;
                var12 = var13;
            } else {
                var14 = (unsigned long)((unsigned int)(*(int *)(&guarded[0])));
                var12 = (unsigned long)((unsigned int)((var14 + var14)));
                var11 = 0;
            }
        } else {
            var12 = (unsigned long)((unsigned int)(*(int *)(&guarded[0])));
            var11 = 0;
        }
        record_cleanup((int *)(&guarded[0]));
        if (((unsigned long)((unsigned int)(var11)) == 1)) {
            var12 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + (unsigned long)((unsigned int)(arg1))))) + (unsigned long)((unsigned int)(arg1)))));
        }
    } else {
        var12 = 0xffffffff;
    }
    ret = (unsigned long)((unsigned int)(var12));
    if ((*(long *)((&guarded[0] + 4)) != 0x28)) {
        __stack_chk_fail();
    }
    // x86-64 epilogue: restore rbp
    return ret;
}

gcc -O2

1/3
alloca_dynamic_frame fail 75 lines
// glaurung: alloca_dynamic_frame @ 0x1120
int32_t alloca_dynamic_frame(int32_t arg0, int32_t arg1) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    int total;
    int index;
    long local_8;
    long rsp;
    unsigned char stack_0[8];
    long var10;
    long var12;
    long var14;
    long var15;
    long var16;
    long var17;
    long var18;
    int var19;
    long var21;
    long var24;
    long var26;
    long var6;
    long var9;
    rsp = (rsp - 8);
    rsp = (rsp - 16);
    local_8 = (long)(0x28);
    if (((unsigned long)(15) < (unsigned long)((unsigned long)((unsigned int)((arg0 - 1)))))) {
        goto L_11e8;
    }
    var6 = (((long)(arg0) * 4) + 23);
    var9 = (rsp - (var6 & -4096));
    var10 = (var6 & -16);
    if ((rsp != var9)) {
        while ((rsp != var9)) {
            rsp = (rsp - 4096);
        }
    }
    var12 = (unsigned long)((unsigned int)((var10 & 4095)));
    rsp = (rsp - var12);
    if ((var12 != 0)) {
        goto L_11e0;
    }
    L_118d: ;
    var14 = (unsigned long)((unsigned int)((arg0 + arg1)));
    var15 = ((rsp + 15) & -16);
    var16 = var15;
    var17 = var15;
    var18 = (unsigned long)((unsigned int)(arg1));
    do {
        *(int *)((var17)) = var18;
        var19 = (var18 + 1);
        var18 = (unsigned long)((unsigned int)(var19));
        var17 = (var17 + 4);
    } while (((unsigned int)(var19) != (unsigned int)(var14)));
    var21 = (var15 + ((unsigned long)((unsigned int)(arg0)) * 4));
    var24 = 0;
    do {
        total = (var24 + *(int *)((var16)));
        var24 = (unsigned long)((unsigned int)(total));
        var16 = (var16 + 4);
        var26 = (unsigned long)((unsigned int)(total));
    } while ((var21 != var16));
    L_11cc: ;
    if ((local_8 != 0x28)) {
        goto L_11f0;
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(var26);
    L_11e0: ;
    *(long *)((&stack_0[0] + var12)) = *(long *)((&stack_0[0] + var12));
    goto L_118d;
    L_11e8: ;
    var26 = 0xffffffff;
    goto L_11cc;
    L_11f0: ;
    __stack_chk_fail();
}
alloca_in_loop fail 93 lines
// glaurung: alloca_in_loop @ 0x1200
int32_t alloca_in_loop(int32_t arg0, int32_t arg1) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    int index;
    int * chunk;
    int total;
    int round;
    long local_28;
    long rbp;
    long rsp;
    long var10;
    long var11;
    long var14;
    long var15;
    long var18;
    long var19;
    long var20;
    long var21;
    long var22;
    long var24;
    long var30;
    int var31;
    long var36;
    long var4;
    long var6;
    rsp = (rsp - 8);
    rbp = rsp;
    rsp = (rsp - 8);
    rsp = (rsp - 8);
    rsp = (rsp - 8);
    rsp = (rsp - 24);
    local_28 = (long)(0x28);
    if (((unsigned long)(7) < (unsigned long)((unsigned long)((unsigned int)((arg1 - 1)))))) {
        goto L_12ef;
    }
    var4 = (unsigned long)((unsigned int)(arg0));
    if (((unsigned long)(4) < (unsigned long)((unsigned long)((unsigned int)(arg0))))) {
        goto L_12ef;
    }
    if (((unsigned long)((unsigned int)(arg0)) == 0)) {
        goto L_12ea;
    }
    var6 = (unsigned long)((unsigned int)(arg1));
    var10 = 0;
    var11 = ((long)(arg1) << 2);
    var14 = (var11 + 23);
    var15 = (var11 - 4);
    var18 = (unsigned long)((unsigned int)((var14 & 4080)));
    var19 = (var14 & -4096);
    var20 = (var18 - 8);
    var21 = 0;
    var22 = 0;
    do {
        var24 = (rsp - var19);
        if ((rsp != var24)) {
            while ((rsp != var24)) {
                rsp = (rsp - 4096);
            }
        }
        rsp = (rsp - var18);
        if ((var18 != 0)) {
            *(long *)((rsp + var20)) = *(long *)((rsp + var20));
        }
        index = 0;
        chunk = (int *)(((rsp + 15) & -16));
        do {
            *(int *)((chunk + index * 4)) = (var10 + index);
            var30 = ((unsigned long)((unsigned int)(index)) + 1);
            index = var30;
        } while (((((unsigned int)(var6) == (unsigned int)(var30)) | ((long)((int)(var6)) < (long)((int)(var30)))) == 0));
        var31 = (var21 + 1);
        total = (var22 + *(int *)((chunk + var15)));
        var10 = (unsigned long)((unsigned int)((var10 + var6)));
        var21 = (unsigned long)((unsigned int)(var31));
        var22 = (unsigned long)((unsigned int)(total));
        var36 = (unsigned long)((unsigned int)(total));
    } while (((unsigned int)(var4) != (unsigned int)(var31)));
    L_12cd: ;
    if ((local_28 != 0x28)) {
        goto L_12f7;
    }
    rsp = (rbp - 24);
    // x86-64 epilogue: restore rbp
    return (unsigned int)(var36);
    L_12ea: ;
    var36 = 0;
    goto L_12cd;
    L_12ef: ;
    var36 = 0xffffffff;
    goto L_12cd;
    L_12f7: ;
    __stack_chk_fail();
}
cleanup_on_every_exit pass 15 lines
// glaurung: cleanup_on_every_exit @ 0x1300
int32_t cleanup_on_every_exit(int32_t * arg0, int32_t arg1) {
    long ret;
    long var2;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    ret = (unsigned long)((unsigned int)(arg1));
    *(int *)(((long)arg0)) = 0;
    if (((unsigned long)((unsigned int)((arg1 & 1))) != 0)) {
        return ret;
    }
    var2 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + (unsigned long)((unsigned int)(arg1)))));
    return (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(arg1)) & 2))) != 0) ? var2 : (unsigned long)((unsigned int)((var2 + (unsigned long)((unsigned int)(arg1))))));
}

← 213 fixtures