Fixture 216

packed union wire record

C · 5 functions · 4 lanes · 20 of 20 function-lanes behave identically

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

Bitfields inside a PACKED UNION, read back through a byte view — the shape every binary protocol header actually has, and one no fixture composes.

WHAT THE COMPOSITION COSTS. Three recovery problems interact here and none of them is visible alone:

* a bitfield read is a load, a shift and a mask, and the field's WIDTH is encoded only in the mask constant; * a union means the same storage is read at two different types, so an object model keyed by access width sees conflicting evidence for one address rather than two disjoint objects; * packed removes the padding that would otherwise separate the fields, so a byte view straddles bitfield boundaries and the shift amounts stop being multiples of eight.

A decompiler that recovers each in isolation can still produce wrong C for the combination: the classic failure is folding the union's two views into one field of the wider type, which compiles, runs, and silently reinterprets every read.

90_bitfields covers bitfield layout on its own. 91_union_type_punning covers a union on its own. 161_packed_struct_layout covers packed on its own. 163_wire_header_parser parses a wire header but does it with explicit shifts and masks rather than bitfields, which is a different recovery problem. This fixture is the intersection, which is what real headers look like.

Bit-field layout within a unit is implementation-defined, so every function here is written to be layout-AGNOSTIC: values are written through the bitfield view and read back through the same view, and the byte view is only ever used to observe that SOMETHING changed in a specific byte, never to assert which bit. That keeps the differential valid across every target while still forcing the recovery to model the storage overlap.

tests/decompiler_fixtures/src/216_packed_union_wire_record.c source
#include <stdint.h>

/* Bitfields inside a PACKED UNION, read back through a byte view — the shape
 * every binary protocol header actually has, and one no fixture composes.
 *
 * WHAT THE COMPOSITION COSTS. Three recovery problems interact here and none of
 * them is visible alone:
 *
 *   * a bitfield read is a load, a shift and a mask, and the field's WIDTH is
 *     encoded only in the mask constant;
 *   * a union means the same storage is read at two different types, so an
 *     object model keyed by access width sees conflicting evidence for one
 *     address rather than two disjoint objects;
 *   * `packed` removes the padding that would otherwise separate the fields,
 *     so a byte view straddles bitfield boundaries and the shift amounts stop
 *     being multiples of eight.
 *
 * A decompiler that recovers each in isolation can still produce wrong C for
 * the combination: the classic failure is folding the union's two views into
 * one field of the wider type, which compiles, runs, and silently reinterprets
 * every read.
 *
 * `90_bitfields` covers bitfield layout on its own. `91_union_type_punning`
 * covers a union on its own. `161_packed_struct_layout` covers `packed` on its
 * own. `163_wire_header_parser` parses a wire header but does it with explicit
 * shifts and masks rather than bitfields, which is a different recovery
 * problem. This fixture is the intersection, which is what real headers look
 * like.
 *
 * Bit-field layout within a unit is implementation-defined, so every function
 * here is written to be layout-AGNOSTIC: values are written through the
 * bitfield view and read back through the same view, and the byte view is only
 * ever used to observe that SOMETHING changed in a specific byte, never to
 * assert which bit. That keeps the differential valid across every target while
 * still forcing the recovery to model the storage overlap.
 */

struct __attribute__((packed)) wire_flags {
    uint8_t version : 3;
    uint8_t urgent  : 1;
    uint8_t kind    : 4;
};

union __attribute__((packed)) wire_head {
    struct wire_flags fields;
    uint8_t raw;
};

/* Write through the bitfield view, read through the same view. Layout-agnostic
 * and exact. */
__attribute__((noinline)) int32_t bitfield_roundtrip(int32_t version,
                                                     int32_t urgent,
                                                     int32_t kind) {
    union wire_head head;
    head.raw = 0;
    head.fields.version = (uint8_t)(version & 0x7);
    head.fields.urgent = (uint8_t)(urgent & 0x1);
    head.fields.kind = (uint8_t)(kind & 0xf);
    return (int32_t)head.fields.version * 100 + (int32_t)head.fields.urgent * 10 +
           (int32_t)head.fields.kind;
}

