Fixture 146

opaque predicates

C · 6 functions · 4 lanes · 24 of 24 function-lanes behave identically

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

Opaque predicates: conditions whose value is fixed for every possible input, but which no compiler (and no decompiler) can fold, because deciding them requires number theory or knowledge the translation unit does not contain.

Two families appear here:

1. Arithmetic invariants — n * (n + 1) is always even; a square is always 0 or 1 modulo 4; (v | 1) is always odd. Each identity survives modular reduction, so it holds for uint32_t wraparound too, not just for the mathematical integers. The compiler would have to reason about all 2^32 inputs to fold the branch, so it emits both arms.

2. A volatile sentinel — a file-scope object the compiler is forbidden to constant-propagate through. It is only ever read, never written, so its value is 0 in every execution, yet every arm guarded by it must be emitted.

Why this breaks decompilers: the recovered CFG contains large regions that are provably dead at runtime but structurally live. Output looks like a function with rich branching behaviour it does not have, and any dataflow summary (taint, range, "which inputs reach this write") is contaminated by paths that never execute. A decompiler that *does* try to simplify — folding (v | 1) & 1 to 1, say — must get the whole identity right; getting it half right silently deletes the live arm and keeps the dead one, which is the canonical confident-nonsense failure. The differential distinguishes the two because every arm here computes a *different* value.

All arms are memory-safe whichever way a mis-recovery branches: no arm indexes outside the validated bounds, so a wrong answer is a wrong number, never a crash in the harness.

tests/decompiler_fixtures/src/146_opaque_predicates.c source
#include <stdint.h>

/* Opaque predicates: conditions whose value is fixed for every possible input,
 * but which no compiler (and no decompiler) can fold, because deciding them
 * requires number theory or knowledge the translation unit does not contain.
 *
 * Two families appear here:
 *
 *   1. Arithmetic invariants — `n * (n + 1)` is always even; a square is always
 *      0 or 1 modulo 4; `(v | 1)` is always odd. Each identity survives modular
 *      reduction, so it holds for uint32_t wraparound too, not just for the
 *      mathematical integers. The compiler would have to reason about all 2^32
 *      inputs to fold the branch, so it emits both arms.
 *
 *   2. A `volatile` sentinel — a file-scope object the compiler is forbidden to
 *      constant-propagate through. It is only ever read, never written, so its
 *      value is 0 in every execution, yet every arm guarded by it must be
 *      emitted.
 *
 * Why this breaks decompilers: the recovered CFG contains large regions that
 * are provably dead at runtime but structurally live. Output looks like a
 * function with rich branching behaviour it does not have, and any dataflow
 * summary (taint, range, "which inputs reach this write") is contaminated by
 * paths that never execute. A decompiler that *does* try to simplify — folding
 * `(v | 1) & 1` to 1, say — must get the whole identity right; getting it half
 * right silently deletes the live arm and keeps the dead one, which is the
 * canonical confident-nonsense failure. The differential distinguishes the two
 * because every arm here computes a *different* value.
 *
 * All arms are memory-safe whichever way a mis-recovery branches: no arm
 * indexes outside the validated bounds, so a wrong answer is a wrong number,
 * never a crash in the harness.
 */

#define OPAQUE146_MAX_ELEMS 16

/* Never written. Reading it is an unpredictable-to-the-compiler load whose
 * runtime value is always zero. */
static volatile uint32_t opq146_sentinel = 0u;

/* `n * (n + 1)` is the product of two consecutive integers, hence even; the
 * property is preserved modulo 2^32 because 2 divides 2^32. The `else` arm can
 * never execute. */
__attribute__((noinline)) int32_t
opaque_always_true(int32_t value) {
    uint32_t v = (uint32_t)value;
    if (((v * (v + 1u)) & 1u) == 0u) {
        return (int32_t)(v * 3u + 1u);
    }
    return (int32_t)(v ^ 0xDEADBEEFu);
}

