Fixture 213

arm predicated execution

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

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

Branchless conditional code: A32 predication, Thumb-2 IT blocks, AArch64 csel, and x86 cmov — the same source shape lowered four different ways, every one of which writes a register CONDITIONALLY.

WHY THIS IS A DATAFLOW FIXTURE, NOT A CONTROL-FLOW ONE. A predicated write is a conditional definition: after mvnhi r0, #0, r0 holds either the new value or its previous one, and which is a runtime fact. Our ARM handling treats a definition as unconditional — arm_defined_register names the register an instruction writes purely from the mnemonic, with no notion of a predicate, and DispatchTracker::kill_register then discards everything known about it. For a range bound that is the safe direction (a lost bound costs a resolution). For a VALUE it is not: the two sides of the predicate must both reach the reader, and a model with only one has to pick.

This bit during the ARM jump-table work: a hand-written A32 reproduction of a table dispatch compiled to cmp r0,#7 / mvnhi r0,#0 / bxhi lr — the guard's failing path was PREDICATED rather than branched, so there was no conditional branch for the bound to propagate across, and the dispatch declined. The corpus firmware uses a real bhi, so the reproduction was unrepresentative in a way that cost an afternoon. Nothing in the corpus covered predication, which is why nothing said so.

14_flag_effects covers flag producers and consumers on x86, where the consumer is a branch or a setcc. 01_conditional_polarity covers which arm a branch takes. Neither has a conditionally-executed instruction.

Written as ordinary C so every compiler picks its own branchless idiom; the shapes below are the ones that reliably produce one at -O2. All lanes must agree on the answer, which is what makes a mis-modelled conditional definition visible.

tests/decompiler_fixtures/src/213_arm_predicated_execution.c source
#include <stdint.h>

/* Branchless conditional code: A32 predication, Thumb-2 IT blocks, AArch64
 * `csel`, and x86 `cmov` — the same source shape lowered four different ways,
 * every one of which writes a register CONDITIONALLY.
 *
 * WHY THIS IS A DATAFLOW FIXTURE, NOT A CONTROL-FLOW ONE. A predicated write is
 * a conditional definition: after `mvnhi r0, #0`, `r0` holds either the new
 * value or its previous one, and which is a runtime fact. Our ARM handling
 * treats a definition as unconditional — `arm_defined_register` names the
 * register an instruction writes purely from the mnemonic, with no notion of a
 * predicate, and `DispatchTracker::kill_register` then discards everything
 * known about it. For a range bound that is the safe direction (a lost bound
 * costs a resolution). For a VALUE it is not: the two sides of the predicate
 * must both reach the reader, and a model with only one has to pick.
 *
 * This bit during the ARM jump-table work: a hand-written A32 reproduction of a
 * table dispatch compiled to `cmp r0,#7 / mvnhi r0,#0 / bxhi lr` — the guard's
 * failing path was PREDICATED rather than branched, so there was no conditional
 * branch for the bound to propagate across, and the dispatch declined. The
 * corpus firmware uses a real `bhi`, so the reproduction was unrepresentative
 * in a way that cost an afternoon. Nothing in the corpus covered predication,
 * which is why nothing said so.
 *
 * `14_flag_effects` covers flag producers and consumers on x86, where the
 * consumer is a branch or a `setcc`. `01_conditional_polarity` covers which arm
 * a branch takes. Neither has a conditionally-executed instruction.
 *
 * Written as ordinary C so every compiler picks its own branchless idiom; the
 * shapes below are the ones that reliably produce one at -O2. All lanes must
 * agree on the answer, which is what makes a mis-modelled conditional
 * definition visible.
 */

/* The canonical `cmov`/`csel`/`movhi` shape. */
__attribute__((noinline)) int32_t select_max(int32_t a, int32_t b) {
    return a > b ? a : b;
}

/* Two predicated writes to the SAME register in sequence, so a model that
 * keeps only the last definition produces a plausible wrong answer. */
