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.
#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/6branched_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/6branched_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/6branched_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/6branched_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)));
}