/* Squares are congruent to 0 or 1 modulo 4, and `& 3` of the truncated product
 * equals the true residue because 4 divides 2^32. The `alternative` arm is
 * therefore unreachable for every pair of inputs. */
__attribute__((noinline)) int32_t
opaque_square_residue(int32_t value, int32_t alternative) {
    uint32_t v = (uint32_t)value;
    uint32_t square = v * v;
    uint32_t residue = square & 3u;
    if (residue == 2u || residue == 3u) {
        return (int32_t)((uint32_t)alternative ^ residue);
    }
    return (int32_t)((square >> 2) + residue);
}

/* A branchless opaque select. `mask` is 0 in every execution, so the result is
 * always `x`, but the compiler must materialise the full blend because the
 * sentinel is volatile. Recovering this as `return a;` is correct; recovering
 * it as `return b;` is the failure mode. */
__attribute__((noinline)) int32_t
opaque_volatile_select(int32_t a, int32_t b) {
    uint32_t gate = opq146_sentinel;
    uint32_t mask = 0u - (gate & 1u);
    uint32_t x = (uint32_t)a;
    uint32_t y = (uint32_t)b;
    return (int32_t)(x ^ ((x ^ y) & mask));
}

/* An opaque predicate re-evaluated on loop-carried data: the product of two odd
 * numbers is odd, so the `else` arm never runs even though its operand changes
 * every iteration. Both arms write in bounds. */
__attribute__((noinline)) int32_t
opaque_loop_filter(int32_t *buffer, int32_t count) {
    int32_t index;
    uint32_t hits = 0u;

    if (buffer == 0 || count < 0 || count > OPAQUE146_MAX_ELEMS) {
        return -1;
    }

    for (index = 0; index < count; ++index) {
        uint32_t odd = (uint32_t)buffer[index] | 1u;
        if (((odd * odd) & 1u) == 1u) {
            buffer[index] = (int32_t)(odd + 1u);
            hits += 1u;
        } else {
            buffer[index] = 0;
        }
    }
    return (int32_t)hits;
}

/* A two-way opaque predicate: the condition genuinely depends on the input, but
 * both arms compute the same value by different routes. A decompiler is free to
 * keep either arm; it must not mix them, and it must not claim the function has
 * two behaviours. */
__attribute__((noinline)) int32_t
opaque_two_way_join(int32_t value, int32_t addend) {
    uint32_t v = (uint32_t)value;
    uint32_t k = (uint32_t)addend;
    if ((v & 1u) == 0u) {
        return (int32_t)((v ^ k) + ((v & k) << 1));
    }
    return (int32_t)((v | k) + (v & k));
}

/* The sentinel drives an index. Even under a total mis-recovery of the volatile
 * load the index stays inside the buffer: it is masked to 0..7 and then reduced
 * modulo a validated positive count. */
__attribute__((noinline)) int32_t
opaque_guarded_store(int32_t *buffer, int32_t count, int32_t value) {
    uint32_t gate = opq146_sentinel;
    int32_t index;

    if (buffer == 0 || count <= 0 || count > OPAQUE146_MAX_ELEMS) {
        return -1;
    }

    index = (int32_t)(gate & 7u) % count;
    buffer[index] = (int32_t)((uint32_t)value + 1u);
    return buffer[0];
}

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