/* Write through the bitfield view, observe through the BYTE view. The exact bit
 * positions are implementation-defined, so only the population count is
 * asserted — which is layout-independent and still requires the storage overlap
 * to be modelled. */
__attribute__((noinline)) int32_t bitfield_seen_as_byte(int32_t version,
                                                        int32_t kind) {
    union wire_head head;
    head.raw = 0;
    head.fields.version = (uint8_t)(version & 0x7);
    head.fields.kind = (uint8_t)(kind & 0xf);
    return __builtin_popcount((unsigned)head.raw);
}

/* Write through the BYTE view, read through the bitfield view: the reverse
 * direction, where a folded union produces a different answer. Again only the
 * population count of the reassembled fields is compared. */
__attribute__((noinline)) int32_t byte_seen_as_bitfields(int32_t byte_value) {
    union wire_head head;
    head.raw = (uint8_t)(byte_value & 0xff);
    int32_t total = (int32_t)head.fields.version + (int32_t)head.fields.urgent +
                    (int32_t)head.fields.kind;
    return total;
}

/* A packed record of several such units, walked as an array. This is the shape
 * a TLV parser has, and it forces a stride the compiler cannot pad. */
struct __attribute__((packed)) wire_record {
    union wire_head head;
    uint16_t length;
    uint8_t tag;
};

__attribute__((noinline)) int32_t walk_packed_records(const uint8_t *bytes,
                                                       int32_t count) {
    int32_t total = 0;
    if (bytes == 0 || count < 0 || count > 4) {
        return -1;
    }
    for (int32_t i = 0; i < count; i++) {
        struct wire_record rec;
        const uint8_t *src = bytes + (int32_t)sizeof(struct wire_record) * i;
        /* Byte-wise copy: no unaligned load, valid on every target. */
        for (uint32_t b = 0; b < sizeof(struct wire_record); b++) {
            ((uint8_t *)&rec)[b] = src[b];
        }
        total += (int32_t)rec.head.fields.kind;
        total += (int32_t)(rec.length & 0xff);
        total += (int32_t)rec.tag;
    }
    return total;
}

/* CONTROL: the same three fields as ordinary members, with no bitfields, no
 * union and no packing. If this fails, the defect is in struct recovery
 * generally rather than in the composition. */
struct plain_head {
    uint8_t version;
    uint8_t urgent;
    uint8_t kind;
};

__attribute__((noinline)) int32_t plain_struct_control(int32_t version,
                                                       int32_t urgent,
                                                       int32_t kind) {
    struct plain_head head;
    head.version = (uint8_t)(version & 0x7);
    head.urgent = (uint8_t)(urgent & 0x1);
    head.kind = (uint8_t)(kind & 0xf);
    return (int32_t)head.version * 100 + (int32_t)head.urgent * 10 +
           (int32_t)head.kind;
}

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