__attribute__((noinline)) int32_t chained_selects(int32_t a, int32_t b,
                                                  int32_t c) {
    int32_t r = a;
    r = (b > r) ? b : r;
    r = (c > r) ? c : r;
    return r;
}

/* A predicated write whose value is CARRIED FORWARD when the predicate is
 * false: the false path is not a no-op, it is "keep what was there". This is
 * the case an unconditional-definition model gets wrong. */
__attribute__((noinline)) int32_t conditional_accumulate(const int32_t *values,
                                                          int32_t count) {
    int32_t acc = 0;
    int32_t last_positive = -1;
    if (values == 0 || count < 0 || count > 16) {
        return -1;
    }
    for (int32_t i = 0; i < count; i++) {
        int32_t v = values[i];
        acc += v;
        /* `last_positive` is written only on the taken side; on the other side
         * its previous value must survive. */
        last_positive = (v > 0) ? v : last_positive;
    }
    return acc + last_positive;
}

/* A predicated RETURN — on A32 this is `bxCC lr`, which ends the block without
 * a branch instruction and keeps lexical fallthrough. */
__attribute__((noinline)) int32_t early_out_branchless(int32_t a, int32_t b) {
    if (a < 0) {
        return -1;
    }
    return (a > b) ? (a - b) : (b - a);
}

/* Three-way branchless classification: enough predicated writes that a
 * conflated definition is arithmetically visible rather than coincidentally
 * equal. */
__attribute__((noinline)) int32_t branchless_classify(int32_t x, int32_t lo,
                                                      int32_t hi) {
    int32_t code = 0;
    code = (x < lo) ? 1 : code;
    code = (x > hi) ? 2 : code;
    code = (x == lo) ? 3 : code;
    code = (x == hi) ? 4 : code;
    return code * 10 + ((x < 0) ? 5 : 6);
}

/* CONTROL: the same decision written so every compiler emits real branches
 * (the arms have side effects and differing costs). If this fails too, the
 * defect is in branch handling and not in predication. */
static int32_t sink_value;