6/6
opaque_always_true pass 11 lines
// glaurung: opaque_always_true @ 0x1100
int32_t opaque_always_true(int32_t arg0) {
    unsigned int v;
    // x86-64 prologue: save rbp
    v = arg0;
    if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((v * (unsigned long)((unsigned int)((v + 1)))))) & 1))) != 0)) {
        return (unsigned int)(((unsigned long)(v) ^ -0x21524111LL));
    } else {
        return (unsigned int)(((v * 3) + 1));
    }
}
opaque_guarded_store pass 32 lines
// glaurung: opaque_guarded_store @ 0x1310
static unsigned char glaurung_global_4024[16] __attribute__((aligned(16)));
int32_t opaque_guarded_store(int32_t * arg0, int32_t arg1, int32_t arg2) {
    extern unsigned char glaurung_global_4024[16];
    unsigned int gate;
    int index;
    int local_4;
    long var3;
    // x86-64 prologue: save rbp
    gate = *(int *)(&glaurung_global_4024[0]);
    if ((arg0 == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    var3 = (unsigned long)((unsigned int)((gate & 7)));
    index = ((int)((((long long)(int)((((unsigned long)((long)((int)(var3))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(var3)) % (int)(arg1)));
    arg0[(long)(index)] = ((unsigned long)((unsigned int)(arg2)) + 1);
    local_4 = *(int *)((long)arg0);
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
opaque_loop_filter pass 36 lines
// glaurung: opaque_loop_filter @ 0x11f0
int32_t opaque_loop_filter(int32_t * arg0, int32_t arg1) {
    unsigned int hits;
    int index;
    unsigned int odd;
    int local_4;
    // x86-64 prologue: save rbp
    hits = 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)) == 16) | ((long)(arg1) < 16)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    for (index = 0; (index < arg1); index++) {
        odd = ((unsigned int)(arg0[(long)(index)]) | 1);
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((odd * odd))) & 1))) != 1)) {
            arg0[(long)(index)] = 0;
        } else {
            arg0[(long)(index)] = (odd + 1);
            hits = (hits + 1);
        }
    }
    local_4 = hits;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
opaque_square_residue pass 27 lines
// glaurung: opaque_square_residue @ 0x1150
int32_t opaque_square_residue(int32_t arg0, int32_t arg1) {
    unsigned int v;
    unsigned int square;
    unsigned int residue;
    int local_4;
    int var8;
    // x86-64 prologue: save rbp
    v = arg0;
    square = (v * v);
    residue = (square & 3);
    if ((residue == 2)) {
        var8 = ((unsigned int)(arg1) ^ residue);
        local_4 = var8;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if ((residue == 3)) {
        var8 = ((unsigned int)(arg1) ^ residue);
        local_4 = var8;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    local_4 = ((unsigned int)(((unsigned int)(square) >> 2)) + residue);
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
opaque_two_way_join pass 13 lines
// glaurung: opaque_two_way_join @ 0x12b0
int32_t opaque_two_way_join(int32_t arg0, int32_t arg1) {
    unsigned int v;
    unsigned int k;
    // x86-64 prologue: save rbp
    v = arg0;
    k = arg1;
    if (((unsigned long)((unsigned int)((v & 1))) != 0)) {
        return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(v) | k))) + (unsigned long)((unsigned int)(((unsigned long)(v) & k)))));
    } else {
        return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(v) ^ k))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(v) & k))) << 1)))));
    }
}
opaque_volatile_select pass 16 lines
// glaurung: opaque_volatile_select @ 0x11b0
static unsigned char glaurung_global_4024[16] __attribute__((aligned(16)));
int32_t opaque_volatile_select(int32_t arg0, int32_t arg1) {
    extern unsigned char glaurung_global_4024[16];
    unsigned int gate;
    unsigned int mask;
    unsigned int x;
    unsigned int y;
    // x86-64 prologue: save rbp
    gate = *(int *)(&glaurung_global_4024[0]);
    mask = (0 - (unsigned int)((gate & 1)));
    x = arg0;
    y = arg1;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned long)(x) ^ (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(x) ^ y))) & mask)))));
}

clang -O2