5/5
bitfield_roundtrip pass 11 lines
// glaurung: bitfield_roundtrip @ 0x1100
__attribute__((no_stack_protector)) int32_t bitfield_roundtrip(int32_t arg0, int32_t arg1, int32_t arg2) {
    unsigned char local_10[1];
    // x86-64 prologue: save rbp
    *(signed char *)(&local_10[0]) = 0;
    *(signed char *)(&local_10[0]) = ((*(char *)(&local_10[0]) & 248) | ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 7))) & 7));
    *(signed char *)(&local_10[0]) = ((*(char *)(&local_10[0]) & 247) | ((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 1))) & 1) << 3) & 255));
    *(signed char *)(&local_10[0]) = ((*(char *)(&local_10[0]) & 15) | ((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) & 15))) & 15) << 4) & 255));
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned long)((unsigned int)((((unsigned int)((unsigned char)((*(char *)(&local_10[0]) & 7))) * 100) + ((unsigned int)((unsigned char)((((unsigned long)((unsigned char)((*(char *)(&local_10[0]) & 255))) >> 3) & 1))) * 10)))) + (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((*(char *)(&local_10[0]) & 255))) >> 4) & 255)))));
}
bitfield_seen_as_byte pass 16 lines
// glaurung: bitfield_seen_as_byte @ 0x1180
__attribute__((no_stack_protector)) int32_t bitfield_seen_as_byte(int32_t arg0, int32_t arg1) {
    unsigned char local_10[1];
    int var28;
    long var36;
    int var45;
    // x86-64 prologue: save rbp
    *(signed char *)(&local_10[0]) = 0;
    *(signed char *)(&local_10[0]) = ((*(char *)(&local_10[0]) & 248) | ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 7))) & 7));
    *(signed char *)(&local_10[0]) = ((*(char *)(&local_10[0]) & 15) | ((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 15))) & 15) << 4) & 255));
    var28 = (unsigned int)((unsigned char)(*(char *)(&local_10[0])));
    var36 = (unsigned long)((unsigned int)((var28 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var28)) >> 1))) & 0x55555555))))));
    var45 = ((unsigned int)(((unsigned long)((unsigned int)(var36)) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var36)) >> 2))) & 0x33333333)));
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var45)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var45)) >> 4)))))) & 0xf0f0f0f))) * 0x1010101))) >> 24));
}
byte_seen_as_bitfields pass 10 lines
// glaurung: byte_seen_as_bitfields @ 0x1200
__attribute__((no_stack_protector)) int32_t byte_seen_as_bitfields(int32_t arg0) {
    int total;
    unsigned char local_8[1];
    // x86-64 prologue: save rbp
    *(signed char *)(&local_8[0]) = arg0;
    total = ((unsigned int)(((unsigned int)((unsigned char)((*(char *)(&local_8[0]) & 7))) + (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((*(char *)(&local_8[0]) & 255))) >> 3) & 1))))) + (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((*(char *)(&local_8[0]) & 255))) >> 4) & 255))));
    // x86-64 epilogue: restore rbp
    return (unsigned int)(total);
}
plain_struct_control pass 10 lines
// glaurung: plain_struct_control @ 0x1320
__attribute__((no_stack_protector)) int32_t plain_struct_control(int32_t arg0, int32_t arg1, int32_t arg2) {
    unsigned char local_10[3];
    // x86-64 prologue: save rbp
    *(signed char *)(&local_10[0]) = ((unsigned long)((unsigned int)(arg0)) & 7);
    *(signed char *)((&local_10[0] + 1)) = ((unsigned long)((unsigned int)(arg1)) & 1);
    *(signed char *)((&local_10[0] + 2)) = ((unsigned long)((unsigned int)(arg2)) & 15);
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned long)((unsigned int)((((unsigned int)((unsigned char)(*(char *)(&local_10[0]))) * 100) + ((unsigned int)((unsigned char)(*(char *)((&local_10[0] + 1)))) * 10)))) + (unsigned int)((unsigned char)(*(char *)((&local_10[0] + 2))))));
}
walk_packed_records pass 40 lines
// glaurung: walk_packed_records @ 0x1240
__attribute__((no_stack_protector)) int32_t walk_packed_records(const uint8_t * arg0, int32_t arg1) {
    int total;
    int i;
    char * src;
    unsigned int b;
    unsigned char local_20[4];
    int local_4;
    // x86-64 prologue: save rbp
    total = 0;
    if ((arg0 == 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)) == 4) | ((long)(arg1) < 4)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    i = 0;
    while ((i < arg1)) {
        src = (char *)(((long)arg0 + (long)((int)(((unsigned long)((unsigned int)(i)) << 2)))));
        for (b = 0; ((unsigned long)(b) < (unsigned long)(4)); b++) {
            *(signed char *)((&local_20[0] + b)) = src[b];
        }
        total = ((unsigned int)((unsigned char)((((unsigned long)((unsigned char)((*(char *)(&local_20[0]) & 255))) >> 4) & 255))) + total);
        total = ((unsigned int)(((unsigned int)((unsigned short)(*(short *)((&local_20[0] + 1)))) & 255)) + total);
        total = ((unsigned int)((unsigned char)(*(char *)((&local_20[0] + 3)))) + total);
        i = ((unsigned int)(i) + 1);
    }
    local_4 = total;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}