__attribute__((noinline)) int32_t branched_control(int32_t a, int32_t b) {
    if (a > b) {
        sink_value = a;
        return a * 3 + 1;
    }
    sink_value = b;
    return b * 5 + 2;
}

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
branched_control pass 13 lines
// glaurung: branched_control @ 0x1360
static unsigned char glaurung_global_4024[16] __attribute__((aligned(16)));
int32_t branched_control(int32_t arg0, int32_t arg1) {
    extern unsigned char glaurung_global_4024[16];
    // x86-64 prologue: save rbp
    if ((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1))) {
        *(int *)(&glaurung_global_4024[0]) = arg1;
        return (unsigned int)(((arg1 * 5) + 2));
    } else {
        *(int *)(&glaurung_global_4024[0]) = arg0;
        return (unsigned int)(((arg0 * 3) + 1));
    }
}
branchless_classify pass 20 lines
// glaurung: branchless_classify @ 0x1290
int32_t branchless_classify(int32_t arg0, int32_t arg1, int32_t arg2) {
    int code;
    int local_14;
    int local_18;
    int local_1c;
    int local_20;
    // x86-64 prologue: save rbp
    code = 0;
    local_14 = ((arg1 <= arg0) ? (unsigned long)((unsigned int)(code)) : 1);
    code = local_14;
    local_18 = ((((unsigned int)(arg0) == (unsigned int)(arg2)) | (arg0 < arg2)) ? (unsigned long)((unsigned int)(code)) : 2);
    code = local_18;
    local_1c = (((unsigned int)(arg0) != (unsigned int)(arg1)) ? (unsigned long)((unsigned int)(code)) : 3);
    code = local_1c;
    local_20 = (((unsigned int)(arg0) != (unsigned int)(arg2)) ? (unsigned long)((unsigned int)(code)) : 4);
    code = local_20;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((code * 10) + (((long)(arg0) < 0) ? 5 : 6)));
}
chained_selects pass 14 lines
// glaurung: chained_selects @ 0x1130
int32_t chained_selects(int32_t arg0, int32_t arg1, int32_t arg2) {
    int r;
    int local_14;
    int local_18;
    // x86-64 prologue: save rbp
    r = arg0;
    local_14 = ((((unsigned int)(arg1) == (unsigned int)(r)) | (arg1 < r)) ? (unsigned long)((unsigned int)(r)) : (unsigned long)((unsigned int)(arg1)));
    r = local_14;
    local_18 = ((((unsigned int)(arg2) == (unsigned int)(r)) | (arg2 < r)) ? (unsigned long)((unsigned int)(r)) : (unsigned long)((unsigned int)(arg2)));
    r = local_18;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(r);
}
conditional_accumulate pass 36 lines
// glaurung: conditional_accumulate @ 0x1190
int32_t conditional_accumulate(const int32_t * arg0, int32_t arg1) {
    int acc;
    int last_positive;
    int i;
    int v;
    int local_28;
    int local_4;
    // x86-64 prologue: save rbp
    acc = 0;
    last_positive = -1;
    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 (i = 0; (i < arg1); i++) {
        v = arg0[(long)(i)];
        acc = ((unsigned int)(v) + acc);
        local_28 = ((((unsigned long)((unsigned int)(v)) == 0) | ((long)(v) < 0)) ? (unsigned long)((unsigned int)(last_positive)) : (unsigned long)((unsigned int)(v)));
        last_positive = local_28;
    }
    local_4 = ((unsigned int)(acc) + last_positive);
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
early_out_branchless pass 11 lines
// glaurung: early_out_branchless @ 0x1240
int32_t early_out_branchless(int32_t arg0, int32_t arg1) {
    int local_10;
    // x86-64 prologue: save rbp
    if ((0 <= (long)(arg0))) {
        local_10 = ((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1)) ? ((unsigned long)((unsigned int)(arg1)) - (unsigned long)((unsigned int)(arg0))) : ((unsigned long)((unsigned int)(arg0)) - (unsigned long)((unsigned int)(arg1))));
        return (unsigned int)(local_10);
    } else {
        return (unsigned int)(-1);
    }
}
select_max pass 9 lines
// glaurung: select_max @ 0x1100
int32_t select_max(int32_t arg0, int32_t arg1) {
    // x86-64 prologue: save rbp
    if ((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1))) {
        return (unsigned int)(arg1);
    } else {
        return (unsigned int)(arg0);
    }
}

clang -O2