6/6
opaque_always_true pass 4 lines
// glaurung: opaque_always_true @ 0x1100
int32_t opaque_always_true(int32_t arg0) {
    return (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + 1))) * arg0))) & 1))) != 0) ? (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) ^ -0x21524111LL))) : (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + (arg0 * 2)))) + 1))));
}
opaque_guarded_store pass 19 lines
// glaurung: opaque_guarded_store @ 0x1250
static unsigned char glaurung_global_4024[16] __attribute__((aligned(16)));
int32_t opaque_guarded_store(int32_t * arg0, int32_t arg1, int32_t arg2) {
    extern unsigned char glaurung_global_4024[16];
    unsigned int gate;
    long ret;
    long var0;
    int var4;
    var0 = (unsigned long)((unsigned int)(*(int *)(&glaurung_global_4024[0])));
    ret = 0xffffffff;
    if ((arg0 != 0)) {
        if (((unsigned long)(0xfffffff0) <= (unsigned long)((unsigned long)((unsigned int)((arg1 - 17)))))) {
            var4 = (unsigned int)((unsigned char)((var0 & 7)));
            arg0[(unsigned int)((unsigned char)((((unsigned long)(((((unsigned char)(((((unsigned short)(unsigned char)((((unsigned long)(var4) >> 8) & 255)) << 8) | (unsigned char)((var4 & 255))) % (unsigned char)((arg1 & 255))))) & 255) << 8)) >> 8) & 255)))] = (arg2 + 1);
            ret = (unsigned long)((unsigned int)(*(int *)(((long)arg0))));
        }
    }
    return ret;
}
opaque_loop_filter pass 97 lines
// glaurung: opaque_loop_filter @ 0x1160
int32_t opaque_loop_filter(int32_t * arg0, int32_t arg1) {
    int index;
    unsigned int hits;
    unsigned int odd;
    long ret;
    long var1;
    int var13;
    int var14;
    int var15;
    int var16;
    int var18;
    int var19;
    int var20;
    int var30;
    int var31;
    int var32;
    long var4;
    int var41;
    int var42;
    int var43;
    int var44;
    int var46;
    int var47;
    int var48;
    int var58;
    int var59;
    int var60;
    ret = 0xffffffff;
    if ((arg0 == 0)) {
        return ret;
    }
    if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return ret;
    }
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        return 0;
    }
    var1 = (unsigned long)((unsigned int)(arg1));
    if (((unsigned long)(4) <= (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        var4 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var1)) & -4)));
        var13 = -1;
        var14 = -1;
        var15 = -1;
        var16 = -1;
        var18 = ((*(int *)(((long)arg0 + 0x4)) | 1) + 1);
        var19 = ((*(int *)(((long)arg0 + 0x8)) | 1) + 1);
        var20 = ((*(int *)(((long)arg0 + 0xc)) | 1) + 1);
        *(int *)(((long)arg0)) = ((*(int *)(((long)arg0)) | 1) + 1);
        *(int *)(((long)arg0 + 0x4)) = var18;
        *(int *)(((long)arg0 + 0x8)) = var19;
        *(int *)(((long)arg0 + 0xc)) = var20;
        if ((var4 != 4)) {
            var30 = ((*(int *)(((long)arg0 + 0x14)) | 1) - var14);
            var31 = ((*(int *)(((long)arg0 + 0x18)) | 1) - var15);
            var32 = ((*(int *)(((long)arg0 + 0x1c)) | 1) - var16);
            *(int *)(((long)arg0 + 0x10)) = ((*(int *)(((long)arg0 + 0x10)) | 1) - var13);
            *(int *)(((long)arg0 + 0x14)) = var30;
            *(int *)(((long)arg0 + 0x18)) = var31;
            *(int *)(((long)arg0 + 0x1c)) = var32;
            if (((unsigned long)((unsigned int)(var4)) != 8)) {
                var41 = -1;
                var42 = -1;
                var43 = -1;
                var44 = -1;
                var46 = ((*(int *)(((long)arg0 + 0x24)) | 1) + 1);
                var47 = ((*(int *)(((long)arg0 + 0x28)) | 1) + 1);
                var48 = ((*(int *)(((long)arg0 + 0x2c)) | 1) + 1);
                *(int *)(((long)arg0 + 0x20)) = ((*(int *)(((long)arg0 + 0x20)) | 1) + 1);
                *(int *)(((long)arg0 + 0x24)) = var46;
                *(int *)(((long)arg0 + 0x28)) = var47;
                *(int *)(((long)arg0 + 0x2c)) = var48;
                if (((unsigned long)((unsigned int)(var4)) != 12)) {
                    var58 = ((*(int *)(((long)arg0 + 0x34)) | 1) - var42);
                    var59 = ((*(int *)(((long)arg0 + 0x38)) | 1) - var43);
                    var60 = ((*(int *)(((long)arg0 + 0x3c)) | 1) - var44);
                    *(int *)(((long)arg0 + 0x30)) = ((*(int *)(((long)arg0 + 0x30)) | 1) - var41);
                    *(int *)(((long)arg0 + 0x34)) = var58;
                    *(int *)(((long)arg0 + 0x38)) = var59;
                    *(int *)(((long)arg0 + 0x3c)) = var60;
                }
            }
        }
        if ((var4 != var1)) {
            L_1210: ;
            do {
                *(int *)(((long)arg0 + var4 * 4)) = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)(((long)arg0 + var4 * 4)))) | 1))) + 1);
                index = (var4 + 1);
                var4 = (unsigned long)((unsigned int)(index));
            } while ((var1 != index));
        }
    } else {
        var4 = 0;
        goto L_1210;
    }
    return (unsigned int)(arg1);
}
opaque_square_residue pass 9 lines
// glaurung: opaque_square_residue @ 0x1120
int32_t opaque_square_residue(int32_t arg0, int32_t arg1) {
    unsigned int square;
    unsigned int residue;
    long var4;
    square = (unsigned long)((unsigned int)((arg0 * arg0)));
    var4 = (unsigned long)((unsigned int)((square & 3)));
    return (((unsigned long)((unsigned char)((square & 2))) != 0) ? (unsigned long)((unsigned int)((arg1 ^ var4))) : (unsigned long)((unsigned int)((var4 + (unsigned long)((unsigned int)(((unsigned long)(square) >> 2)))))));
}
opaque_two_way_join pass 9 lines
// glaurung: opaque_two_way_join @ 0x1230
int32_t opaque_two_way_join(int32_t arg0, int32_t arg1) {
    long var0;
    var0 = (unsigned long)((unsigned int)(arg1));
    if (((unsigned long)((unsigned char)((arg0 & 1))) != 0)) {
        return (unsigned int)((var0 + arg0));
    }
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) ^ arg0))) + ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & arg0))) * 2)));
}
opaque_volatile_select pass 9 lines
// glaurung: opaque_volatile_select @ 0x1140
static unsigned char glaurung_global_4024[16] __attribute__((aligned(16)));
int32_t opaque_volatile_select(int32_t arg0, int32_t arg1) {
    extern unsigned char glaurung_global_4024[16];
    unsigned int gate;
    unsigned int mask;
    unsigned int y;
    return (unsigned int)(((unsigned long)((unsigned int)(((-(unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)(&glaurung_global_4024[0]))) & 1)))) & (unsigned long)((unsigned int)((arg1 ^ arg0)))))) ^ arg0));
}

