Fixture 13
loop early exit
C · 6 functions · 4 lanes · 24 of 24 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
Loops whose body can leave the function.
At -O0 every return in a function jumps to ONE shared epilogue block, so a return inside a loop makes that epilogue post-dominate the loop body. A structurer that trusts the immediate post-dominator as an if/else join then places the epilogue INSIDE the loop: the loop can run at most one iteration, and the code after the loop loses its return.
sort:bsearch_i in the DecBench corpus decompiled to exactly that — an unconditional return ret; at the bottom of the loop and a trailing ret = -1; with no return — and the graph-edit-distance metric scored it fine. Only running it caught the problem, which is why these live here: the fixture gate is execution-differential per function per lane.
Each function below reaches the shared epilogue from a different place, so a fix that special-cases one shape does not pass the rest.
As committed, 19 of these 24 cells (6 functions x 4 lanes) FAIL. That is recorded in baseline.json deliberately: the gate fails on new breakage while known bugs stay visible. Two of the failures are not early-exit defects at all — see sum_positive — so do not read a green fixture 13 as proof that Phase B worked without checking WHICH cells moved.
/* Loops whose body can leave the function.
*
* At -O0 every `return` in a function jumps to ONE shared epilogue block, so a
* `return` inside a loop makes that epilogue post-dominate the loop body. A
* structurer that trusts the immediate post-dominator as an if/else join then
* places the epilogue INSIDE the loop: the loop can run at most one iteration,
* and the code after the loop loses its return.
*
* `sort:bsearch_i` in the DecBench corpus decompiled to exactly that — an
* unconditional `return ret;` at the bottom of the loop and a trailing
* `ret = -1;` with no `return` — and the graph-edit-distance metric scored it
* fine. Only running it caught the problem, which is why these live here: the
* fixture gate is execution-differential per function per lane.
*
* Each function below reaches the shared epilogue from a different place, so a
* fix that special-cases one shape does not pass the rest.
*
* As committed, 19 of these 24 cells (6 functions x 4 lanes) FAIL. That is recorded
* in baseline.json deliberately: the gate fails on new breakage while known bugs
* stay visible. Two of the failures are not early-exit defects at all — see
* `sum_positive` — so do not read a green fixture 13 as proof that Phase B worked
* without checking WHICH cells moved.
*/
/* The canonical case: an early return from inside a loop, plus a fallthrough
* return after it. Two paths into one epilogue. */
int find_first(const int *a, int n, int key) {
for (int i = 0; i < n; i++) {
if (a[i] == key) return i;
}
return -1;
}
/* The bsearch shape specifically: the early return is nested two conditionals
* deep, and the sibling arms both continue the loop via a back edge. Those back
* edges are what make the post-dominator the wrong join. */
int bisect(const int *a, int n, int key) {
int lo = 0, hi = n - 1;
while (lo <= hi) {
int m = (lo + hi) / 2;
if (a[m] == key) return m;
if (a[m] < key) lo = m + 1;
else hi = m - 1;
}
return -1;
}
/* Two early returns from the same loop, with different values, so a structurer
* that collapses the epilogue into a single tail must still distinguish them. */
/* HOIST TRAP — measured, do not "simplify" this loop's lowering.
*
* This function is one of exactly four the loop-header hoist fallback protects. The
* verbose `while (1) { pre; if (!cond) break; }` form it decompiles to is NOT an
* accident to be tidied away: hoisting the header above the loop lets constant
* propagation substitute the initial value that dominates at the hoist position, which
* freezes the loop-carried value and the loop stops making progress.
*
* Measured on branch `recover-ged-cells` (see docs/design/ged-recovery-measured-trade.md):
* always-hoisting recovers 50.32 GED points, 46% of a regression — and breaks exactly
* these four functions across six lanes:
* 03_loop_shapes:gcc:O2:while_prefix
* 12_loop_rotation:gcc:O2:find_first_set
* 13_loop_early_exit:{clang,gcc}:O2:classify_run
* 14_flag_effects:{clang,gcc}:O0:countdown
* So the compact form is worth real score, and it is wrong. That is the trade.
*
* FOUR predicates have been tried and all four failed, each differently: a copy-chain
* rule, a loop-invariance rule, a use-count rule, and a post-fold check requiring only a
* nonempty read/write intersection (which passes `find_first_set`, whose body reassigns
* its flag lower down while the frozen value sits inside the hoisted expression). If a
* post-fold check is attempted again it must preserve EVERY original loop-carried
* dependency, not one overlapping register.
*
* The real fix is typed value identity plus dominance, where "may this expression move
* here" is a query rather than a guess — value-model-root-cause-and-plan.md Phase 2.
*/
int classify_run(const int *a, int n) {
for (int i = 1; i < n; i++) {
if (a[i] < a[i - 1]) return -1;
if (a[i] == a[i - 1]) return 0;
}
return 1;
}
/* An early return from a NESTED loop: the epilogue post-dominates both loop
* bodies, so the wrong-join failure can occur at either depth. */
int has_pair(const int *a, int n, int target) {
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (a[i] + a[j] == target) return 1;
}
}
return 0;
}
/* A loop whose early exit is a `break` rather than a `return`: the join really
* is inside the function, so this one should be structured as a loop with a break.
* It was written as the counterexample that stops a fix from being "never use the
* post-dominator" — but it does NOT currently pass. It decompiles with an
* unconditional `return` at the bottom of the loop body and a `goto` to an empty
* label, i.e. the same shape as `bisect`. So it is not yet a control; it is
* another instance. Re-read this comment once Phase B lands. */
int sum_until_zero(const int *a, int n) {
int s = 0;
for (int i = 0; i < n; i++) {
if (a[i] == 0) break;
s += a[i];
}
return s;
}
/* A `continue` in the middle: a back edge from inside a conditional, which is
* the same edge kind that misleads the join choice in `bisect` — but here there is
* no early return, so structuring is NOT the problem.
*
* This one fails for two entirely different reasons, which is why it earns its
* place: gcc -O0 emits the guard as `test %eax,%eax ; jle`, our `test` lifting
* does not define Flag::Sle, so `jle` reads the stale Sle left by the loop's own
* `cmp`; and the inverted condition then renders as `~sle`, where bitwise NOT of a
* 0/1 flag is always true. The guard therefore never skips and the function sums
* every element. Neither defect has anything to do with early exits — the fixture
* found them by accident, which is the argument for fixtures over targeted cases. */
int sum_positive(const int *a, int n) {
int s = 0;
for (int i = 0; i < n; i++) {
if (a[i] <= 0) continue;
s += a[i];
}
return s;
} 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/6bisect pass 32 lines
// glaurung: bisect @ 0x1160
int bisect(const int * arg0, int arg1, int arg2) {
int lo;
int hi;
int m;
int local_4;
int var5;
lo = 0;
hi = ((unsigned int)(arg1) - 1);
L_117e: ;
if (((((unsigned int)(lo) == (unsigned int)(hi)) | (lo < hi)) == 0)) {
goto L_11ea;
}
var5 = ((unsigned int)(lo) + hi);
m = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(var5))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(var5)))) / (int)(2)));
if (((unsigned int)(arg0[(long)(m)]) == (unsigned int)(arg2))) {
local_4 = m;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((long)((int)(arg0[(long)(m)])) < (long)(arg2))) {
lo = ((unsigned int)(m) + 1);
goto L_11e5;
}
hi = ((unsigned int)(m) - 1);
L_11e5: ;
goto L_117e;
L_11ea: ;
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} classify_run pass 26 lines
// glaurung: classify_run @ 0x1200
int classify_run(const int * arg0, int arg1) {
int i;
int local_4;
i = 1;
L_1212: ;
if ((arg1 <= i)) {
goto L_128b;
}
if (((long)((int)(arg0[(long)(i)])) < (long)((int)(arg0[(long)((int)(((unsigned long)((unsigned int)(i)) - 1)))])))) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((unsigned int)(arg0[(long)(i)]) == (unsigned int)(arg0[(long)((int)(((unsigned long)((unsigned int)(i)) - 1)))]))) {
// x86-64 epilogue: restore rbp
return 0;
}
goto L_127d;
L_127d: ;
i = ((unsigned int)(i) + 1);
goto L_1212;
L_128b: ;
// x86-64 epilogue: restore rbp
return 1;
} find_first pass 23 lines
// glaurung: find_first @ 0x1100
int find_first(const int * arg0, int arg1, int arg2) {
int i;
int local_4;
i = 0;
L_1115: ;
if ((arg1 <= i)) {
goto L_1153;
}
if (((unsigned int)(arg0[(long)(i)]) == (unsigned int)(arg2))) {
local_4 = i;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
goto L_1145;
L_1145: ;
i = ((unsigned int)(i) + 1);
goto L_1115;
L_1153: ;
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} has_pair pass 31 lines
// glaurung: has_pair @ 0x12a0
int has_pair(const int * arg0, int arg1, int arg2) {
int i;
int j;
i = 0;
L_12b5: ;
if ((arg1 <= i)) {
goto L_1327;
}
j = ((unsigned int)(i) + 1);
L_12ca: ;
if ((arg1 <= j)) {
goto L_1314;
}
if (((unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(i)])) + arg0[(long)(j)])) == (unsigned int)(arg2))) {
// x86-64 epilogue: restore rbp
return 1;
}
goto L_1306;
L_1306: ;
j = ((unsigned int)(j) + 1);
goto L_12ca;
L_1314: ;
goto L_1319;
L_1319: ;
i = ((unsigned int)(i) + 1);
goto L_12b5;
L_1327: ;
// x86-64 epilogue: restore rbp
return 0;
} sum_positive pass 17 lines
// glaurung: sum_positive @ 0x13a0
int sum_positive(const int * arg0, int arg1) {
int s;
int i;
long t10;
// x86-64 prologue: save rbp
s = 0;
for (i = 0; (i < arg1); i++) {
t10 = arg0[(long)(i)];
if (((((unsigned long)((unsigned int)(t10)) == 0) | ((long)((int)(t10)) < 0)) == 0)) {
s = ((unsigned int)(arg0[(long)(i)]) + s);
} else {
}
}
// x86-64 epilogue: restore rbp
return (unsigned int)(s);
} sum_until_zero pass 17 lines
// glaurung: sum_until_zero @ 0x1340
int sum_until_zero(const int * arg0, int arg1) {
int s;
int i;
// x86-64 prologue: save rbp
s = 0;
i = 0;
while ((i < arg1)) {
if (((unsigned long)((unsigned int)(arg0[(long)(i)])) == 0)) {
break;
}
s = ((unsigned int)(arg0[(long)(i)]) + s);
i = ((unsigned int)(i) + 1);
}
// x86-64 epilogue: restore rbp
return (unsigned int)(s);
} clang -O2
6/6bisect pass 42 lines
// glaurung: bisect @ 0x1130
int bisect(const int * arg0, int arg1, int arg2) {
int hi;
int lo;
int m;
long ret;
long t164;
long var18;
int var19;
int var6;
long var8;
ret = 0xffffffff;
if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
return ret;
}
hi = (unsigned long)((unsigned int)((arg1 - 1)));
lo = 0;
goto L_115c;
L_1150: ;
var6 = (m - 1);
hi = (unsigned long)((unsigned int)(var6));
if (((((unsigned int)(lo) == (unsigned int)(var6)) | (lo < var6)) == 0)) {
return ret;
}
L_115c: ;
var8 = (unsigned long)((unsigned int)((hi + lo)));
m = (unsigned long)((unsigned int)(((int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var8)) >> 31))) + var8)) >> 1)));
var18 = (unsigned long)((unsigned int)(arg0[(long)(m)]));
t164 = (var18 - (unsigned long)((unsigned int)(arg2)));
if (((unsigned int)(var18) == (unsigned int)(arg2))) {
return (unsigned int)(m);
}
if (((long)(arg2) <= (long)((int)(var18)))) {
goto L_1150;
}
var19 = (m + 1);
lo = (unsigned long)((unsigned int)(var19));
if ((((unsigned int)(var19) == (unsigned int)(hi)) | (var19 < hi))) {
goto L_115c;
}
return ret;
} classify_run pass 32 lines
// glaurung: classify_run @ 0x1190
int classify_run(const int * arg0, int arg1) {
int i;
long ret;
long var0;
long var1;
long var4;
long zf_3;
ret = 1;
if (((long)(arg1) < 2)) {
return ret;
}
var0 = (unsigned long)((unsigned int)(arg1));
var1 = (unsigned long)((unsigned int)(*(int *)(((long)arg0))));
i = 1;
while (1) {
var4 = (unsigned long)((unsigned int)(var1));
var1 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + i * 4))));
zf_3 = ((unsigned int)(var1) == (unsigned int)(var4));
if (((long)((int)(var1)) < (long)((int)(var4)))) {
break;
}
if (zf_3) {
return 0;
}
i = (i + 1);
if ((var0 == i)) {
return ret;
}
}
return 0xffffffff;
} find_first pass 21 lines
// glaurung: find_first @ 0x1100
int find_first(const int * arg0, int arg1, int arg2) {
int i;
long ret;
long var0;
long var2;
ret = 0xffffffff;
if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
return ret;
}
var0 = (unsigned long)((unsigned int)(arg1));
var2 = 0;
while (((unsigned int)(*(int *)(((long)arg0 + var2 * 4))) != (unsigned int)(arg2))) {
i = (var2 + 1);
var2 = (unsigned long)((unsigned int)(i));
if ((var0 == i)) {
return ret;
}
}
return (unsigned int)(var2);
} has_pair pass 54 lines
// glaurung: has_pair @ 0x11d0
int has_pair(const int * arg0, int arg1, int arg2) {
int i;
long var0;
long var10;
long var11;
long var12;
long var14;
long var15;
long var2;
long var3;
long var6;
long var7;
long var8;
if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
var10 = 0;
// x86-64 epilogue: tear down frame
return 0;
}
var0 = (unsigned long)((unsigned int)(arg1));
var3 = ((var2 & -256) | 1);
var6 = (unsigned long)((unsigned int)(arg1));
var7 = (long)arg0;
var8 = 0;
goto L_11fd;
L_11f0: ;
var7 = (var7 + 4);
var6 = (var6 - 1);
var8 = (unsigned long)((unsigned int)(i));
var10 = var3;
if ((i == var0)) {
// x86-64 epilogue: tear down frame
return (unsigned int)(((unsigned int)((unsigned char)((var10 & 255))) & 1));
}
L_11fd: ;
var11 = (unsigned long)((unsigned int)(var3));
var12 = var8;
i = (var8 + 1);
var3 = ((unsigned long)(i) < (unsigned long)(var0));
if (((unsigned long)(var0) <= (unsigned long)(i))) {
goto L_11f0;
}
var14 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + var12 * 4))));
var15 = 1;
do {
if (((unsigned int)(((unsigned long)((unsigned int)(*(int *)((var7 + var15 * 4)))) + var14)) == (unsigned int)(arg2))) {
var10 = (unsigned long)((unsigned int)(var11));
// x86-64 epilogue: tear down frame
return (unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(var11)) & 255))) & 1));
}
var15 = (var15 + 1);
} while ((var6 != var15));
goto L_11f0;
} sum_positive pass 185 lines
// glaurung: sum_positive @ 0x1280
int sum_positive(const int * arg0, int arg1) {
int s;
int i;
long ret;
long var1;
long var10;
int var11;
int var12;
int var13;
int var14;
long var16;
int var18;
long var182;
long var183;
int var19;
int var20;
int var21;
int var22;
int var23;
int var24;
int var25;
int var27;
int var28;
int var29;
long var3;
int var30;
int var50;
int var51;
int var52;
int var53;
long var6;
int var67;
int var68;
int var69;
long var7;
int var70;
long var72;
int var74;
int var75;
int var76;
int var77;
int var81;
int var82;
int var83;
int var84;
int var86;
int var87;
int var88;
int var89;
int var91;
int var92;
int var93;
int var94;
int var96;
int var97;
int var98;
int var99;
if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
return 0;
}
var1 = (unsigned long)((unsigned int)(arg1));
var3 = 0;
if (((unsigned long)(8) <= (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
var6 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var1)) & -8)));
var7 = (var6 - 8);
var10 = (((unsigned long)(var7) >> 3) + 1);
if ((var7 == 0)) {
ret = 0;
var11 = 0;
var12 = 0;
var13 = 0;
var14 = 0;
var16 = 0;
var18 = 0;
var19 = 0;
var20 = 0;
var21 = 0;
if (((unsigned long)((unsigned char)((var10 & 1))) != 0)) {
L_1337: ;
var22 = *(int *)(((long)arg0 + var16 * 4));
var23 = *(int *)(((long)arg0 + var16 * 4 + 0x4));
var24 = *(int *)(((long)arg0 + var16 * 4 + 0x8));
var25 = *(int *)(((long)arg0 + var16 * 4 + 0xc));
var27 = *(int *)(((long)arg0 + var16 * 4 + 0x10));
var28 = *(int *)(((long)arg0 + var16 * 4 + 0x14));
var29 = *(int *)(((long)arg0 + var16 * 4 + 0x18));
var30 = *(int *)(((long)arg0 + var16 * 4 + 0x1c));
var50 = (var11 + ((-(0 < var22)) & var22));
var51 = (var12 + ((-(0 < var23)) & var23));
var52 = (var13 + ((-(0 < var24)) & var24));
var53 = (var14 + ((-(0 < var25)) & var25));
var67 = (var18 + ((-(0 < var27)) & var27));
var68 = (var19 + ((-(0 < var28)) & var28));
var69 = (var20 + ((-(0 < var29)) & var29));
var70 = (var21 + ((-(0 < var30)) & var30));
} else {
var50 = var11;
var51 = var12;
var52 = var13;
var53 = var14;
var67 = var18;
var68 = var19;
var69 = var20;
var70 = var21;
}
} else {
var72 = (var10 & -2);
var74 = 0;
var75 = 0;
var76 = 0;
var77 = 0;
var16 = 0;
var11 = 0;
var12 = 0;
var13 = 0;
var14 = 0;
var18 = 0;
var19 = 0;
var20 = 0;
var21 = 0;
do {
var81 = *(int *)(((long)arg0 + var16 * 4));
var82 = *(int *)(((long)arg0 + var16 * 4 + 0x4));
var83 = *(int *)(((long)arg0 + var16 * 4 + 0x8));
var84 = *(int *)(((long)arg0 + var16 * 4 + 0xc));
var86 = *(int *)(((long)arg0 + var16 * 4 + 0x10));
var87 = *(int *)(((long)arg0 + var16 * 4 + 0x14));
var88 = *(int *)(((long)arg0 + var16 * 4 + 0x18));
var89 = *(int *)(((long)arg0 + var16 * 4 + 0x1c));
var91 = *(int *)(((long)arg0 + var16 * 4 + 0x20));
var92 = *(int *)(((long)arg0 + var16 * 4 + 0x24));
var93 = *(int *)(((long)arg0 + var16 * 4 + 0x28));
var94 = *(int *)(((long)arg0 + var16 * 4 + 0x2c));
var96 = *(int *)(((long)arg0 + var16 * 4 + 0x30));
var97 = *(int *)(((long)arg0 + var16 * 4 + 0x34));
var98 = *(int *)(((long)arg0 + var16 * 4 + 0x38));
var99 = *(int *)(((long)arg0 + var16 * 4 + 0x3c));
var11 = (((-(var74 < var91)) & var91) + (((-(var74 < var81)) & var81) + var11));
var12 = (((-(var75 < var92)) & var92) + (((-(var75 < var82)) & var82) + var12));
var13 = (((-(var76 < var93)) & var93) + (((-(var76 < var83)) & var83) + var13));
var14 = (((-(var77 < var94)) & var94) + (((-(var77 < var84)) & var84) + var14));
ret = ((unsigned long)((unsigned int)(var12)) | (unsigned long)((unsigned int)(var11)));
var18 = (((-(var74 < var96)) & var96) + (((-(var74 < var86)) & var86) + var18));
var19 = (((-(var75 < var97)) & var97) + (((-(var75 < var87)) & var87) + var19));
var20 = (((-(var76 < var98)) & var98) + (((-(var76 < var88)) & var88) + var20));
var21 = (((-(var77 < var99)) & var99) + (((-(var77 < var89)) & var89) + var21));
var16 = (var16 + 16);
var72 = (var72 - 2);
} while ((var72 != 0));
var50 = var11;
var51 = var12;
var52 = var13;
var53 = var14;
var67 = var18;
var68 = var19;
var69 = var20;
var70 = var21;
if (((unsigned long)((unsigned char)((var10 & 1))) == 0)) {
goto L_1366;
}
goto L_1337;
}
L_1366: ;
var182 = (unsigned long)((unsigned int)((((var53 + var70) + (var51 + var68)) + ((var52 + var69) + (var50 + var67)))));
ret = var182;
if ((var6 == var1)) {
return ret;
}
L_1390: ;
do {
var183 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + var6 * 4))));
s = (var182 + (((long)((int)(var183)) < 0) ? var3 : var183));
i = (var6 + 1);
var182 = (unsigned long)((unsigned int)(s));
var6 = (unsigned long)((unsigned int)(i));
ret = (unsigned long)((unsigned int)(s));
} while ((var1 != i));
} else {
var182 = 0;
var6 = 0;
goto L_1390;
}
return ret;
} sum_until_zero pass 31 lines
// glaurung: sum_until_zero @ 0x1250
int sum_until_zero(const int * arg0, int arg1) {
int i;
int s;
long ret;
long var1;
long var6;
long var8;
int var9;
if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
return 0;
}
var1 = (unsigned long)((unsigned int)(arg1));
var6 = 0;
i = 0;
while (1) {
var8 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + i * 4))));
ret = var6;
if (((unsigned long)((unsigned int)(var8)) == 0)) {
break;
}
var9 = (var6 + var8);
var6 = (unsigned long)((unsigned int)(var9));
i = (i + 1);
ret = (unsigned long)((unsigned int)(var9));
if ((var1 == i)) {
break;
}
}
return ret;
} gcc -O0
6/6bisect pass 30 lines
// glaurung: bisect @ 0x1147
int bisect(const int * arg0, int arg1, int arg2) {
int lo;
int hi;
int m;
long var27;
int var5;
lo = 0;
hi = ((unsigned int)(arg1) - 1);
goto L_11ce;
L_116b: ;
var5 = ((unsigned int)(hi) + (unsigned int)(lo));
m = ((int)(((unsigned long)((unsigned int)(var5)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var5)) >> 31))))) >> 1);
if (((unsigned int)(arg2) == (unsigned int)(arg0[(long)(m)]))) {
// x86-64 epilogue: restore rbp
return (unsigned int)(m);
}
var27 = (unsigned long)((unsigned int)(arg0[(long)(m)]));
if (((((unsigned int)(arg2) == (unsigned int)(var27)) | ((long)(arg2) < (long)((int)(var27)))) == 0)) {
lo = ((unsigned int)(m) + 1);
goto L_11ce;
}
hi = ((unsigned int)(m) - 1);
L_11ce: ;
if ((((unsigned int)(lo) == (unsigned int)(hi)) | (lo < hi))) {
goto L_116b;
}
// x86-64 epilogue: restore rbp
return 0xffffffff;
} classify_run pass 22 lines
// glaurung: classify_run @ 0x11dd
int classify_run(const int * arg0, int arg1) {
int i;
i = 1;
goto L_1267;
L_11f5: ;
if (((long)((int)(arg0[(long)(i)])) < (long)((int)(*(int *)(((long)arg0 + (((long)(i) << 2) - 4))))))) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((unsigned int)(arg0[(long)(i)]) == (unsigned int)(*(int *)(((long)arg0 + (((long)(i) << 2) - 4)))))) {
// x86-64 epilogue: restore rbp
return 0;
}
i = (i + 1);
L_1267: ;
if ((i < arg1)) {
goto L_11f5;
}
// x86-64 epilogue: restore rbp
return 1;
} find_first pass 18 lines
// glaurung: find_first @ 0x10f9
int find_first(const int * arg0, int arg1, int arg2) {
int i;
i = 0;
goto L_1138;
L_1114: ;
if (((unsigned int)(arg2) == (unsigned int)(arg0[(long)(i)]))) {
// x86-64 epilogue: restore rbp
return (unsigned int)(i);
}
i = (i + 1);
L_1138: ;
if ((i < arg1)) {
goto L_1114;
}
// x86-64 epilogue: restore rbp
return 0xffffffff;
} has_pair pass 27 lines
// glaurung: has_pair @ 0x1276
int has_pair(const int * arg0, int arg1, int arg2) {
int i;
int j;
i = 0;
goto L_12e6;
L_1291: ;
j = ((unsigned int)(i) + 1);
goto L_12da;
L_129c: ;
if (((unsigned int)(arg2) == (unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(j)])) + (unsigned long)((unsigned int)(arg0[(long)(i)])))))) {
// x86-64 epilogue: restore rbp
return 1;
}
j = (j + 1);
L_12da: ;
if ((j < arg1)) {
goto L_129c;
}
i = (i + 1);
L_12e6: ;
if ((i < arg1)) {
goto L_1291;
}
// x86-64 epilogue: restore rbp
return 0;
} sum_positive pass 17 lines
// glaurung: sum_positive @ 0x135b
int sum_positive(const int * arg0, int arg1) {
int s;
int i;
long t140;
// x86-64 prologue: save rbp
s = 0;
for (i = 0; (i < arg1); i++) {
t140 = (unsigned long)((unsigned int)(arg0[(long)(i)]));
if ((((unsigned long)((unsigned int)(t140)) == 0) | ((long)((int)(t140)) < 0))) {
} else {
s = (s + (unsigned int)(arg0[(long)(i)]));
}
}
// x86-64 epilogue: restore rbp
return (unsigned int)(s);
} sum_until_zero pass 21 lines
// glaurung: sum_until_zero @ 0x12f5
int sum_until_zero(const int * arg0, int arg1) {
int s;
int i;
s = 0;
i = 0;
goto L_134b;
L_1314: ;
if (((unsigned long)((unsigned int)(arg0[(long)(i)])) == 0)) {
// x86-64 epilogue: restore rbp
return (unsigned int)(s);
}
s = (s + (unsigned int)(arg0[(long)(i)]));
i = (i + 1);
L_134b: ;
if ((i < arg1)) {
goto L_1314;
}
// x86-64 epilogue: restore rbp
return (unsigned int)(s);
} gcc -O2
6/6bisect pass 39 lines
// glaurung: bisect @ 0x1140
int bisect(const int * arg0, int arg1, int arg2) {
int hi;
int m;
int lo;
long t10;
long t152;
int var0;
long var4;
long var6;
var0 = (arg1 - 1);
if (((long)((int)(var0)) < 0)) {
return 0xffffffff;
}
var4 = 0;
hi = (unsigned long)((unsigned int)(var0));
goto L_1157;
L_1150: ;
var6 = (unsigned long)((unsigned int)((m + 1)));
var4 = var6;
if (((long)(hi) < (long)((int)(var6)))) {
return 0xffffffff;
}
L_1157: ;
m = (unsigned long)((unsigned int)(((int)((hi + var4)) >> 1)));
t10 = arg0[(long)(m)];
t152 = (t10 - (unsigned long)((unsigned int)(arg2)));
if (((unsigned int)(t10) == (unsigned int)(arg2))) {
return m;
}
if (((long)((int)(t10)) < (long)(arg2))) {
goto L_1150;
}
hi = (unsigned long)((unsigned int)((m - 1)));
if (((long)((int)(var4)) <= (long)(hi))) {
goto L_1157;
}
return 0xffffffff;
} classify_run pass 30 lines
// glaurung: classify_run @ 0x1180
int classify_run(const int * arg0, int arg1) {
int i;
long t10;
long var1;
long var2;
long var3;
long zf_3;
if ((((unsigned long)((unsigned int)(arg1)) == 1) | ((long)(arg1) < 1))) {
return 1;
}
var1 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 2))) * 4)) + 4));
var2 = (long)arg0;
while (1) {
var3 = (unsigned long)((unsigned int)(*(int *)((var2))));
t10 = *(int *)((var2 + 0x4));
zf_3 = ((unsigned int)(t10) == (unsigned int)(var3));
if (((long)((int)(t10)) < (long)((int)(var3)))) {
break;
}
if (zf_3) {
return 0;
}
var2 = (var2 + 4);
if ((var2 == var1)) {
return 1;
}
}
return 0xffffffff;
} find_first pass 24 lines
// glaurung: find_first @ 0x1100
int find_first(const int * arg0, int arg1, int arg2) {
int i;
long var1;
long var5;
long var6;
if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
return 0xffffffff;
}
var1 = (long)(arg1);
i = 0;
while (1) {
var5 = (unsigned long)((unsigned int)(i));
if (((unsigned int)(*(int *)(((long)arg0 + i * 4))) == (unsigned int)(arg2))) {
break;
}
var6 = ((unsigned long)((unsigned int)(i)) + 1);
i = var6;
if ((var6 == var1)) {
return 0xffffffff;
}
}
return (unsigned int)(var5);
} has_pair pass 40 lines
// glaurung: has_pair @ 0x11d0
int has_pair(const int * arg0, int arg1, int arg2) {
int i;
long ret;
long var0;
long var1;
long var4;
long var6;
var0 = ret;
if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
return 0;
}
var1 = (long)(arg1);
i = 1;
var0 = ret;
if ((1 == (long)(arg1))) {
return 0;
}
L_11e6: ;
var4 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + i * 4 - 0x4))));
var6 = (unsigned long)((unsigned int)(i));
goto L_11f8;
L_11f0: ;
var0 = (var6 + 1);
var6 = var0;
if ((((unsigned int)(arg1) == (unsigned int)(var0)) | ((long)(arg1) < (long)((int)(var0))))) {
goto L_1210;
}
L_11f8: ;
if (((unsigned int)(((unsigned long)((unsigned int)(*(int *)(((long)arg0 + var6 * 4)))) + var4)) != (unsigned int)(arg2))) {
goto L_11f0;
}
return 1;
L_1210: ;
i = (i + 1);
if ((i != var1)) {
goto L_11e6;
}
return 0;
} sum_positive pass 23 lines
// glaurung: sum_positive @ 0x1260
int sum_positive(const int * arg0, int arg1) {
int i;
int s;
long ret;
long var2;
long var5;
long var6;
long var7;
if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
return 0;
}
var2 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 1))) * 4)) + 4));
var5 = 0;
var6 = (long)arg0;
do {
var7 = (unsigned long)((unsigned int)(*(int *)((var6))));
ret = (((((unsigned long)((unsigned int)(var7)) == 0) | ((long)((int)(var7)) < 0)) == 0) ? (unsigned long)((unsigned int)((var5 + var7))) : var5);
var6 = (var6 + 4);
var5 = ret;
} while ((var6 != var2));
return ret;
} sum_until_zero pass 31 lines
// glaurung: sum_until_zero @ 0x1220
int sum_until_zero(const int * arg0, int arg1) {
int s;
int i;
long var2;
long var6;
long var7;
long var8;
long var9;
if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
return 0;
}
var6 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 1))) * 4)) + 4));
var7 = 0;
var8 = (long)arg0;
while (1) {
var9 = (unsigned long)((unsigned int)(*(int *)((var8))));
var2 = var7;
if (((unsigned long)((unsigned int)(var9)) == 0)) {
break;
}
var8 = (var8 + 4);
s = (var7 + var9);
var7 = (unsigned long)((unsigned int)(s));
var2 = (unsigned long)((unsigned int)(s));
if ((var8 == var6)) {
break;
}
}
return (unsigned int)(var2);
}