6/6
branched_control pass 4 lines
// glaurung: branched_control @ 0x1240
int32_t branched_control(int32_t arg0, int32_t arg1) {
    return (((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1)) == 0) ? (unsigned long)((unsigned int)(((arg0 + (arg0 * 2)) + 1))) : (unsigned long)((unsigned int)(((arg1 + (arg1 * 4)) + 2))));
}
branchless_classify pass 4 lines
// glaurung: branchless_classify @ 0x1200
int32_t branchless_classify(int32_t arg0, int32_t arg1, int32_t arg2) {
    return (unsigned int)(((unsigned long)((unsigned int)(((((unsigned int)(arg0) != (unsigned int)(arg2)) ? (((unsigned int)(arg0) != (unsigned int)(arg1)) ? ((((unsigned int)(arg0) == (unsigned int)(arg2)) | (arg0 < arg2)) ? ((arg1 <= arg0) ? 0 : 10) : 20) : 30) : 40) + (unsigned long)((unsigned int)(((int)(arg0) >> 31)))))) + 6));
}
chained_selects pass 7 lines
// glaurung: chained_selects @ 0x1110
int32_t chained_selects(int32_t arg0, int32_t arg1, int32_t arg2) {
    int r;
    int var1;
    var1 = (((((unsigned int)(arg1) == (unsigned int)(arg0)) | (arg1 < arg0)) == 0) ? arg1 : (unsigned long)((unsigned int)(arg0)));
    return ((var1 < arg2) ? arg2 : var1);
}
conditional_accumulate pass 75 lines
// glaurung: conditional_accumulate @ 0x1120
int32_t conditional_accumulate(const int32_t * arg0, int32_t arg1) {
    int i;
    int acc;
    int last_positive;
    int v;
    long ret;
    long var1;
    long var12;
    long var13;
    long var14;
    long var15;
    long var22;
    long var26;
    int var27;
    long var29;
    int var30;
    long var31;
    long var37;
    long var39;
    long var40;
    long var41;
    long var42;
    int var43;
    long var5;
    long var7;
    ret = 0xffffffff;
    if (((unsigned long)(15) < (unsigned long)((unsigned long)((unsigned int)((arg1 - 1)))))) {
        return ret;
    }
    if ((arg0 == 0)) {
        return ret;
    }
    var1 = (unsigned long)((unsigned int)(arg1));
    var5 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 3)));
    if (((unsigned long)(3) <= (unsigned long)(((unsigned long)((unsigned int)(arg1)) - 1)))) {
        var7 = (unsigned long)((unsigned int)((var1 & -4)));
        i = 0;
        var12 = 0;
        var13 = 0xffffffff;
        do {
            var14 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + i * 4))));
            var15 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + i * 4 + 0x4))));
            var22 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + i * 4 + 0x8))));
            var26 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + i * 4 + 0xc))));
            var27 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var12 + var14))) + var15))) + var22)) + var26);
            var13 = (((((unsigned long)((unsigned int)(var26)) == 0) | ((long)((int)(var26)) < 0)) == 0) ? var26 : (((((unsigned long)((unsigned int)(var22)) == 0) | ((long)((int)(var22)) < 0)) == 0) ? var22 : (((((unsigned long)((unsigned int)(var15)) == 0) | ((long)((int)(var15)) < 0)) == 0) ? var15 : (((((unsigned long)((unsigned int)(var14)) == 0) | ((long)((int)(var14)) < 0)) == 0) ? var14 : var13))));
            i = (i + 4);
            var12 = (unsigned long)((unsigned int)(var27));
            var29 = (unsigned long)((unsigned int)(var27));
            var30 = var13;
            var31 = (unsigned long)((unsigned int)(i));
        } while ((var7 != i));
    } else {
        var29 = 0;
        var30 = 0xffffffff;
        var31 = 0;
    }
    if ((var5 != 0)) {
        var37 = (long)(((long)arg0 + (var31 * 4)));
        var39 = 0;
        var40 = var29;
        var41 = (unsigned long)((unsigned int)(var30));
        while ((var5 != var39)) {
            var42 = (unsigned long)((unsigned int)(*(int *)((var37 + var39 * 4))));
            var43 = (var40 + var42);
            var40 = (unsigned long)((unsigned int)(var43));
            var41 = (((((unsigned long)((unsigned int)(var42)) == 0) | ((long)((int)(var42)) < 0)) == 0) ? var42 : var41);
            var39 = (var39 + 1);
            var29 = (unsigned long)((unsigned int)(var43));
            var30 = var41;
        }
    }
    return (unsigned int)((var29 + var30));
}
early_out_branchless pass 6 lines
// glaurung: early_out_branchless @ 0x11e0
int32_t early_out_branchless(int32_t arg0, int32_t arg1) {
    int var5;
    var5 = ((unsigned int)(arg0) - arg1);
    return ((0 <= (long)(arg0)) ? ((((unsigned long)((unsigned int)(var5)) == 0) | (arg0 < arg1)) ? (-(unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) - arg1)))) : (unsigned long)((unsigned int)(var5))) : 0xffffffff);
}
select_max pass 4 lines
// glaurung: select_max @ 0x1100
int32_t select_max(int32_t arg0, int32_t arg1) {
    return (((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1)) == 0) ? arg0 : (unsigned long)((unsigned int)(arg1)));
}

