Fixture 194
narrow return widths
C · 10 functions · 4 lanes · 40 of 40 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
#include <stdint.h>
/* RETURN VALUES NARROWER THAN A REGISTER.
*
* A census of every function definition in this corpus (900 of them, across
* `.c`, `.cpp` and `.rs`) found that the returned type is a full machine word
* almost everywhere:
*
* int32_t / int / uint32_t / i32 704 definitions
* double / float 22
* 64-bit (long, int64_t, uint64_t) 14
* uint8_t 2 (11_call_shapes:wrap_byte,
* 43_base64:encode_symbol)
* uint16_t 1 (07_packet_parser:read_be16,
* not a REQUIRED function)
* int8_t, int16_t, char, _Bool 0
*
* So the corpus asks "what happens when only the low 8 or 16 bits of the result
* register are architecturally meaningful?" exactly twice, never in the SIGNED
* direction, and never for `_Bool`. That is the shape this fixture adds.
*
* Why it is a distinct question from a narrow LOCAL (which `02_integer_widths`
* already covers): a narrow local is a value the compiler may keep in any width
* it likes, while a narrow return is an ABI contract about `al`/`ax` — the
* high bits of `eax` are dead, so `movsbl`/`movzwl` around the return are the
* only thing that distinguishes `int8_t f()` from `int32_t f()` in the machine
* code. A decompiler that models every result as a 32-bit register produces C
* that compiles and that agrees on every input whose value happens to fit.
*
* Each positive case therefore narrows and then does arithmetic that the
* narrowing CHANGES, so the low bits differ rather than only the dead high
* ones: signed division after truncation is not truncation after division.
*
* THREE NEGATIVE CONTROLS, each aimed at a different wrong generalisation:
*
* `nrw194_i32_control` computes the same expression as `nrw194_i8_divide`
* at full width. A recovery that narrows every
* return satisfies the positives and fails here.
* `nrw194_u8_value_control` has the same BODY as `nrw194_u8_mix` — the value
* is narrowed to 8 bits — but returns `int32_t`.
* It separates "models the return width" from
* "models the value width"; conflating the two
* passes every other case in this file.
* `nrw194_bool_wide_control` spells `nrw194_bool_and`'s boolean normalisation
* out explicitly with `!= 0` and returns `int32_t`,
* so the `_Bool` case is measuring the CONVERSION
* and not the arithmetic around it.
*
* Every function is a pure function of its integer arguments: no memory, no
* I/O, no undefined behaviour. Intermediate products are formed in `uint32_t`
* so the boundary sweep's `INT_MIN`/`INT_MAX` vectors cannot overflow a signed
* multiply, and every divisor is a nonzero constant.
*
* ONE DELIBERATE CROSS-ARCHITECTURE ARTIFACT: plain `char` is SIGNED on x86 and
* x86-64 and UNSIGNED on both ARM targets, so `nrw194_char_divide` has a
* genuinely different DWARF return type in an AArch64/ARMv7 build than in the
* host reference. `diff_decompile.abi_incomparable` should decline those two
* lanes with `incomparable` rather than compare a truncation against a
* zero-extension and call the difference a lifter bug. That refusal is part of
* what this fixture is for; the i386 lane shares x86's signed `char` and must
* stay comparable. */
/* --- signed narrow returns ------------------------------------------------ */
/* int8_t: truncate to 8 bits, THEN divide. `x = 300` narrows to 44 and returns
* 22; dividing first and truncating afterwards returns 106. The two disagree in
* the low byte, which is the only byte the ABI defines. */
__attribute__((noinline)) int8_t nrw194_i8_divide(int32_t x) {
int8_t narrowed = (int8_t)((uint32_t)x * 3u);
return (int8_t)(narrowed / 2);
}
/* int16_t: the same question one width up, where a 16-bit truncation is a
* different instruction (`movswl` rather than `movsbl`). */
__attribute__((noinline)) int16_t nrw194_i16_divide(int32_t x) {
int16_t narrowed = (int16_t)((uint32_t)x * 5u);
return (int16_t)(narrowed / 7);
}
/* --- unsigned narrow returns ---------------------------------------------- */
/* uint8_t: division and a logical shift of a ZERO-extended byte. Reading the
* same bits as signed makes `narrowed >> 5` an arithmetic shift and changes the
* answer for every input with bit 7 set. */
__attribute__((noinline)) uint8_t nrw194_u8_mix(int32_t x) {
uint8_t narrowed = (uint8_t)x;
return (uint8_t)(narrowed / 3u + (uint32_t)(narrowed >> 5));
}
/* uint16_t: the same, one width up. */
__attribute__((noinline)) uint16_t nrw194_u16_mix(int32_t x) {
uint16_t narrowed = (uint16_t)x;
return (uint16_t)(narrowed / 9u + (uint32_t)(narrowed >> 11));
}
/* --- plain `char`, whose signedness is a property of the TARGET ------------ */
/* Signed on x86/x86-64, unsigned on AArch64 and ARMv7. The host lanes divide a
* sign-extended byte; a naive cross-architecture comparison would divide a
* zero-extended one and blame the lifter. See the header note. */
__attribute__((noinline)) char nrw194_char_divide(int32_t x) {
char narrowed = (char)x;
return (char)(narrowed / 2);
}
/* --- _Bool, where the ABI value is NORMALISED and not merely truncated ----- */
/* `(x & 0x100)` is 0 or 256; converting it to `_Bool` is `test`/`setne`, so the
* returned byte is 0 or 1. A recovery that keeps the raw mask returns 0 for
* EVERY input, because 256's low byte is zero — the one case where the dead
* high bits are what carried the answer. */
__attribute__((noinline)) _Bool nrw194_bool_bit(int32_t x) {
return (_Bool)(x & 0x100);
}
/* Two `_Bool` conversions combined with a bitwise AND. Both operands must be
* normalised to 0/1 first: `4 & 8` is 0, so a recovery that ANDs the raw masks
* answers 0 where the original answers 1. */
__attribute__((noinline)) _Bool nrw194_bool_and(int32_t x, int32_t y) {
_Bool a = (_Bool)(x & 4);
_Bool b = (_Bool)(y & 8);
return (_Bool)(a & b);
}
/* --- CONTROLS ------------------------------------------------------------- */
/* CONTROL: `nrw194_i8_divide`'s expression at FULL width. A decompiler that
* applies a narrowing to every return fails exactly here. */
__attribute__((noinline)) int32_t nrw194_i32_control(int32_t x) {
int32_t wide = (int32_t)((uint32_t)x * 3u);
return wide / 2;
}
/* CONTROL: `nrw194_u8_mix`'s BODY, returned at full width. The value is narrow
* and the result is not, so conflating the two is visible here and nowhere
* else in this file. */
__attribute__((noinline)) int32_t nrw194_u8_value_control(int32_t x) {
uint8_t narrowed = (uint8_t)x;
return (int32_t)(narrowed / 3u + (uint32_t)(narrowed >> 5));
}
/* CONTROL: `nrw194_bool_and` with the normalisation written out by hand and an
* `int32_t` result. If this passes while `nrw194_bool_and` fails, the defect is
* in the `_Bool` return conversion rather than in the surrounding arithmetic. */
__attribute__((noinline)) int32_t nrw194_bool_wide_control(int32_t x, int32_t y) {
int32_t a = (x & 4) != 0;
int32_t b = (y & 8) != 0;
return a & b;
} 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
10/10nrw194_bool_and pass 8 lines
// glaurung: nrw194_bool_and @ 0x11e0
_Bool nrw194_bool_and(int32_t arg0, int32_t arg1) {
int a;
int b;
// x86-64 prologue: save rbp
// x86-64 epilogue: restore rbp
return ((unsigned long)((unsigned int)((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 4))) != 0) & ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 8))) != 0)))) != 0);
} nrw194_bool_bit pass 6 lines
// glaurung: nrw194_bool_bit @ 0x11c0
_Bool nrw194_bool_bit(int32_t arg0) {
// x86-64 prologue: save rbp
// x86-64 epilogue: restore rbp
return ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 256))) != 0);
} nrw194_bool_wide_control pass 8 lines
// glaurung: nrw194_bool_wide_control @ 0x1280
int32_t nrw194_bool_wide_control(int32_t arg0, int32_t arg1) {
int a;
int b;
// x86-64 prologue: save rbp
// x86-64 epilogue: restore rbp
return (unsigned int)((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 4))) != 0) & ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 8))) != 0)));
} nrw194_char_divide pass 8 lines
// glaurung: nrw194_char_divide @ 0x11a0
char nrw194_char_divide(int32_t arg0) {
signed char narrowed;
// x86-64 prologue: save rbp
narrowed = arg0;
// x86-64 epilogue: restore rbp
return (int)((signed char)((((int)((((long long)(int)((((unsigned long)((long)((int)(narrowed))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(narrowed)) / (int)(2))) & 255)));
} nrw194_i16_divide pass 8 lines
// glaurung: nrw194_i16_divide @ 0x1120
int16_t nrw194_i16_divide(int32_t arg0) {
short narrowed;
// x86-64 prologue: save rbp
narrowed = (arg0 * 5);
// x86-64 epilogue: restore rbp
return (int)((short)(((int)((((long long)(int)((((unsigned long)((long)((int)(narrowed))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(narrowed)) / (int)(7)))));
} nrw194_i32_control pass 8 lines
// glaurung: nrw194_i32_control @ 0x1230
int32_t nrw194_i32_control(int32_t arg0) {
int wide;
// x86-64 prologue: save rbp
wide = (arg0 * 3);
// x86-64 epilogue: restore rbp
return ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(wide))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(wide)))) / (int)(2)));
} nrw194_i8_divide pass 8 lines
// glaurung: nrw194_i8_divide @ 0x1100
int8_t nrw194_i8_divide(int32_t arg0) {
signed char narrowed;
// x86-64 prologue: save rbp
narrowed = (arg0 * 3);
// x86-64 epilogue: restore rbp
return (int)((signed char)((((int)((((long long)(int)((((unsigned long)((long)((int)(narrowed))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(narrowed)) / (int)(2))) & 255)));
} nrw194_u16_mix pass 8 lines
// glaurung: nrw194_u16_mix @ 0x1170
uint16_t nrw194_u16_mix(int32_t arg0) {
unsigned short narrowed;
// x86-64 prologue: save rbp
narrowed = arg0;
// x86-64 epilogue: restore rbp
return (unsigned int)((unsigned short)(((unsigned long)((unsigned int)((((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)((unsigned int)(narrowed))) / (unsigned int)(9)))) + (unsigned long)((unsigned int)(((int)(narrowed) >> 11)))))) & 0xffff)));
} nrw194_u8_mix pass 8 lines
// glaurung: nrw194_u8_mix @ 0x1140
uint8_t nrw194_u8_mix(int32_t arg0) {
unsigned char narrowed;
// x86-64 prologue: save rbp
narrowed = arg0;
// x86-64 epilogue: restore rbp
return (unsigned int)((unsigned char)(((unsigned long)((unsigned int)((((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)((unsigned int)(narrowed))) / (unsigned int)(3)))) + (unsigned long)((unsigned int)(((int)(narrowed) >> 5)))))) & 255)));
} nrw194_u8_value_control pass 8 lines
// glaurung: nrw194_u8_value_control @ 0x1250
int32_t nrw194_u8_value_control(int32_t arg0) {
unsigned char narrowed;
// x86-64 prologue: save rbp
narrowed = arg0;
// x86-64 epilogue: restore rbp
return (unsigned int)((((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)((unsigned int)(narrowed))) / (unsigned int)(3)))) + (unsigned long)((unsigned int)(((int)(narrowed) >> 5)))));
} clang -O2
10/10nrw194_bool_and pass 6 lines
// glaurung: nrw194_bool_and @ 0x11a0
_Bool nrw194_bool_and(int32_t arg0, int32_t arg1) {
long var8;
var8 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) >> 3))) & (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) >> 2))))));
return ((unsigned char)(((var8 & -256) | (var8 & 1))) != 0);
} nrw194_bool_bit pass 4 lines
// glaurung: nrw194_bool_bit @ 0x1190
_Bool nrw194_bool_bit(int32_t arg0) {
return ((unsigned char)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) >> 8))) & 1))) != 0);
} nrw194_bool_wide_control pass 4 lines
// glaurung: nrw194_bool_wide_control @ 0x11e0
int32_t nrw194_bool_wide_control(int32_t arg0, int32_t arg1) {
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) >> 3))) & (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) >> 2)))))) & 1));
} nrw194_char_divide pass 8 lines
// glaurung: nrw194_char_divide @ 0x1180
char nrw194_char_divide(int32_t arg0) {
long var2;
long var4;
var2 = (((unsigned long)((unsigned int)(arg0)) & -256) | (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(arg0)) & 255))) >> 7) & 255));
var4 = ((var2 & -256) | (((var2 & 255) + ((unsigned long)((unsigned int)(arg0)) & 255)) & 255));
return ((var4 & -256) | (((signed char)((var4 & 255)) >> 1) & 255));
} nrw194_i16_divide pass 8 lines
// glaurung: nrw194_i16_divide @ 0x1120
int16_t nrw194_i16_divide(int32_t arg0) {
long var1;
int var6;
var1 = (unsigned long)((unsigned int)((arg0 << 16)));
var6 = ((unsigned int)(((int)((var1 + (var1 * 4))) >> 16)) * 0x4925);
return (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((int)(var6) >> 17))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var6)) >> 31))))));
} nrw194_i32_control pass 6 lines
// glaurung: nrw194_i32_control @ 0x11b0
int32_t nrw194_i32_control(int32_t arg0) {
int wide;
wide = (unsigned long)((unsigned int)((arg0 + (arg0 * 2))));
return (unsigned int)(((int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(wide)) >> 31))) + wide)) >> 1));
} nrw194_i8_divide pass 12 lines
// glaurung: nrw194_i8_divide @ 0x1100
int8_t nrw194_i8_divide(int32_t arg0) {
long var1;
long var11;
long var2;
long var9;
var1 = (unsigned long)((unsigned int)((arg0 << 24)));
var2 = (unsigned long)((unsigned int)((var1 + (var1 * 2))));
var9 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var2)) >> 31)));
var11 = ((var9 & -256) | (((var9 & 255) + ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var2)) >> 24))) & 255)) & 255));
return ((var11 & -256) | (((signed char)((var11 & 255)) >> 1) & 255));
} nrw194_u16_mix pass 6 lines
// glaurung: nrw194_u16_mix @ 0x1160
uint16_t nrw194_u16_mix(int32_t arg0) {
int var0;
var0 = (unsigned int)((unsigned short)((arg0 & 0xffff)));
return (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) >> 11))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var0 * 0xe38f))) >> 19))))));
} nrw194_u8_mix pass 8 lines
// glaurung: nrw194_u8_mix @ 0x1140
uint8_t nrw194_u8_mix(int32_t arg0) {
int var0;
long var6;
var0 = (unsigned int)((unsigned char)((arg0 & 255)));
var6 = (((unsigned long)((unsigned int)(var0)) & -256) | (((unsigned long)((unsigned char)((var0 & 255))) >> 5) & 255));
return ((var6 & -256) | (((var6 & 255) + ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var0 * 171))) >> 9))) & 255)) & 255));
} nrw194_u8_value_control pass 5 lines
// glaurung: nrw194_u8_value_control @ 0x11c0
int32_t nrw194_u8_value_control(int32_t arg0) {
unsigned char narrowed;
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)((arg0 & 255))) * 171))) >> 9))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) >> 5))) & 7)))));
} gcc -O0
10/10nrw194_bool_and pass 10 lines
// glaurung: nrw194_bool_and @ 0x11f8
_Bool nrw194_bool_and(int32_t arg0, int32_t arg1) {
int a;
int b;
long var13;
// x86-64 prologue: save rbp
var13 = (unsigned long)((unsigned int)((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 8))) != 0) & ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 4))) != 0))));
// x86-64 epilogue: restore rbp
return ((unsigned char)(((var13 & -256) | ((unsigned long)((unsigned int)(var13)) != 0))) != 0);
} nrw194_bool_bit pass 8 lines
// glaurung: nrw194_bool_bit @ 0x11de
_Bool nrw194_bool_bit(int32_t arg0) {
long var2;
// x86-64 prologue: save rbp
var2 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 256)));
// x86-64 epilogue: restore rbp
return ((unsigned char)(((var2 & -256) | ((unsigned long)((unsigned int)(var2)) != 0))) != 0);
} nrw194_bool_wide_control pass 8 lines
// glaurung: nrw194_bool_wide_control @ 0x128b
int32_t nrw194_bool_wide_control(int32_t arg0, int32_t arg1) {
int a;
int b;
// x86-64 prologue: save rbp
// x86-64 epilogue: restore rbp
return (unsigned int)((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 4))) != 0) & ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 8))) != 0)));
} nrw194_char_divide pass 10 lines
// glaurung: nrw194_char_divide @ 0x11be
char nrw194_char_divide(int32_t arg0) {
signed char narrowed;
int var5;
// x86-64 prologue: save rbp
narrowed = arg0;
var5 = ((unsigned int)((unsigned char)(narrowed)) + (((unsigned int)((unsigned char)(narrowed)) & -256) | (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)((unsigned char)(narrowed))) & 255))) >> 7) & 255)));
// x86-64 epilogue: restore rbp
return (((unsigned long)((unsigned int)(var5)) & -256) | (((signed char)(((unsigned long)((unsigned int)(var5)) & 255)) >> 1) & 255));
} nrw194_i16_divide pass 10 lines
// glaurung: nrw194_i16_divide @ 0x1121
int16_t nrw194_i16_divide(int32_t arg0) {
short narrowed;
long var12;
// x86-64 prologue: save rbp
narrowed = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) << 2))) + (unsigned long)((unsigned int)(arg0)));
var12 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((int)((short)(((unsigned int)((unsigned short)(narrowed)) & 0xffff))) * 0x4925))) >> 16)));
// x86-64 epilogue: restore rbp
return (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((var12 & -0x10000LL) | (((short)((var12 & 0xffff)) >> 1) & 0xffff)))) - (unsigned long)((unsigned int)((((unsigned int)((unsigned short)(narrowed)) & -0x10000LL) | (((short)(((unsigned int)((unsigned short)(narrowed)) & 0xffff)) >> 15) & 0xffff)))))));
} nrw194_i32_control pass 8 lines
// glaurung: nrw194_i32_control @ 0x1233
int32_t nrw194_i32_control(int32_t arg0) {
int wide;
// x86-64 prologue: save rbp
wide = ((unsigned int)(((unsigned long)((unsigned int)(arg0)) + (unsigned long)((unsigned int)(arg0)))) + (unsigned int)(arg0));
// x86-64 epilogue: restore rbp
return (unsigned int)(((int)(((unsigned long)((unsigned int)(wide)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(wide)) >> 31))))) >> 1));
} nrw194_i8_divide pass 10 lines
// glaurung: nrw194_i8_divide @ 0x10f9
int8_t nrw194_i8_divide(int32_t arg0) {
signed char narrowed;
int var11;
// x86-64 prologue: save rbp
narrowed = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + (unsigned long)((unsigned int)(arg0))))) + (unsigned long)((unsigned int)(arg0)));
var11 = ((unsigned int)((unsigned char)(narrowed)) + (((unsigned int)((unsigned char)(narrowed)) & -256) | (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)((unsigned char)(narrowed))) & 255))) >> 7) & 255)));
// x86-64 epilogue: restore rbp
return (((unsigned long)((unsigned int)(var11)) & -256) | (((signed char)(((unsigned long)((unsigned int)(var11)) & 255)) >> 1) & 255));
} nrw194_u16_mix pass 10 lines
// glaurung: nrw194_u16_mix @ 0x118a
uint16_t nrw194_u16_mix(int32_t arg0) {
unsigned short narrowed;
long var7;
// x86-64 prologue: save rbp
narrowed = arg0;
var7 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned short)((narrowed & 0xffff))) * 0xe38f))) >> 16)));
// x86-64 epilogue: restore rbp
return (unsigned long)((unsigned int)(((((unsigned int)(narrowed) & -0x10000LL) | (((unsigned long)((unsigned short)(((unsigned int)(narrowed) & 0xffff))) >> 11) & 0xffff)) + ((var7 & -0x10000LL) | (((unsigned long)((unsigned short)((var7 & 0xffff))) >> 3) & 0xffff)))));
} nrw194_u8_mix pass 12 lines
// glaurung: nrw194_u8_mix @ 0x115b
uint8_t nrw194_u8_mix(int32_t arg0) {
unsigned char narrowed;
long var6;
long var9;
// x86-64 prologue: save rbp
narrowed = arg0;
var6 = (((unsigned long)(narrowed) & -0x10000LL) | ((((unsigned char)(((unsigned short)(unsigned char)((narrowed & 255)) * (unsigned short)(unsigned char)((0xffffffab & 255))) >> 8)) & 255) << 8));
var9 = (unsigned long)((unsigned int)(((var6 & -0x10000LL) | (((unsigned long)((unsigned short)((var6 & 0xffff))) >> 8) & 0xffff))));
// x86-64 epilogue: restore rbp
return (unsigned long)((unsigned int)(((((unsigned int)(narrowed) & -256) | (((unsigned long)((unsigned char)(((unsigned int)(narrowed) & 255))) >> 5) & 255)) + ((var9 & -256) | (((unsigned long)((unsigned char)((var9 & 255))) >> 1) & 255)))));
} nrw194_u8_value_control pass 8 lines
// glaurung: nrw194_u8_value_control @ 0x1258
int32_t nrw194_u8_value_control(int32_t arg0) {
unsigned char narrowed;
// x86-64 prologue: save rbp
narrowed = arg0;
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned int)((unsigned char)((((unsigned long)((unsigned char)(((unsigned int)(narrowed) & 255))) >> 5) & 255))) + (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((((unsigned long)((unsigned short)((((((unsigned char)(((unsigned short)(unsigned char)(((unsigned int)(narrowed) & 255)) * (unsigned short)(unsigned char)((0xffffffab & 255))) >> 8)) & 255) << 8) & 0xffff))) >> 8) & 255))) >> 1) & 255)))));
} gcc -O2
10/10nrw194_bool_and pass 4 lines
// glaurung: nrw194_bool_and @ 0x11a0
_Bool nrw194_bool_and(int32_t arg0, int32_t arg1) {
return ((unsigned char)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) >> 3))) & 1))) & (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) >> 2)))))) != 0);
} nrw194_bool_bit pass 4 lines
// glaurung: nrw194_bool_bit @ 0x1190
_Bool nrw194_bool_bit(int32_t arg0) {
return ((unsigned char)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) >> 8))) & 1))) != 0);
} nrw194_bool_wide_control pass 4 lines
// glaurung: nrw194_bool_wide_control @ 0x1200
int32_t nrw194_bool_wide_control(int32_t arg0, int32_t arg1) {
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) >> 3))) & (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) >> 2)))))) & 1));
} nrw194_char_divide pass 6 lines
// glaurung: nrw194_char_divide @ 0x1180
char nrw194_char_divide(int32_t arg0) {
int var3;
var3 = ((((unsigned int)(arg0) & -256) | (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(arg0)) & 255))) >> 7) & 255)) + arg0);
return (((unsigned long)((unsigned int)(var3)) & -256) | (((signed char)(((unsigned long)((unsigned int)(var3)) & 255)) >> 1) & 255));
} nrw194_i16_divide pass 6 lines
// glaurung: nrw194_i16_divide @ 0x1120
int16_t nrw194_i16_divide(int32_t arg0) {
long var0;
var0 = (unsigned long)((unsigned int)((arg0 + (arg0 * 4))));
return (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((int)(((int)((short)((var0 & 0xffff))) * 0x4925)) >> 17))) - ((var0 & -0x10000LL) | (((short)((var0 & 0xffff)) >> 15) & 0xffff)))));
} nrw194_i32_control pass 6 lines
// glaurung: nrw194_i32_control @ 0x11c0
int32_t nrw194_i32_control(int32_t arg0) {
long var0;
var0 = (unsigned long)((unsigned int)((arg0 + (arg0 * 2))));
return (unsigned int)(((int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) >> 31))) + var0)) >> 1));
} nrw194_i8_divide pass 8 lines
// glaurung: nrw194_i8_divide @ 0x1100
int8_t nrw194_i8_divide(int32_t arg0) {
long var0;
int var4;
var0 = (unsigned long)((unsigned int)((arg0 + (arg0 * 2))));
var4 = ((((unsigned int)(var0) & -256) | (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(var0)) & 255))) >> 7) & 255)) + var0);
return (((unsigned long)((unsigned int)(var4)) & -256) | (((signed char)(((unsigned long)((unsigned int)(var4)) & 255)) >> 1) & 255));
} nrw194_u16_mix pass 4 lines
// glaurung: nrw194_u16_mix @ 0x1160
uint16_t nrw194_u16_mix(int32_t arg0) {
return (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned short)((arg0 & 0xffff))) * 0xe38f))) >> 19))) + ((arg0 & -0x10000LL) | (((unsigned long)((unsigned short)((arg0 & 0xffff))) >> 11) & 0xffff)))));
} nrw194_u8_mix pass 6 lines
// glaurung: nrw194_u8_mix @ 0x1140
uint8_t nrw194_u8_mix(int32_t arg0) {
long var4;
var4 = (0xffff0000 | ((((unsigned char)(((unsigned short)(unsigned char)((0xffffffab & 255)) * (unsigned short)(unsigned char)((arg0 & 255))) >> 8)) & 255) << 8));
return (unsigned long)((unsigned int)((((var4 & -0x10000LL) | (((unsigned long)((unsigned short)((var4 & 0xffff))) >> 9) & 0xffff)) + ((arg0 & -256) | (((unsigned long)((unsigned char)((arg0 & 255))) >> 5) & 255)))));
} nrw194_u8_value_control pass 4 lines
// glaurung: nrw194_u8_value_control @ 0x11e0
int32_t nrw194_u8_value_control(int32_t arg0) {
return (unsigned int)(((unsigned int)((unsigned char)((((unsigned long)((unsigned short)((((((unsigned char)(((unsigned short)(unsigned char)((0xffffffab & 255)) * (unsigned short)(unsigned char)((arg0 & 255))) >> 8)) & 255) << 8) & 0xffff))) >> 9) & 255))) + (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((arg0 & 255))) >> 5) & 255)))));
}