gcc -O0

6/6
opaque_always_true pass 11 lines
// glaurung: opaque_always_true @ 0x10f9
int32_t opaque_always_true(int32_t arg0) {
    unsigned int v;
    // x86-64 prologue: save rbp
    v = arg0;
    if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((v + 1))) * v))) & 1))) != 0)) {
        return (unsigned int)(((unsigned long)(v) ^ -0x21524111LL));
    } else {
        return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(v) + (unsigned long)(v)))) + (unsigned long)(v)))) + 1));
    }
}
opaque_guarded_store pass 27 lines
// glaurung: opaque_guarded_store @ 0x12a9
static unsigned char glaurung_global_4024[16] __attribute__((aligned(16)));
int32_t opaque_guarded_store(int32_t * arg0, int32_t arg1, int32_t arg2) {
    extern unsigned char glaurung_global_4024[16];
    unsigned int gate;
    int index;
    long var3;
    // x86-64 prologue: save rbp
    gate = *(int *)(&glaurung_global_4024[0]);
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    var3 = (unsigned long)((unsigned int)((gate & 7)));
    index = ((int)((((long long)(int)((((unsigned long)((long)((int)(var3))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(var3)) % (int)(arg1)));
    arg0[(long)(index)] = ((unsigned long)((unsigned int)(arg2)) + 1);
    // x86-64 epilogue: restore rbp
    return (unsigned int)(*(int *)((long)arg0));
}
opaque_loop_filter pass 31 lines
// glaurung: opaque_loop_filter @ 0x11b8
int32_t opaque_loop_filter(int32_t * arg0, int32_t arg1) {
    unsigned int hits;
    int index;
    unsigned int odd;
    // x86-64 prologue: save rbp
    hits = 0;
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((long)(arg1) < 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    for (index = 0; (index < arg1); index++) {
        odd = ((unsigned int)(arg0[(long)(index)]) | 1);
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((odd * odd))) & 1))) == 0)) {
            arg0[(long)(index)] = 0;
        } else {
            arg0[(long)(index)] = (odd + 1);
            hits = (hits + 1);
        }
    }
    // x86-64 epilogue: restore rbp
    return hits;
}
opaque_square_residue pass 23 lines
// glaurung: opaque_square_residue @ 0x1133
int32_t opaque_square_residue(int32_t arg0, int32_t arg1) {
    unsigned int v;
    unsigned int square;
    unsigned int residue;
    int var8;
    // x86-64 prologue: save rbp
    v = arg0;
    square = (v * v);
    residue = (square & 3);
    if ((residue == 2)) {
        var8 = ((unsigned int)(arg1) ^ residue);
        // x86-64 epilogue: restore rbp
        return (unsigned int)(var8);
    }
    if ((residue == 3)) {
        var8 = ((unsigned int)(arg1) ^ residue);
        // x86-64 epilogue: restore rbp
        return (unsigned int)(var8);
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned long)(residue) + (unsigned long)((unsigned int)(((unsigned long)(square) >> 2)))));
}
opaque_two_way_join pass 15 lines
// glaurung: opaque_two_way_join @ 0x1267
int32_t opaque_two_way_join(int32_t arg0, int32_t arg1) {
    unsigned int v;
    unsigned int k;
    long var14;
    // x86-64 prologue: save rbp
    v = arg0;
    k = arg1;
    if (((unsigned long)((unsigned int)((v & 1))) != 0)) {
        return (unsigned int)(((unsigned long)(k) + (unsigned long)(v)));
    } else {
        var14 = (unsigned long)((unsigned int)((v & k)));
        return (unsigned int)(((unsigned long)((unsigned int)((var14 + var14))) + (unsigned long)((unsigned int)(((unsigned long)(v) ^ k)))));
    }
}
opaque_volatile_select pass 16 lines
// glaurung: opaque_volatile_select @ 0x117c
static unsigned char glaurung_global_4024[16] __attribute__((aligned(16)));
int32_t opaque_volatile_select(int32_t arg0, int32_t arg1) {
    extern unsigned char glaurung_global_4024[16];
    unsigned int gate;
    unsigned int mask;
    unsigned int x;
    unsigned int y;
    // x86-64 prologue: save rbp
    gate = *(int *)(&glaurung_global_4024[0]);
    mask = (-(unsigned long)((unsigned int)((gate & 1))));
    x = arg0;
    y = arg1;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)(x) ^ y))) & mask))) ^ x));
}