gcc -O0

6/6
branched_control pass 13 lines
// glaurung: branched_control @ 0x1295
static unsigned char glaurung_global_4024[16] __attribute__((aligned(16)));
int32_t branched_control(int32_t arg0, int32_t arg1) {
    extern unsigned char glaurung_global_4024[16];
    // x86-64 prologue: save rbp
    if ((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1))) {
        *(int *)(&glaurung_global_4024[0]) = arg1;
        return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) << 2))) + (unsigned long)((unsigned int)(arg1))))) + 2));
    } else {
        *(int *)(&glaurung_global_4024[0]) = arg0;
        return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + (unsigned long)((unsigned int)(arg0))))) + (unsigned long)((unsigned int)(arg0))))) + 1));
    }
}
branchless_classify pass 14 lines
// glaurung: branchless_classify @ 0x1205
int32_t branchless_classify(int32_t arg0, int32_t arg1, int32_t arg2) {
    int code;
    int var12;
    // x86-64 prologue: save rbp
    code = 0;
    code = ((arg0 < arg1) ? 1 : (unsigned long)((unsigned int)(code)));
    code = (((((unsigned int)(arg0) == (unsigned int)(arg2)) | (arg0 < arg2)) == 0) ? 2 : (unsigned long)((unsigned int)(code)));
    code = (((unsigned int)(arg0) == (unsigned int)(arg1)) ? 3 : (unsigned long)((unsigned int)(code)));
    code = (((unsigned int)(arg0) == (unsigned int)(arg2)) ? 4 : (unsigned long)((unsigned int)(code)));
    var12 = ((unsigned int)(((unsigned long)((unsigned int)(code)) << 2)) + (unsigned int)(code));
    // x86-64 epilogue: restore rbp
    return (unsigned int)((((0 <= (long)(arg0)) ? 6 : 5) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var12)) + (unsigned long)((unsigned int)(var12)))))));
}
chained_selects pass 10 lines
// glaurung: chained_selects @ 0x1114
int32_t chained_selects(int32_t arg0, int32_t arg1, int32_t arg2) {
    int r;
    // x86-64 prologue: save rbp
    r = arg0;
    r = ((arg1 <= r) ? (unsigned long)((unsigned int)(r)) : (unsigned long)((unsigned int)(arg1)));
    r = ((arg2 <= r) ? (unsigned long)((unsigned int)(r)) : (unsigned long)((unsigned int)(arg2)));
    // x86-64 epilogue: restore rbp
    return (unsigned int)(r);
}
conditional_accumulate pass 29 lines
// glaurung: conditional_accumulate @ 0x114c
int32_t conditional_accumulate(const int32_t * arg0, int32_t arg1) {
    int acc;
    int last_positive;
    int i;
    int v;
    // x86-64 prologue: save rbp
    acc = 0;
    last_positive = -1;
    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 (i = 0; (i < arg1); i++) {
        v = arg0[(long)(i)];
        acc = (acc + (unsigned int)(v));
        last_positive = ((((unsigned long)((unsigned int)(v)) == 0) | ((long)(v) < 0)) ? (unsigned long)((unsigned int)(last_positive)) : (unsigned long)((unsigned int)(v)));
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(((unsigned long)((unsigned int)(last_positive)) + (unsigned long)((unsigned int)(acc))));
}
early_out_branchless pass 13 lines
// glaurung: early_out_branchless @ 0x11d2
int32_t early_out_branchless(int32_t arg0, int32_t arg1) {
    // x86-64 prologue: save rbp
    if ((0 <= (long)(arg0))) {
        if ((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1))) {
            return (unsigned int)(((unsigned long)((unsigned int)(arg1)) - arg0));
        } else {
            return (unsigned int)(((unsigned long)((unsigned int)(arg0)) - arg1));
        }
    } else {
        return 0xffffffff;
    }
}
select_max pass 6 lines
// glaurung: select_max @ 0x10f9
int32_t select_max(int32_t arg0, int32_t arg1) {
    // x86-64 prologue: save rbp
    // x86-64 epilogue: restore rbp
    return ((arg0 <= arg1) ? (unsigned long)((unsigned int)(arg1)) : (unsigned long)((unsigned int)(arg0)));
}