clang -O2

5/5
bitfield_roundtrip pass 6 lines
// glaurung: bitfield_roundtrip @ 0x1100
int32_t bitfield_roundtrip(int32_t arg0, int32_t arg1, int32_t arg2) {
    long var6;
    var6 = (unsigned long)((unsigned int)((arg1 & 1)));
    return (unsigned int)(((unsigned long)((unsigned int)((((unsigned long)((unsigned int)((arg0 & 7))) * 100) + ((unsigned long)((unsigned int)((var6 + (var6 * 4)))) * 2)))) + (unsigned long)((unsigned int)((arg2 & 15)))));
}
bitfield_seen_as_byte pass 10 lines
// glaurung: bitfield_seen_as_byte @ 0x1120
int32_t bitfield_seen_as_byte(int32_t arg0, int32_t arg1) {
    long var14;
    int var23;
    long var6;
    var6 = (unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)((arg1 << 4))) & 255))) | (unsigned long)((unsigned int)((arg0 & 7))))));
    var14 = (unsigned long)((unsigned int)((var6 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var6)) >> 1))) & -47))))));
    var23 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var14)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var14)) & 0x33333333)));
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var23)) >> 4))) + (unsigned long)((unsigned int)(var23))))) & 0xf0f0f0f))) * 0x1010101))) >> 24));
}
byte_seen_as_bitfields pass 5 lines
// glaurung: byte_seen_as_bitfields @ 0x1160
int32_t byte_seen_as_bitfields(int32_t arg0) {
    int total;
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) >> 3))) & 1))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 7)))))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) >> 4))) & 15)))));
}
plain_struct_control pass 6 lines
// glaurung: plain_struct_control @ 0x1200
int32_t plain_struct_control(int32_t arg0, int32_t arg1, int32_t arg2) {
    long var3;
    var3 = (unsigned long)((unsigned int)((arg1 & 1)));
    return (unsigned int)(((unsigned long)((unsigned int)((((unsigned long)((unsigned int)((arg0 & 7))) * 100) + ((unsigned long)((unsigned int)((var3 + (var3 * 4)))) * 2)))) + (unsigned long)((unsigned int)((arg2 & 15)))));
}
walk_packed_records pass 38 lines
// glaurung: walk_packed_records @ 0x1180
int32_t walk_packed_records(const uint8_t * arg0, int32_t arg1) {
    unsigned int b;
    int i;
    int total;
    long ret;
    int var10;
    int var22;
    int var34;
    long var35;
    ret = 0xffffffff;
    if ((arg0 != 0)) {
        ret = 0xffffffff;
        if (((unsigned long)(4) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
            return ret;
        }
        if (((unsigned long)((unsigned int)(arg1)) == 0)) {
            return 0;
        }
        var10 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((unsigned char)(*(char *)(((long)arg0))))) >> 4))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x1)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x3)))));
        ret = (unsigned long)((unsigned int)(var10));
        if (((unsigned long)((unsigned int)(arg1)) == 1)) {
            return ret;
        }
        var22 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var10)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x4))))) >> 4)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x5)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x7)))));
        ret = (unsigned long)((unsigned int)(var22));
        if (((unsigned long)((unsigned int)(arg1)) == 2)) {
            return ret;
        }
        var34 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var22)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x8))))) >> 4)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x9)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0xb)))));
        var35 = (unsigned long)((unsigned int)(var34));
        ret = (unsigned long)((unsigned int)(var34));
        if (((unsigned long)((unsigned int)(arg1)) != 3)) {
            ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var35 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0xc))))) >> 4)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0xd))))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0xf)))))));
        }
    }
    return ret;
}

gcc -O0