gcc -O2

6/6
opaque_always_true pass 9 lines
// glaurung: opaque_always_true @ 0x1100
int32_t opaque_always_true(int32_t arg0) {
    long var5;
    var5 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) ^ -0x21524111LL)));
    if (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + 1))) * arg0))) & 1))) == 0)) {
        var5 = (unsigned long)((unsigned int)(((arg0 + (arg0 * 2)) + 1)));
    }
    return (unsigned int)(var5);
}
opaque_guarded_store pass 20 lines
// glaurung: opaque_guarded_store @ 0x11f0
static unsigned char glaurung_global_4024[16] __attribute__((aligned(16)));
int32_t opaque_guarded_store(int32_t * arg0, int32_t arg1, int32_t arg2) {
    extern unsigned char glaurung_global_4024[16];
    unsigned int gate;
    int index;
    long var0;
    long var2;
    long var4;
    var0 = (unsigned long)((unsigned int)(arg2));
    var2 = (unsigned long)((unsigned int)(*(int *)(&glaurung_global_4024[0])));
    if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 1)))) <= (unsigned long)(15))) {
        if ((arg0 != 0)) {
            var4 = (unsigned long)((unsigned int)((var2 & 7)));
            arg0[(long)((int)(((int)((((long long)(int)((((unsigned long)((long)((int)(var4))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(var4)) % (int)(arg1)))))] = (var0 + 1);
            return (unsigned int)(*(int *)(((long)arg0)));
        }
    }
    return 0xffffffff;
}
opaque_loop_filter pass 35 lines
// glaurung: opaque_loop_filter @ 0x1170
int32_t opaque_loop_filter(int32_t * arg0, int32_t arg1) {
    unsigned int odd;
    unsigned int hits;
    int index;
    long ret;
    long var2;
    long var5;
    long var6;
    long var7;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return 0xffffffff;
    }
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        return 0;
    }
    var2 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 1))) * 4)) + 4));
    ret = 0;
    var5 = var6;
    var7 = (long)arg0;
    do {
        var5 = 0;
        odd = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)((var7)))) | 1)));
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((odd * odd))) & 1))) != 0)) {
            var5 = (unsigned long)((unsigned int)((odd + 1)));
            ret = (unsigned long)((unsigned int)((ret + 1)));
        }
        *(int *)((var7)) = var5;
        var7 = (var7 + 4);
    } while ((var2 != var7));
    return ret;
}
opaque_square_residue pass 8 lines
// glaurung: opaque_square_residue @ 0x1130
int32_t opaque_square_residue(int32_t arg0, int32_t arg1) {
    unsigned int residue;
    unsigned int square;
    long var1;
    var1 = (unsigned long)((unsigned int)((arg0 * arg0)));
    return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var1)) >> 2))) + (unsigned long)((unsigned int)((var1 & 3)))));
}
opaque_two_way_join pass 7 lines
// glaurung: opaque_two_way_join @ 0x11d0
int32_t opaque_two_way_join(int32_t arg0, int32_t arg1) {
    if (((unsigned long)((unsigned char)((arg0 & 1))) == 0)) {
        return (unsigned int)(((unsigned long)((unsigned int)((arg0 ^ arg1))) + ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & arg1))) * 2)));
    }
    return (unsigned int)((arg0 + arg1));
}
opaque_volatile_select pass 9 lines
// glaurung: opaque_volatile_select @ 0x1150
static unsigned char glaurung_global_4024[16] __attribute__((aligned(16)));
int32_t opaque_volatile_select(int32_t arg0, int32_t arg1) {
    extern unsigned char glaurung_global_4024[16];
    unsigned int gate;
    unsigned int mask;
    unsigned int y;
    return (unsigned int)(((unsigned long)((unsigned int)(((-(unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)(&glaurung_global_4024[0]))) & 1)))) & (unsigned long)((unsigned int)((arg1 ^ arg0)))))) ^ arg0));
}

← 213 fixtures