gcc -O2

6/6
branched_control pass 7 lines
// glaurung: branched_control @ 0x11f0
int32_t branched_control(int32_t arg0, int32_t arg1) {
    if (((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1)) == 0)) {
        return (unsigned int)(((arg0 + (arg0 * 2)) + 1));
    }
    return (unsigned int)(((arg1 + (arg1 * 4)) + 2));
}
branchless_classify pass 25 lines
// glaurung: branchless_classify @ 0x11a0
int32_t branchless_classify(int32_t arg0, int32_t arg1, int32_t arg2) {
    int code;
    long var12;
    long var6;
    if (((((unsigned int)(arg0) == (unsigned int)(arg2)) | (arg0 < arg2)) == 0)) {
        goto L_11d0;
    }
    code = (((unsigned int)(arg0) == (unsigned int)(arg1)) ? 3 : (arg0 < arg1));
    var6 = 40;
    if (((unsigned int)(arg0) != (unsigned int)(arg2))) {
        var12 = (unsigned long)((unsigned int)((code + (code * 4))));
        return (unsigned int)((((unsigned long)((unsigned int)((var12 + var12))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((~arg0))) >> 31)))) + 5));
    }
    L_11c0: ;
    return (unsigned int)(((var6 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((~arg0))) >> 31)))) + 5));
    L_11d0: ;
    var6 = 20;
    code = 3;
    if (((unsigned int)(arg0) != (unsigned int)(arg1))) {
        goto L_11c0;
    }
    var12 = (unsigned long)((unsigned int)((code + (code * 4))));
    return (unsigned int)((((unsigned long)((unsigned int)((var12 + var12))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((~arg0))) >> 31)))) + 5));
}
chained_selects pass 6 lines
// glaurung: chained_selects @ 0x1110
int32_t chained_selects(int32_t arg0, int32_t arg1, int32_t arg2) {
    int var1;
    var1 = ((arg1 < arg2) ? arg2 : arg1);
    return ((arg0 <= var1) ? var1 : (unsigned long)((unsigned int)(arg0)));
}
conditional_accumulate pass 31 lines
// glaurung: conditional_accumulate @ 0x1130
int32_t conditional_accumulate(const int32_t * arg0, int32_t arg1) {
    int v;
    int acc;
    int i;
    int last_positive;
    long var3;
    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 0xffffffff;
    }
    var3 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 1))) * 4)) + 4));
    var5 = 0xffffffff;
    var6 = 0;
    var7 = (long)arg0;
    do {
        v = (unsigned long)((unsigned int)(*(int *)((var7))));
        var6 = (unsigned long)((unsigned int)((var6 + v)));
        var5 = (((((unsigned long)((unsigned int)(v)) == 0) | ((long)(v) < 0)) == 0) ? v : var5);
        var7 = (var7 + 4);
    } while ((var7 != var3));
    return (unsigned int)((var5 + var6));
}
early_out_branchless pass 7 lines
// glaurung: early_out_branchless @ 0x1180
int32_t early_out_branchless(int32_t arg0, int32_t arg1) {
    if (((long)(arg0) < 0)) {
        return 0xffffffff;
    }
    return (((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1)) == 0) ? (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) - arg1))) : (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) - arg0))));
}
select_max pass 4 lines
// glaurung: select_max @ 0x1100
int32_t select_max(int32_t arg0, int32_t arg1) {
    return ((arg0 <= arg1) ? arg1 : (unsigned long)((unsigned int)(arg0)));
}

← 213 fixtures