5/5
bitfield_roundtrip pass 15 lines
// glaurung: bitfield_roundtrip @ 0x1119
__attribute__((no_stack_protector)) int32_t bitfield_roundtrip(int32_t arg0, int32_t arg1, int32_t arg2) {
    unsigned char local_1[1];
    int var43;
    int var47;
    // x86-64 prologue: save rbp
    *(signed char *)(&local_1[0]) = 0;
    *(signed char *)(&local_1[0]) = ((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & -8))) | (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 7))) & 7))));
    *(signed char *)(&local_1[0]) = ((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & -9))) | (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 1))) & 1))) * 8))));
    *(signed char *)(&local_1[0]) = ((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & 15))) | (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) & 15))) << 4))));
    var43 = (unsigned int)((unsigned char)(((unsigned long)((unsigned int)((((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & 255))) >> 3) & 1))) & 255)));
    var47 = ((unsigned int)(((unsigned long)((unsigned int)(var43)) << 2)) + var43);
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned int)((unsigned char)((((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & 255))) >> 4) & 255))) + (unsigned long)((unsigned int)((((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & 7))) & 255))) * 100) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var47)) + (unsigned long)((unsigned int)(var47))))))))));
}
bitfield_seen_as_byte pass 13 lines
// glaurung: bitfield_seen_as_byte @ 0x11ac
__attribute__((no_stack_protector)) int32_t bitfield_seen_as_byte(int32_t arg0, int32_t arg1) {
    extern unsigned long __popcountdi2(unsigned long);
    unsigned char local_1[1];
    unsigned long ret;
    // x86-64 prologue: save rbp, frame 32 bytes
    *(signed char *)(&local_1[0]) = 0;
    *(signed char *)(&local_1[0]) = ((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & -8))) | (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 7))) & 7))));
    *(signed char *)(&local_1[0]) = ((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & 15))) | (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 15))) << 4))));
    ret = __popcountdi2((unsigned long)((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & 255)))));
    // x86-64 epilogue: restore rbp
    return ret;
}
byte_seen_as_bitfields pass 10 lines
// glaurung: byte_seen_as_bitfields @ 0x1203
__attribute__((no_stack_protector)) int32_t byte_seen_as_bitfields(int32_t arg0) {
    int total;
    unsigned char local_5[1];
    // x86-64 prologue: save rbp
    *(signed char *)(&local_5[0]) = arg0;
    total = ((unsigned int)((unsigned char)((((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_5[0]))) & 255))) >> 4) & 255))) + (unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_5[0]))) & 7))) & 255))) + (unsigned int)((unsigned char)(((unsigned long)((unsigned int)((((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_5[0]))) & 255))) >> 3) & 1))) & 255))))));
    // x86-64 epilogue: restore rbp
    return (unsigned int)(total);
}
plain_struct_control pass 14 lines
// glaurung: plain_struct_control @ 0x1316
__attribute__((no_stack_protector)) int32_t plain_struct_control(int32_t arg0, int32_t arg1, int32_t arg2) {
    unsigned char local_3[3];
    int var13;
    int var17;
    // x86-64 prologue: save rbp
    *(signed char *)(&local_3[0]) = ((unsigned long)((unsigned int)(arg0)) & 7);
    *(signed char *)((&local_3[0] + 1)) = ((unsigned long)((unsigned int)(arg1)) & 1);
    *(signed char *)((&local_3[0] + 2)) = ((unsigned long)((unsigned int)(arg2)) & 15);
    var13 = (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((&local_3[0] + 1)))) & 255)));
    var17 = ((unsigned int)(((unsigned long)((unsigned int)(var13)) << 2)) + var13);
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((&local_3[0] + 2)))) & 255))) + (unsigned long)((unsigned int)((((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_3[0]))) & 255))) * 100) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var17)) + (unsigned long)((unsigned int)(var17))))))))));
}
walk_packed_records pass 35 lines
// glaurung: walk_packed_records @ 0x1241
int32_t walk_packed_records(const uint8_t * arg0, int32_t arg1) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    int total;
    int i;
    char * src;
    unsigned int b;
    unsigned char local_14[4];
    long local_8;
    long ret;
    // x86-64 prologue: save rbp, frame 48 bytes
    local_8 = (long)(0x28);
    total = 0;
    if ((((arg0 == 0) || ((long)(arg1) < 0)) || (((unsigned long)((unsigned int)(arg1)) != 4) && (4 <= (long)(arg1))))) {
        ret = 0xffffffff;
    } else {
        i = 0;
        while ((i < arg1)) {
            src = (char *)(((long)arg0 + (long)((int)(((unsigned long)((unsigned int)(i)) << 2)))));
            for (b = 0; ((unsigned long)(b) <= (unsigned long)(3)); b++) {
                *(signed char *)((b + &local_14[0])) = src[b];
            }
            total = (total + (unsigned int)((unsigned char)((((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_14[0]))) & 255))) >> 4) & 255))));
            total = (total + (unsigned int)((unsigned char)(((unsigned int)((unsigned short)(((unsigned int)((unsigned short)(*(short *)((&local_14[0] + 1)))) & 0xffff))) & 255))));
            total = (total + (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((&local_14[0] + 3)))) & 255))));
            i = (i + 1);
        }
        ret = (unsigned long)((unsigned int)(total));
    }
    if ((local_8 != 0x28)) {
        __stack_chk_fail();
    }
    // x86-64 epilogue: restore rbp
    return ret;
}

