Fixture 210
shared return epilogues
C · 5 functions · 4 lanes · 20 of 20 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
Early returns converging on ONE epilogue, at chain lengths 1, 2 and 3 — the exact dimension along which the shape matcher's return-chain rule is written, and the one no fixture varied.
WHY EACH LENGTH IS A DIFFERENT SHAPE. detect_if_shape matches an early return in three mutually exclusive ways:
* a SINGLE terminal block -> the early-exit shape (runs first); * a SHARED multi-block chain -> the clone shape, which duplicates the chain into the if-then body; * an EXCLUSIVELY OWNED multi-block chain -> no shape at all.
The third case falls through every pattern, the conditional is emitted as a bare block with a goto, and the rest of the walk lands in Unstructured. shared_return_chain opens with if cfg.preds[entry].len() <= 1 { return None }, so the chain is only recognised when it is shared — and sharing was never what made cloning safe. The caller's chain[..len - 1] consumption rule is.
That gap was found, fixed, measured and REVERTED on 2026-08-27: admitting the owned case took a transcription of bin_090 sub_7370 from nine unstructured blocks to one, kept all 91 structure tests green, moved nothing on the corpus, and cost 26 new undefined reads in already-tracked rustc lanes (gen_defuse_baseline.py refused the regeneration). It was the third local fix to that function to be reverted after measurement.
This fixture exists so the next attempt has something to measure against BEFORE it is written. Each function pins one chain length, so a change that trades one length for another shows up as one cell moving each way rather than as a wash.
13_loop_early_exit covers early exits inside a LOOP; this covers them in straight-line code, where the epilogue is the function's own, and varies the length rather than the loop shape.
#include <stdint.h>
/* Early returns converging on ONE epilogue, at chain lengths 1, 2 and 3 — the
* exact dimension along which the shape matcher's return-chain rule is written,
* and the one no fixture varied.
*
* WHY EACH LENGTH IS A DIFFERENT SHAPE. `detect_if_shape` matches an early
* return in three mutually exclusive ways:
*
* * a SINGLE terminal block -> the early-exit shape (runs first);
* * a SHARED multi-block chain -> the clone shape, which duplicates
* the chain into the if-then body;
* * an EXCLUSIVELY OWNED multi-block chain -> no shape at all.
*
* The third case falls through every pattern, the conditional is emitted as a
* bare block with a goto, and the rest of the walk lands in `Unstructured`.
* `shared_return_chain` opens with `if cfg.preds[entry].len() <= 1 { return
* None }`, so the chain is only recognised when it is shared — and sharing was
* never what made cloning safe. The caller's `chain[..len - 1]` consumption
* rule is.
*
* That gap was found, fixed, measured and REVERTED on 2026-08-27: admitting the
* owned case took a transcription of `bin_090 sub_7370` from nine unstructured
* blocks to one, kept all 91 structure tests green, moved nothing on the corpus,
* and cost 26 new undefined reads in already-tracked rustc lanes
* (`gen_defuse_baseline.py` refused the regeneration). It was the third local
* fix to that function to be reverted after measurement.
*
* This fixture exists so the next attempt has something to measure against
* BEFORE it is written. Each function pins one chain length, so a change that
* trades one length for another shows up as one cell moving each way rather
* than as a wash.
*
* `13_loop_early_exit` covers early exits inside a LOOP; this covers them in
* straight-line code, where the epilogue is the function's own, and varies the
* length rather than the loop shape.
*/
static int32_t sink_value;
static int32_t record(int32_t value) {
sink_value = value;
return value;
}
/* Length 1: the terminating arm is a single block. The early-exit shape owns
* this, and it must keep owning it. */
__attribute__((noinline)) int32_t epilogue_chain_one(int32_t a, int32_t b) {
if (a < 0) {
return -1;
}
if (b < 0) {
return -2;
}
return a + b;
}
/* Length 2: two blocks between the guard and the return, exclusively owned by
* that guard. Nothing matches this today. */
__attribute__((noinline)) int32_t epilogue_chain_two(int32_t a, int32_t b) {
int32_t acc = a ^ b;
if (a < 0) {
acc = record(acc);
return acc - 1;
}
if (b < 0) {
acc = record(-acc);
return acc - 2;
}
return acc + 3;
}
/* Length 3, and the tail is SHARED by both guards, so the clone rule applies
* rather than the owned rule. Pinning both in one fixture is what makes a trade
* between them visible. */
__attribute__((noinline)) int32_t epilogue_chain_three_shared(int32_t a,
int32_t b,
int32_t *out) {
int32_t acc = a | b;
if (out == 0) {
return -1;
}
if (a < 0) {
acc = record(acc);
acc &= 0xffff;
*out = acc;
return acc + 10;
}
if (b < 0) {
acc = record(-acc);
acc &= 0xffff;
*out = acc;
return acc + 20;
}
*out = acc;
return acc + 30;
}
/* A chain long enough to hit the matcher's eight-block ceiling from below. If a
* future rule raises or lowers that bound, this is where it shows. */
__attribute__((noinline)) int32_t epilogue_chain_long(int32_t a, int32_t b) {
int32_t acc = a + b;
if (a < 0) {
acc = record(acc);
acc ^= 0x11;
acc += 3;
acc ^= 0x22;
acc += 5;
return acc;
}
return acc + 1;
}
/* CONTROL: the two arms genuinely diverge — neither can reach the other's
* terminal. A rule that treats a reconverging pair as an early return would
* break this while leaving every function above passing. */
__attribute__((noinline)) int32_t divergent_arms(int32_t a, int32_t b) {
if (a > b) {
return record(a) + 100;
}
return record(b) + 200;
} Recovered C
Generated by glaurung decompile --style decbench at b47f6b43.
baseline.json records the result after recompiling the C and calling it beside the
original with seeded inputs.
clang -O0
5/5divergent_arms pass 14 lines
// glaurung: divergent_arms @ 0x1320
int32_t divergent_arms(int32_t arg0, int32_t arg1) {
extern int record(int);
int var1;
int var5;
// x86-64 prologue: save rbp, frame 16 bytes
if ((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1))) {
var1 = record((unsigned long)((unsigned int)(arg1)));
return (unsigned int)((var1 + 200));
} else {
var5 = record((unsigned long)((unsigned int)(arg0)));
return (unsigned int)((var5 + 100));
}
} epilogue_chain_long pass 19 lines
// glaurung: epilogue_chain_long @ 0x12b0
int32_t epilogue_chain_long(int32_t arg0, int32_t arg1) {
extern int record(int);
int acc;
int var6;
// x86-64 prologue: save rbp, frame 16 bytes
acc = ((unsigned int)(arg0) + arg1);
if ((0 <= (long)(arg0))) {
return (unsigned int)(((unsigned long)((unsigned int)(acc)) + 1));
} else {
var6 = record((unsigned long)((unsigned int)(acc)));
acc = var6;
acc = ((unsigned int)(acc) ^ 17);
acc = ((unsigned int)(acc) + 3);
acc = ((unsigned int)(acc) ^ 34);
acc = ((unsigned int)(acc) + 5);
return (unsigned int)(acc);
}
} epilogue_chain_one pass 13 lines
// glaurung: epilogue_chain_one @ 0x1100
int32_t epilogue_chain_one(int32_t arg0, int32_t arg1) {
// x86-64 prologue: save rbp
if ((0 <= (long)(arg0))) {
if ((0 <= (long)(arg1))) {
return (unsigned int)(((unsigned long)((unsigned int)(arg0)) + arg1));
} else {
return (unsigned int)(-2);
}
} else {
return (unsigned int)(-1);
}
} epilogue_chain_three_shared pass 31 lines
// glaurung: epilogue_chain_three_shared @ 0x11f0
int32_t epilogue_chain_three_shared(int32_t arg0, int32_t arg1, int32_t * arg2) {
extern int record(int);
int acc;
int var11;
int var21;
// x86-64 prologue: save rbp, frame 32 bytes
acc = ((unsigned int)(arg0) | arg1);
if ((arg2 != 0)) {
if ((0 <= (long)(arg0))) {
if ((0 <= (long)(arg1))) {
*(int *)((long)arg2) = acc;
return (unsigned int)(((unsigned long)((unsigned int)(acc)) + 30));
} else {
var11 = record((unsigned long)((unsigned int)((0 - acc))));
acc = var11;
acc = ((unsigned int)(acc) & 0xffff);
*(int *)((long)arg2) = acc;
return (unsigned int)(((unsigned long)((unsigned int)(acc)) + 20));
}
} else {
var21 = record((unsigned long)((unsigned int)(acc)));
acc = var21;
acc = ((unsigned int)(acc) & 0xffff);
*(int *)((long)arg2) = acc;
return (unsigned int)(((unsigned long)((unsigned int)(acc)) + 10));
}
} else {
return (unsigned int)(-1);
}
} epilogue_chain_two pass 22 lines
// glaurung: epilogue_chain_two @ 0x1150
int32_t epilogue_chain_two(int32_t arg0, int32_t arg1) {
extern int record(int);
int acc;
int var14;
int var9;
// x86-64 prologue: save rbp, frame 16 bytes
acc = ((unsigned int)(arg0) ^ arg1);
if ((0 <= (long)(arg0))) {
if ((0 <= (long)(arg1))) {
return (unsigned int)(((unsigned long)((unsigned int)(acc)) + 3));
} else {
var9 = record((unsigned long)((unsigned int)((0 - acc))));
acc = var9;
return (unsigned int)(((unsigned long)((unsigned int)(acc)) - 2));
}
} else {
var14 = record((unsigned long)((unsigned int)(acc)));
acc = var14;
return (unsigned int)(((unsigned long)((unsigned int)(acc)) - 1));
}
} clang -O2
5/5divergent_arms pass 4 lines
// glaurung: divergent_arms @ 0x11a0
int32_t divergent_arms(int32_t arg0, int32_t arg1) {
return (((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1)) == 0) ? (unsigned long)((unsigned int)((arg0 + 100))) : (unsigned long)((unsigned int)((arg1 + 200))));
} epilogue_chain_long pass 10 lines
// glaurung: epilogue_chain_long @ 0x1180
int32_t epilogue_chain_long(int32_t arg0, int32_t arg1) {
int acc;
long var2;
var2 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + arg0)));
if (((long)(arg0) < 0)) {
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var2 ^ 17))) + 3))) ^ 34))) + 5));
}
return (unsigned int)((var2 + 1));
} epilogue_chain_one pass 4 lines
// glaurung: epilogue_chain_one @ 0x1100
int32_t epilogue_chain_one(int32_t arg0, int32_t arg1) {
return ((0 <= (long)(arg0)) ? ((0 <= (long)(arg1)) ? (unsigned long)((unsigned int)((arg1 + arg0))) : 0xfffffffe) : 0xffffffff);
} epilogue_chain_three_shared pass 22 lines
// glaurung: epilogue_chain_three_shared @ 0x1140
int32_t epilogue_chain_three_shared(int32_t arg0, int32_t arg1, int32_t * arg2) {
int acc;
int var3;
int var6;
if ((arg2 == 0)) {
return 0xffffffff;
}
acc = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) | arg0)));
if (((long)(arg0) < 0)) {
var3 = (unsigned int)((unsigned short)((acc & 0xffff)));
*(int *)(((long)arg2)) = var3;
return (unsigned int)((var3 + 10));
}
if (((long)(arg1) < 0)) {
var6 = (unsigned int)((unsigned short)(((-acc) & 0xffff)));
*(int *)(((long)arg2)) = var6;
return (unsigned int)((var6 + 20));
}
*(int *)(((long)arg2)) = acc;
return (unsigned int)((acc + 30));
} epilogue_chain_two pass 13 lines
// glaurung: epilogue_chain_two @ 0x1120
int32_t epilogue_chain_two(int32_t arg0, int32_t arg1) {
int acc;
long var2;
var2 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) ^ arg0)));
if (((long)(arg0) < 0)) {
return (unsigned int)((var2 - 1));
}
if (((long)(arg1) < 0)) {
return (unsigned int)((0xfffffffe - var2));
}
return (unsigned int)((var2 + 3));
} gcc -O0
5/5divergent_arms pass 14 lines
// glaurung: divergent_arms @ 0x1282
int32_t divergent_arms(int32_t arg0, int32_t arg1) {
extern int record(int);
int var2;
int var6;
// x86-64 prologue: save rbp, frame 8 bytes
if ((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1))) {
var2 = record((unsigned long)((unsigned int)(arg1)));
return (unsigned int)((var2 + 200));
} else {
var6 = record((unsigned long)((unsigned int)(arg0)));
return (unsigned int)((var6 + 100));
}
} epilogue_chain_long pass 19 lines
// glaurung: epilogue_chain_long @ 0x1235
int32_t epilogue_chain_long(int32_t arg0, int32_t arg1) {
extern int record(int);
int acc;
int var7;
// x86-64 prologue: save rbp, frame 24 bytes
acc = ((unsigned int)(arg1) + (unsigned int)(arg0));
if ((0 <= (long)(arg0))) {
return (unsigned int)(((unsigned long)((unsigned int)(acc)) + 1));
} else {
var7 = record((unsigned long)((unsigned int)(acc)));
acc = var7;
acc = (acc ^ 17);
acc = (acc + 3);
acc = (acc ^ 34);
acc = (acc + 5);
return (unsigned int)(acc);
}
} epilogue_chain_one pass 13 lines
// glaurung: epilogue_chain_one @ 0x1112
int32_t epilogue_chain_one(int32_t arg0, int32_t arg1) {
// x86-64 prologue: save rbp
if ((0 <= (long)(arg0))) {
if ((0 <= (long)(arg1))) {
return (unsigned int)(((unsigned long)((unsigned int)(arg1)) + (unsigned long)((unsigned int)(arg0))));
} else {
return 0xfffffffe;
}
} else {
return 0xffffffff;
}
} epilogue_chain_three_shared pass 31 lines
// glaurung: epilogue_chain_three_shared @ 0x119f
int32_t epilogue_chain_three_shared(int32_t arg0, int32_t arg1, int32_t * arg2) {
extern int record(int);
int acc;
int var16;
int var9;
// x86-64 prologue: save rbp, frame 32 bytes
acc = ((unsigned int)(arg0) | arg1);
if ((arg2 != 0)) {
if ((0 <= (long)(arg0))) {
if ((0 <= (long)(arg1))) {
*(int *)((long)arg2) = acc;
return (unsigned int)(((unsigned long)((unsigned int)(acc)) + 30));
} else {
var9 = record((unsigned long)((unsigned int)((-(unsigned long)((unsigned int)(acc))))));
acc = var9;
acc = (acc & 0xffff);
*(int *)((long)arg2) = acc;
return (unsigned int)(((unsigned long)((unsigned int)(acc)) + 20));
}
} else {
var16 = record((unsigned long)((unsigned int)(acc)));
acc = var16;
acc = (acc & 0xffff);
*(int *)((long)arg2) = acc;
return (unsigned int)(((unsigned long)((unsigned int)(acc)) + 10));
}
} else {
return 0xffffffff;
}
} epilogue_chain_two pass 22 lines
// glaurung: epilogue_chain_two @ 0x1144
int32_t epilogue_chain_two(int32_t arg0, int32_t arg1) {
extern int record(int);
int acc;
int var12;
int var7;
// x86-64 prologue: save rbp, frame 24 bytes
acc = ((unsigned int)(arg0) ^ arg1);
if ((0 <= (long)(arg0))) {
if ((0 <= (long)(arg1))) {
return (unsigned int)(((unsigned long)((unsigned int)(acc)) + 3));
} else {
var7 = record((unsigned long)((unsigned int)((-(unsigned long)((unsigned int)(acc))))));
acc = var7;
return (unsigned int)(((unsigned long)((unsigned int)(acc)) - 2));
}
} else {
var12 = record((unsigned long)((unsigned int)(acc)));
acc = var12;
return (unsigned int)(((unsigned long)((unsigned int)(acc)) - 1));
}
} gcc -O2
5/5divergent_arms pass 4 lines
// glaurung: divergent_arms @ 0x11c0
int32_t divergent_arms(int32_t arg0, int32_t arg1) {
return (((((unsigned int)(arg0) == (unsigned int)(arg1)) | (arg0 < arg1)) == 0) ? (unsigned long)((unsigned int)((arg0 + 100))) : (unsigned long)((unsigned int)((arg1 + 200))));
} epilogue_chain_long pass 12 lines
// glaurung: epilogue_chain_long @ 0x11a0
int32_t epilogue_chain_long(int32_t arg0, int32_t arg1) {
int acc;
int var0;
long var1;
var0 = (arg1 + arg0);
var1 = (unsigned long)((unsigned int)(var0));
if (((long)(arg0) < 0)) {
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var1 ^ 17))) + 3))) ^ 34))) + 5));
}
return (unsigned int)(((unsigned long)((unsigned int)(var0)) + 1));
} epilogue_chain_one pass 10 lines
// glaurung: epilogue_chain_one @ 0x1100
int32_t epilogue_chain_one(int32_t arg0, int32_t arg1) {
if (((long)(arg0) < 0)) {
return 0xffffffff;
}
if (((long)(arg1) < 0)) {
return 0xfffffffe;
}
return (unsigned int)((arg0 + arg1));
} epilogue_chain_three_shared pass 22 lines
// glaurung: epilogue_chain_three_shared @ 0x1150
int32_t epilogue_chain_three_shared(int32_t arg0, int32_t arg1, int32_t * arg2) {
int acc;
int var3;
int var6;
acc = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) | arg1)));
if ((arg2 == 0)) {
return 0xffffffff;
}
if (((long)(arg0) < 0)) {
var3 = (unsigned int)((unsigned short)((acc & 0xffff)));
*(int *)(((long)arg2)) = var3;
return (unsigned int)((var3 + 10));
}
if (((long)(arg1) < 0)) {
var6 = (unsigned int)((unsigned short)(((-acc) & 0xffff)));
*(int *)(((long)arg2)) = var6;
return (unsigned int)((var6 + 20));
}
*(int *)(((long)arg2)) = acc;
return (unsigned int)((acc + 30));
} epilogue_chain_two pass 9 lines
// glaurung: epilogue_chain_two @ 0x1120
int32_t epilogue_chain_two(int32_t arg0, int32_t arg1) {
int acc;
acc = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) ^ arg1)));
if (((long)(arg0) < 0)) {
return (unsigned int)((acc - 1));
}
return (((long)(arg1) < 0) ? (unsigned long)((unsigned int)((0xfffffffe - acc))) : (unsigned long)((unsigned int)((acc + 3))));
}