Fixture 168
rust enum niche
Rust · 9 functions · 2 lanes · 10 of 18 function-lanes behave identically
2 of 2 lanes have a function that returns a different result after decompilation: rustc-O0 (4/9), rustc-O2 (6/9).
// 168_rust_enum_niche.rs
//
// Rust enum layout, including the niche optimizations that make a Rust enum
// unrecognisable as a tagged union.
//
// Three distinct layouts appear here:
//
// * `Shape` — a data-carrying enum with variants of different sizes. Laid out
// as an explicit discriminant plus a union-like payload area; the payload
// offset is chosen by the compiler and is NOT stable across variants, so
// reading `Pair.0` and `Tagged.id` may or may not be the same load.
//
// * `Option<&i32>` — the NULL POINTER OPTIMIZATION. `size_of::<Option<&i32>>()
// == size_of::<&i32>() == 8`. There is no discriminant at all: `None` IS the
// null pointer. A `match` on it decompiles to a null test, which looks
// exactly like a C null check and gives no hint that an enum existed.
//
// * `Option<NonZeroU32>` — the same trick at 4 bytes, folded into a payload
// that is documented never to be zero. `None` IS `0u32`.
//
// * `Option<Option<NonZeroU32>>` — the niche is EXHAUSTED. `Option<NonZeroU32>`
// already spends the only forbidden value (0) on its own `None`, so every
// u32 bit pattern is now valid and the outer `Option` has to grow a real tag:
// 8 bytes, not 4. Verified at runtime by `rust_niche_sizes`. The lesson for a
// decompiler is that niche folding is NOT compositional — the same source
// shape one level deeper has a completely different layout.
//
// Exposure: every driver is `#[no_mangle] pub extern "C" fn` over plain i32/u32
// scalars and caller-owned `*const i32` / `*mut i32` buffers. Discriminant
// selectors are taken modulo the variant count, indices are masked to <= 15,
// pointers are null-checked (and the null case is a legitimate `None`), and all
// arithmetic is `wrapping_*`. No input the harness can pass can panic.
//
// Deterministic: `rust_niche_sizes` returns compile-time constants; nothing else
// observes an address.
use core::num::NonZeroU32;
/// A data-carrying enum: differing payload sizes force a real discriminant.
enum Shape {
Unit,
Pair(i32, i32),
Tagged { id: i32, v: i32 },
Wide(i64),
Byte(i8),
}
/// Total over all inputs: `kind` is reduced modulo the variant count.
#[inline(never)]
fn make(kind: u32, a: i32, b: i32) -> Shape {
match kind % 5 {
0 => Shape::Unit,
1 => Shape::Pair(a, b),
2 => Shape::Tagged { id: a, v: b },
3 => Shape::Wide((a as i64).wrapping_mul(0x1_0000_0001).wrapping_add(b as i64)),
_ => Shape::Byte(a as i8),
}
}
/// The discriminant read plus five payload decodings. Each arm produces a value
/// in its own decade, so a mis-recovered discriminant lands in the wrong decade
/// and the differential catches it.
#[inline(never)]
fn eval(s: &Shape) -> i32 {
match s {
Shape::Unit => 1,
Shape::Pair(x, y) => 100i32.wrapping_add(x.wrapping_mul(3)).wrapping_add(*y),
Shape::Tagged { id, v } => 200i32.wrapping_add(id.wrapping_sub(*v)),
Shape::Wide(w) => 300i32.wrapping_add((*w as i32) ^ ((*w >> 32) as i32)),
Shape::Byte(b) => 400i32.wrapping_add(*b as i32),
}
}
#[no_mangle]
pub extern "C" fn rust_enum_eval(kind: u32, a: i32, b: i32) -> i32 {
eval(&make(kind, a, b))
}
/// The enum crosses a function boundary BY VALUE, so its ABI layout (how many
/// registers, which halves carry the discriminant) is exercised rather than just
/// its in-memory form.
#[inline(never)]
fn combine(x: Shape, y: Shape) -> i32 {
eval(&x).wrapping_mul(31).wrapping_add(eval(&y))
}
#[no_mangle]
pub extern "C" fn rust_enum_by_value(k1: u32, k2: u32, a: i32, b: i32) -> i32 {
combine(make(k1, a, b), make(k2, b, a))
}
/// Only the discriminant, with no payload use: the compiler is free to emit a
/// bare tag load and a jump table.
#[no_mangle]
pub extern "C" fn rust_enum_discriminant(kind: u32, a: i32, b: i32) -> i32 {
match make(kind, a, b) {
Shape::Unit => 0,
Shape::Pair(..) => 1,
Shape::Tagged { .. } => 2,
Shape::Wide(_) => 3,
Shape::Byte(_) => 4,
}
}
// --- niche optimization: Option<&T> is a nullable pointer ------------------
/// `Option<&i32>` built from a raw pointer. `as_ref()` performs the null test;
/// the resulting `Option` has NO tag — the pointer value IS the tag.
///
/// `p` may legitimately be null (the harness never passes null, but the code is
/// total either way); `idx` is masked to the 16-element buffer.
#[no_mangle]
pub extern "C" fn rust_option_ref(p: *const i32, idx: u32) -> i32 {
let off = (idx & 15) as usize;
// SAFETY: when non-null the caller owns at least 16 i32s at `p`, and
// `off <= 15`. `as_ref` itself performs the null check.
let opt: Option<&i32> = unsafe { p.add(off).as_ref() };
match opt {
Some(v) => v.wrapping_add(1000),
None => -1,
}
}
/// The same niche used as a RETURN value: the function returns one pointer-sized
/// register that is either a valid address or zero.
#[inline(never)]
fn first_positive(buf: &[i32]) -> Option<&i32> {
for v in buf {
if *v > 0 {
return Some(v);
}
}
None
}
#[no_mangle]
pub extern "C" fn rust_option_ref_find(p: *const i32, n: u32) -> i32 {
if p.is_null() {
return -2;
}
let len = if n > 16 { 16 } else { n } as usize;
// SAFETY: caller owns >= 16 i32s at `p`; `len <= 16`.
let buf: &[i32] = unsafe { core::slice::from_raw_parts(p, len) };
match first_positive(buf) {
Some(v) => *v,
None => -1,
}
}
// --- niche optimization: Option<NonZeroU32> is a u32 with 0 == None ---------
/// `NonZeroU32::new` is the niche construction: it is a compare against zero,
/// and the `Option` it returns is bit-identical to its argument.
#[no_mangle]
pub extern "C" fn rust_option_nonzero(v: u32) -> u32 {
match NonZeroU32::new(v) {
Some(nz) => nz.get().wrapping_mul(3) ^ 0x5a,
None => 0xFFFF_FFFF,
}
}
/// Nested `Option`s where the niche has run out: the outer layer carries an
/// explicit discriminant word beside the u32 payload (8 bytes total), so three
/// distinct results — outer `None`, inner `None`, and a payload — come from two
/// different mechanisms in one match.
#[no_mangle]
pub extern "C" fn rust_option_nested(v: u32, sel: u32) -> u32 {
let inner: Option<NonZeroU32> = NonZeroU32::new(v);
let outer: Option<Option<NonZeroU32>> = if sel & 1 == 0 { None } else { Some(inner) };
match outer {
None => 7,
Some(None) => 8,
Some(Some(nz)) => nz.get().wrapping_add(9),
}
}
/// The niche flowing through a caller-owned buffer: each element is interpreted
/// as an `Option<NonZeroU32>` and rewritten, so both the `None` encoding and the
/// payload encoding are visible as memory.
#[no_mangle]
pub extern "C" fn rust_option_niche_fill(out: *mut i32, n: u32) -> i32 {
if out.is_null() {
return -1;
}
let len = if n > 16 { 16 } else { n } as usize;
// SAFETY: caller owns >= 16 i32s at `out`; `len <= 16`.
let dst: &mut [i32] = unsafe { core::slice::from_raw_parts_mut(out, len) };
let mut count: i32 = 0;
for slot in dst.iter_mut() {
let o = NonZeroU32::new(*slot as u32);
*slot = match o {
Some(nz) => {
count = count.wrapping_add(1);
nz.get().wrapping_add(1) as i32
}
None => -5,
};
}
count
}
/// The layout facts themselves, as compile-time constants: (Option<&i32>,
/// Option<NonZeroU32>, Option<u32>, Option<Option<NonZeroU32>>) sizes packed
/// into one i32. Observed value on x86-64: 8_04_08_08, i.e. 8 / 4 / 8 / 8 —
/// `Option<u32>` and `Option<Option<NonZeroU32>>` have no niche left and pay for
/// a tag, which is the contrast that proves the other two are niche-optimized.
#[no_mangle]
pub extern "C" fn rust_niche_sizes() -> i32 {
let a = core::mem::size_of::<Option<&i32>>() as i32; // 8 (NPO)
let b = core::mem::size_of::<Option<NonZeroU32>>() as i32; // 4 (niche)
let c = core::mem::size_of::<Option<u32>>() as i32; // 8 (no niche)
let d = core::mem::size_of::<Option<Option<NonZeroU32>>>() as i32; // 8 (niche exhausted)
a.wrapping_mul(1_000_000)
.wrapping_add(b.wrapping_mul(10_000))
.wrapping_add(c.wrapping_mul(100))
.wrapping_add(d)
} 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.
rustc -O0
4/9rust_enum_by_value fail 14 lines
// glaurung: rust_enum_by_value @ 0x18a0
__attribute__((no_stack_protector)) unsigned int rust_enum_by_value(int arg0, unsigned int arg1, unsigned int arg2, unsigned int arg3) {
extern long _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(long *, int, unsigned int);
extern unsigned int _ZN20_168_rust_enum_niche7combine17h31620037001fc60eE(char *, long);
unsigned char local_30[32];
unsigned int ret;
long var2;
long var5;
arg1 = arg1;
var2 = ((long (*)(long *))_ZN20_168_rust_enum_niche4make17h9a025a139a4752daE)((long *)(&local_30[0]));
var5 = _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE((long *)((&local_30[0] + 16)), arg1, arg3);
ret = _ZN20_168_rust_enum_niche7combine17h31620037001fc60eE((char *)(&local_30[0]), (long)((&local_30[0] + 16)));
return ret;
} rust_enum_discriminant fail 10 lines
// glaurung: rust_enum_discriminant @ 0x1900
__attribute__((no_stack_protector)) unsigned int rust_enum_discriminant(int arg0, unsigned int arg1, unsigned int arg2) {
extern long _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(long *, int, unsigned int);
unsigned char local_20[20];
long local_30;
long var3;
var3 = ((long (*)(long *))_ZN20_168_rust_enum_niche4make17h9a025a139a4752daE)((long *)(&local_20[0]));
local_30 = (unsigned int)((unsigned char)(*(char *)(&local_20[0])));
/* unrecovered indirect jump through ((long)((int)(*(int *)((0x2024 + (local_30 * 4))))) + 0x2024) */
} rust_enum_eval fail 11 lines
// glaurung: rust_enum_eval @ 0x1830
__attribute__((no_stack_protector)) long rust_enum_eval(int arg0, unsigned int arg1, unsigned int arg2) {
extern long _ZN20_168_rust_enum_niche4eval17habc7f91386cad0cfE(char *);
extern long _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(long *, int, unsigned int);
unsigned char local_20[20];
long ret;
long var3;
var3 = ((long (*)(long *))_ZN20_168_rust_enum_niche4make17h9a025a139a4752daE)((long *)(&local_20[0]));
ret = _ZN20_168_rust_enum_niche4eval17habc7f91386cad0cfE((char *)(&local_20[0]));
return ret;
} rust_niche_sizes pass 36 lines
// glaurung: rust_niche_sizes @ 0x1db0
unsigned int rust_niche_sizes(void) {
int local_10;
int local_14;
int local_18;
int local_1c;
int local_20;
int local_24;
int local_28;
int local_2c;
int local_30;
int local_34;
int local_38;
int local_3c;
int local_4;
int local_40;
int local_8;
int local_c;
local_40 = 8;
local_3c = 4;
local_38 = 8;
local_34 = 8;
local_8 = 8;
local_4 = 0xf4240;
local_10 = 4;
local_c = 0x2710;
local_20 = 0x7a1200;
local_1c = 0x9c40;
local_18 = 8;
local_14 = 100;
local_28 = 0x7aae40;
local_24 = 800;
local_30 = 0x7ab160;
local_2c = 8;
return 0x7ab168;
} rust_option_nested pass 36 lines
// glaurung: rust_option_nested @ 0x1ba0
unsigned int rust_option_nested(int arg0, unsigned int arg1) {
extern long _ZN4core3num7nonzero10NonZeroU323get17hbd59da5b5a8e9c9dE(int);
extern unsigned int _ZN4core3num7nonzero10NonZeroU323new17h3c4ed299db95b8a4E(int);
int local_10;
int local_1c;
int local_20;
int local_28;
int local_4;
int local_8;
int local_c;
unsigned int var0;
long var12;
var0 = _ZN4core3num7nonzero10NonZeroU323new17h3c4ed299db95b8a4E(arg0);
local_28 = var0;
local_10 = var0;
if (((unsigned long)((unsigned int)((arg1 & 1))) != 0)) {
local_1c = local_28;
local_20 = 1;
} else {
local_20 = 0;
}
if (((unsigned long)((unsigned int)(local_20)) != 0)) {
if (((((unsigned long)((unsigned int)(local_1c)) == 0) ? 0 : 1) == 0)) {
return 8;
} else {
local_c = local_1c;
var12 = ((long (*)(void))_ZN4core3num7nonzero10NonZeroU323get17hbd59da5b5a8e9c9dE)();
local_8 = var12;
local_4 = 9;
return (unsigned int)((var12 + 9));
}
} else {
return 7;
}
} rust_option_niche_fill fail 80 lines
// glaurung: rust_option_niche_fill @ 0x1c50
__attribute__((no_stack_protector)) unsigned int rust_option_niche_fill(char * arg0, unsigned int arg1) {
extern long _ZN4core3num7nonzero10NonZeroU323get17hbd59da5b5a8e9c9dE(int);
extern unsigned int _ZN4core3num7nonzero10NonZeroU323new17h3c4ed299db95b8a4E(int);
extern int _ZN4core3ptr7mut_ptr31__LT_impl_u20__BP_mut_u20_T_GT_7is_null17h6aa1216baf4d5916E(char *);
extern long _ZN4core5slice29__LT_impl_u20__u5b_T_u5d__GT_8iter_mut17hd159003656df9d18E(long);
extern long _ZN4core5slice3raw18from_raw_parts_mut17h12e5279671aabd10E(char *, long);
extern long _ZN63__LT_I_u20_as_u20_core__iter__traits__collect__IntoIterator_GT_9into_iter17ha82f13d10d68680dE(long);
extern long _ZN94__LT_core__slice__iter__IterMut_LT_T_GT__u20_as_u20_core__iter__traits__iterator__Iterator_GT_4next17h830345d9a7e0ca4eE(char *);
int local_10;
int local_14;
long local_20;
long local_28;
long local_30;
long local_38;
int local_4;
int local_4c;
int local_50;
long local_58;
long local_60;
unsigned char local_68[8];
int local_8;
unsigned char local_88[32];
int local_c;
int var0;
long var10;
long var11;
long var14;
long var19;
unsigned int var27;
long var34;
long var37;
long var6;
var0 = _ZN4core3ptr7mut_ptr31__LT_impl_u20__BP_mut_u20_T_GT_7is_null17h6aa1216baf4d5916E(arg0);
if (((unsigned long)((unsigned char)((var0 & 1))) != 0)) {
*(int *)((&local_88[0] + 20)) = -1;
} else {
if (((unsigned long)(16) < (unsigned long)(arg1))) {
*(int *)((&local_88[0] + 24)) = 16;
} else {
*(int *)((&local_88[0] + 24)) = arg1;
}
local_38 = (unsigned int)(*(int *)((&local_88[0] + 24)));
var6 = ((long (*)(char *))_ZN4core5slice3raw18from_raw_parts_mut17h12e5279671aabd10E)(arg0);
local_30 = var6;
local_28 = var10;
*(int *)((&local_88[0] + 28)) = 0;
var11 = ((long (*)(void))_ZN4core5slice29__LT_impl_u20__u5b_T_u5d__GT_8iter_mut17hd159003656df9d18E)();
var14 = _ZN63__LT_I_u20_as_u20_core__iter__traits__collect__IntoIterator_GT_9into_iter17ha82f13d10d68680dE(var11);
*(long *)(&local_68[0]) = var14;
local_60 = var10;
while (1) {
var19 = _ZN94__LT_core__slice__iter__IterMut_LT_T_GT__u20_as_u20_core__iter__traits__iterator__Iterator_GT_4next17h830345d9a7e0ca4eE((char *)(&local_68[0]));
local_58 = var19;
if ((((local_58 == 0) ? 0 : 1) == 0)) {
break;
}
*(long *)(&local_88[0]) = local_58;
local_20 = local_58;
var27 = _ZN4core3num7nonzero10NonZeroU323new17h3c4ed299db95b8a4E((unsigned long)((unsigned int)(*(int *)(local_58))));
local_50 = var27;
if (((((unsigned long)((unsigned int)(local_50)) == 0) ? 0 : 1) == 0)) {
local_4c = -5;
} else {
local_14 = local_50;
var34 = (unsigned long)((unsigned int)(*(int *)((&local_88[0] + 28))));
local_10 = var34;
local_c = 1;
*(int *)((&local_88[0] + 28)) = (var34 + 1);
var37 = ((long (*)(void))_ZN4core3num7nonzero10NonZeroU323get17hbd59da5b5a8e9c9dE)();
local_8 = var37;
local_4 = 1;
local_4c = (var37 + 1);
}
*(int *)(*(long *)(&local_88[0])) = local_4c;
}
*(int *)((&local_88[0] + 20)) = *(int *)((&local_88[0] + 28));
}
return (unsigned int)(*(int *)((&local_88[0] + 20)));
} rust_option_nonzero pass 21 lines
// glaurung: rust_option_nonzero @ 0x1b40
__attribute__((no_stack_protector)) unsigned int rust_option_nonzero(int arg0) {
extern long _ZN4core3num7nonzero10NonZeroU323get17hbd59da5b5a8e9c9dE(int);
extern unsigned int _ZN4core3num7nonzero10NonZeroU323new17h3c4ed299db95b8a4E(int);
unsigned char local_18[24];
unsigned int var0;
long var7;
*(int *)((&local_18[0] + 8)) = arg0;
var0 = _ZN4core3num7nonzero10NonZeroU323new17h3c4ed299db95b8a4E(arg0);
*(int *)((&local_18[0] + 4)) = var0;
if (((((unsigned long)((unsigned int)(*(int *)((&local_18[0] + 4)))) == 0) ? 0 : 1) != 0)) {
*(int *)((&local_18[0] + 12)) = *(int *)((&local_18[0] + 4));
var7 = ((long (*)(void))_ZN4core3num7nonzero10NonZeroU323get17hbd59da5b5a8e9c9dE)();
*(int *)((&local_18[0] + 16)) = var7;
*(int *)((&local_18[0] + 20)) = 3;
*(int *)(&local_18[0]) = ((var7 * 3) ^ 90);
} else {
*(int *)(&local_18[0]) = -1;
}
return (unsigned int)(*(int *)(&local_18[0]));
} rust_option_ref pass 27 lines
// glaurung: rust_option_ref @ 0x1980
unsigned int rust_option_ref(char * arg0, unsigned int arg1) {
extern long _ZN4core3ptr9const_ptr33__LT_impl_u20__BP_const_u20_T_GT_6as_ref17h7fa8fe4eb09ecef0E(char *);
int local_14;
int local_18;
long local_20;
long local_28;
long local_40;
long local_8;
long var12;
long var2;
long var4;
var2 = (unsigned long)((unsigned int)((arg1 & 15)));
local_28 = var2;
local_8 = var2;
var4 = _ZN4core3ptr9const_ptr33__LT_impl_u20__BP_const_u20_T_GT_6as_ref17h7fa8fe4eb09ecef0E((char *)(((long)arg0 + (var2 << 2))));
local_40 = var4;
if ((((local_40 == 0) ? 0 : 1) != 0)) {
local_20 = local_40;
var12 = (unsigned long)((unsigned int)(*(int *)(local_40)));
local_18 = var12;
local_14 = 1000;
return (unsigned int)((var12 + 1000));
} else {
return (unsigned int)(-1);
}
} rust_option_ref_find fail 34 lines
// glaurung: rust_option_ref_find @ 0x1a80
unsigned int rust_option_ref_find(char * arg0, unsigned int arg1) {
extern long _ZN20_168_rust_enum_niche14first_positive17h11d53ca900de4405E(long);
extern int _ZN4core3ptr9const_ptr33__LT_impl_u20__BP_const_u20_T_GT_7is_null17ha91e1c541d7185f3E(char *);
extern long _ZN4core5slice3raw14from_raw_parts17hcb69f8e0bbc46596E(char *, long);
long local_10;
long local_18;
long local_20;
long local_38;
int local_3c;
long local_8;
int var0;
long var10;
long var11;
long var6;
var0 = _ZN4core3ptr9const_ptr33__LT_impl_u20__BP_const_u20_T_GT_7is_null17ha91e1c541d7185f3E(arg0);
if (((unsigned long)((unsigned char)((var0 & 1))) != 0)) {
return (unsigned int)(-2);
} else {
local_3c = (((unsigned long)(16) < (unsigned long)(arg1)) ? 16 : (unsigned long)(arg1));
local_20 = (unsigned int)(local_3c);
var6 = ((long (*)(char *))_ZN4core5slice3raw14from_raw_parts17hcb69f8e0bbc46596E)(arg0);
local_18 = var6;
local_10 = var10;
var11 = ((long (*)(void))_ZN20_168_rust_enum_niche14first_positive17h11d53ca900de4405E)();
local_38 = var11;
if ((((local_38 == 0) ? 0 : 1) != 0)) {
local_8 = local_38;
return (unsigned int)(*(int *)(local_38));
} else {
return (unsigned int)(-1);
}
}
} rustc -O2
6/9rust_enum_by_value fail 18 lines
// glaurung: rust_enum_by_value @ 0x1230
__attribute__((no_stack_protector)) unsigned int rust_enum_by_value(int arg0, unsigned int arg1, long arg2, unsigned int arg3) {
extern long _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(void *, unsigned int, long);
extern unsigned int _ZN20_168_rust_enum_niche7combine17h31620037001fc60eE(char *, char *);
unsigned char local_48[32];
unsigned int ret;
long var0;
long var2;
long var4;
long var8;
var0 = (unsigned long)(arg3);
var2 = (unsigned long)(arg1);
var4 = ((long (*)(void *, unsigned int))_ZN20_168_rust_enum_niche4make17h9a025a139a4752daE)(&local_48[0], (unsigned long)((unsigned int)(arg0)));
var8 = _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE((void *)((&local_48[0] + 16)), (unsigned long)((unsigned int)(var2)), (unsigned long)((unsigned int)(var0)));
ret = _ZN20_168_rust_enum_niche7combine17h31620037001fc60eE((char *)(&local_48[0]), (char *)((&local_48[0] + 16)));
// x86-64 epilogue: tear down frame
return ret;
} rust_enum_discriminant pass 8 lines
// glaurung: rust_enum_discriminant @ 0x1280
__attribute__((no_stack_protector)) unsigned int rust_enum_discriminant(int arg0, unsigned int arg1, unsigned int arg2) {
extern long _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(void *, unsigned int, long);
unsigned char local_10[16];
long var1;
var1 = _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(&local_10[0], (unsigned long)((unsigned int)(arg0)), arg1);
return (unsigned int)((unsigned char)(*(char *)(&local_10[0])));
} rust_enum_eval fail 12 lines
// glaurung: rust_enum_eval @ 0x11d0
__attribute__((no_stack_protector)) long rust_enum_eval(int arg0, unsigned int arg1, unsigned int arg2) {
extern long _ZN20_168_rust_enum_niche4eval17habc7f91386cad0cfE(char *);
extern long _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(void *, unsigned int, long);
unsigned char local_18[16];
long ret;
long var2;
var2 = _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(&local_18[0], (unsigned long)((unsigned int)(arg0)), arg1);
ret = _ZN20_168_rust_enum_niche4eval17habc7f91386cad0cfE((char *)(&local_18[0]));
// x86-64 epilogue: tear down frame
return ret;
} rust_niche_sizes pass 4 lines
// glaurung: rust_niche_sizes @ 0x14a0
int rust_niche_sizes(void) {
return 0x7ab168;
} rust_option_nested pass 4 lines
// glaurung: rust_option_nested @ 0x1340
unsigned int rust_option_nested(long arg0, long arg1) {
return (((unsigned long)((unsigned char)((arg1 & 1))) != 0) ? (((unsigned long)((unsigned int)(arg0)) != 0) ? (unsigned long)((unsigned int)((arg0 + 9))) : 8) : 7);
} rust_option_niche_fill pass 145 lines
// glaurung: rust_option_niche_fill @ 0x1360
int rust_option_niche_fill(char * arg0, long arg1) {
long ret;
long var1;
long var10;
long var12;
long var13;
int var14;
long var140;
long var141;
long var142;
long var145;
int var15;
long var150;
int var152;
int var16;
int var17;
long var19;
int var20;
int var21;
int var22;
int var23;
int var24;
int var25;
int var26;
int var27;
int var29;
int var30;
int var31;
int var32;
int var34;
int var35;
int var36;
int var37;
int var38;
int var39;
long var4;
int var40;
int var41;
int var43;
int var44;
int var45;
int var46;
int var66;
int var67;
int var68;
int var69;
int var71;
int var72;
int var73;
int var74;
long var8;
long var9;
if ((arg0 == 0)) {
return 0xffffffff;
}
var1 = (((unsigned long)((unsigned long)((unsigned int)(arg1))) < (unsigned long)(16)) ? arg1 : 16);
if (((unsigned long)((unsigned int)(var1)) == 0)) {
return 0;
}
var4 = (0x3fffffffffffffff & (var1 - 1));
var8 = 0;
var9 = (long)arg0;
if (((unsigned long)(7) <= (unsigned long)(var4))) {
var10 = (var4 + 1);
var12 = (var10 & -8);
var13 = (long)(((long)arg0 + (var12 * 4)));
ret = 0;
var14 = 0;
var15 = 0;
var16 = 0;
var17 = 0;
var19 = 0;
var20 = -1;
var21 = -1;
var22 = -1;
var23 = -1;
var24 = 0xfffffffb;
var25 = 0xfffffffb;
var26 = 0xfffffffb;
var27 = 0xfffffffb;
var29 = 0;
var30 = 0;
var31 = 0;
var32 = 0;
var34 = 0;
var35 = 0;
var36 = 0;
var37 = 0;
do {
var38 = *(int *)(((long)arg0 + var19 * 4));
var39 = *(int *)(((long)arg0 + var19 * 4 + 0x4));
var40 = *(int *)(((long)arg0 + var19 * 4 + 0x8));
var41 = *(int *)(((long)arg0 + var19 * 4 + 0xc));
var43 = *(int *)(((long)arg0 + var19 * 4 + 0x10));
var44 = *(int *)(((long)arg0 + var19 * 4 + 0x14));
var45 = *(int *)(((long)arg0 + var19 * 4 + 0x18));
var46 = *(int *)(((long)arg0 + var19 * 4 + 0x1c));
var66 = (-(var38 == var14));
var67 = (-(var39 == var15));
var68 = (-(var40 == var16));
var69 = (-(var41 == var17));
var71 = (-(var43 == var14));
var72 = (-(var44 == var15));
var73 = (-(var45 == var16));
var74 = (-(var46 == var17));
var29 = ((var29 + var66) - var20);
var30 = ((var30 + var67) - var21);
var31 = ((var31 + var68) - var22);
var32 = ((var32 + var69) - var23);
var34 = ((var34 + var71) - var20);
var35 = ((var35 + var72) - var21);
var36 = ((var36 + var73) - var22);
var37 = ((var37 + var74) - var23);
*(int *)(((long)arg0 + var19 * 4)) = ((var66 & var24) | ((~var66) & (var38 - var20)));
*(int *)(((long)arg0 + var19 * 4 + 0x4)) = ((var67 & var25) | ((~var67) & (var39 - var21)));
*(int *)(((long)arg0 + var19 * 4 + 0x8)) = ((var68 & var26) | ((~var68) & (var40 - var22)));
*(int *)(((long)arg0 + var19 * 4 + 0xc)) = ((var69 & var27) | ((~var69) & (var41 - var23)));
*(int *)(((long)arg0 + var19 * 4 + 0x10)) = ((var71 & var24) | ((~var71) & (var43 - var20)));
*(int *)(((long)arg0 + var19 * 4 + 0x14)) = ((var72 & var25) | ((~var72) & (var44 - var21)));
*(int *)(((long)arg0 + var19 * 4 + 0x18)) = ((var73 & var26) | ((~var73) & (var45 - var22)));
*(int *)(((long)arg0 + var19 * 4 + 0x1c)) = ((var74 & var27) | ((~var74) & (var46 - var23)));
var19 = (var19 + 8);
} while ((var12 != var19));
var140 = (unsigned long)((unsigned int)((((var37 + var32) + (var35 + var30)) + ((var36 + var31) + (var34 + var29)))));
var8 = var140;
var9 = var13;
ret = var140;
if ((var10 == var12)) {
return ret;
}
}
var141 = (long)(((long)arg0 + (var1 * 4)));
var142 = 0xfffffffb;
do {
var145 = (unsigned long)((unsigned int)(*(int *)((var9))));
*(int *)((var9)) = (((unsigned long)((unsigned int)(var145)) == 0) ? var142 : (unsigned long)((unsigned int)((var145 + 1))));
var150 = (var9 + 4);
var152 = (var8 + ((unsigned long)((unsigned int)(var145)) != 0));
var8 = (unsigned long)((unsigned int)(var152));
var9 = var150;
ret = (unsigned long)((unsigned int)(var152));
} while ((var150 != var141));
return ret;
} rust_option_nonzero pass 4 lines
// glaurung: rust_option_nonzero @ 0x1330
unsigned int rust_option_nonzero(long arg0) {
return (unsigned int)(((unsigned int)((0 - ((unsigned long)((unsigned long)((unsigned int)(arg0))) < (unsigned long)(1)))) | (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + (arg0 * 2)))) ^ 90)))));
} rust_option_ref pass 7 lines
// glaurung: rust_option_ref @ 0x12a0
int rust_option_ref(char * arg0, unsigned int arg1) {
if ((arg0 == 0)) {
return 0xffffffff;
}
return (unsigned int)((1000 + *(int *)(((long)arg0 + ((unsigned long)((unsigned int)((arg1 & 15))) * 4)))));
} rust_option_ref_find fail 16 lines
// glaurung: rust_option_ref_find @ 0x12f0
int rust_option_ref_find(int * arg0, int arg1) {
extern unsigned int _ZN20_168_rust_enum_niche14first_positive17h11d53ca900de4405E(int *);
long local_8;
long ret;
unsigned int var3;
if ((arg0 == 0)) {
return 0xfffffffe;
}
local_8 = ret;
var3 = _ZN20_168_rust_enum_niche14first_positive17h11d53ca900de4405E(arg0);
if ((var3 == 0)) {
return 0xffffffff;
}
return (unsigned int)(*(int *)((var3)));
}