gcc -O2

5/5
bitfield_roundtrip pass 6 lines
// glaurung: bitfield_roundtrip @ 0x1100
int32_t bitfield_roundtrip(int32_t arg0, int32_t arg1, int32_t arg2) {
    long var3;
    var3 = (unsigned long)((unsigned int)((arg1 & 1)));
    return (unsigned int)(((unsigned long)((unsigned int)((((unsigned long)((unsigned int)((arg0 & 7))) * 100) + ((unsigned long)((unsigned int)((var3 + (var3 * 4)))) * 2)))) + (unsigned long)((unsigned int)((arg2 & 15)))));
}
bitfield_seen_as_byte pass 7 lines
// glaurung: bitfield_seen_as_byte @ 0x1120
int32_t bitfield_seen_as_byte(int32_t arg0, int32_t arg1) {
    extern unsigned long __popcountdi2(unsigned long);
    unsigned long ret;
    ret = __popcountdi2((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg1 << 4))) | (unsigned long)((unsigned int)((arg0 & 7)))))) & 255))));
    return ret;
}
byte_seen_as_bitfields pass 5 lines
// glaurung: byte_seen_as_bitfields @ 0x1140
int32_t byte_seen_as_bitfields(int32_t arg0) {
    int total;
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 7))) + (unsigned long)((unsigned int)((((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(arg0)) & 255))) >> 3) & 1)))))) + (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((arg0 & 255))) >> 4) & 255)))));
}
plain_struct_control pass 6 lines
// glaurung: plain_struct_control @ 0x11b0
int32_t plain_struct_control(int32_t arg0, int32_t arg1, int32_t arg2) {
    long var3;
    var3 = (unsigned long)((unsigned int)((arg1 & 1)));
    return (unsigned int)(((unsigned long)((unsigned int)((((unsigned long)((unsigned int)((arg0 & 7))) * 100) + ((unsigned long)((unsigned int)((var3 + (var3 * 4)))) * 2)))) + (unsigned long)((unsigned int)((arg2 & 15)))));
}
walk_packed_records pass 28 lines
// glaurung: walk_packed_records @ 0x1160
int32_t walk_packed_records(const uint8_t * arg0, int32_t arg1) {
    int i;
    int total;
    unsigned int b;
    long ret;
    long var6;
    long var7;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    if (((unsigned long)(4) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return 0xffffffff;
    }
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        return 0;
    }
    i = 0;
    var6 = 0;
    do {
        var7 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + i * 4))));
        i = (i + 1);
        total = ((unsigned int)(((unsigned int)((unsigned char)((((unsigned long)(var7) >> 8) & 255))) + (unsigned long)((unsigned int)(((unsigned int)((unsigned char)((((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(var7)) & 255))) >> 4) & 255))) + var6))))) + (unsigned int)(((unsigned long)((unsigned int)(var7)) >> 24)));
        ret = (unsigned long)((unsigned int)(total));
        var6 = (unsigned long)((unsigned int)(total));
    } while (((((unsigned int)(arg1) == (unsigned int)(i)) | (arg1 < i)) == 0));
    return ret;
}

← 213 fixtures