Fixture 201
float bit stores
C · 8 functions · 4 lanes · 25 of 32 function-lanes behave identically
4 of 4 lanes have a function that returns a different result after decompilation: gcc-O2 (5/8), clang-O2 (6/8), clang-O0 (7/8), gcc-O0 (7/8).
A FLOATING VALUE STORED THROUGH INTEGER-TYPED STORAGE, and the reverse.
movss %xmm0, -0x10(%rbp) copies four bytes. The recovered destination type comes from the ACCESS WIDTH, so it is int, and a renderer that reconciles an int destination with a float source by inserting a cast emits *(int *)(&local[0]) = (float)(...) — which is C's arithmetic conversion (C23 6.3.1.4, truncation toward zero). 1.5f is then written as 1 rather than 0x3FC00000, and every byte of the destination is wrong immediately, before anything downstream reads it.
The corpus already contained this shape in 195, 197 and 198 — but only inside AGGREGATE-RETURNING helpers, which exec_class refuses, so all twelve occurrences were recorded structural and none was ever executed. It also contained it in 174's fp174_float_bits, which is a LOCAL symbol with no baseline row of its own. So the defect had no lane that could report it: no function in the corpus both exhibits the shape and is directly executed. Every function here is int32_t-returning and scalar-argument, so every one of them is.
THE NEGATIVE CONTROLS ARE THE POINT. A reinterpretation is right here and wrong for cvttss2si, and the two are one instruction apart. f201_*_values do the same arithmetic on the same values and TRUNCATE, so a recovery that satisfies the positives by never converting fails exactly there; and f201_scalar_control has no floating point at all, so a recovery that broke ordinary integer stores while fixing these is separable from one that did not.
memcpy rather than a union or a pointer cast: it is the one spelling defined under every aliasing rule, and both compilers turn a four- or eight-byte copy into a single register move. Every value is a small integer converted to float/double, so it is exactly representable in both widths and the differential compares exact values rather than rounding artifacts.
#include <stdint.h>
#include <string.h>
/* A FLOATING VALUE STORED THROUGH INTEGER-TYPED STORAGE, and the reverse.
*
* `movss %xmm0, -0x10(%rbp)` copies four bytes. The recovered destination type
* comes from the ACCESS WIDTH, so it is `int`, and a renderer that reconciles
* an `int` destination with a `float` source by inserting a cast emits
* `*(int *)(&local[0]) = (float)(...)` — which is C's arithmetic conversion
* (C23 6.3.1.4, truncation toward zero). `1.5f` is then written as `1` rather
* than `0x3FC00000`, and every byte of the destination is wrong immediately,
* before anything downstream reads it.
*
* The corpus already contained this shape in `195`, `197` and `198` — but only
* inside AGGREGATE-RETURNING helpers, which `exec_class` refuses, so all twelve
* occurrences were recorded `structural` and none was ever executed. It also
* contained it in `174`'s `fp174_float_bits`, which is a LOCAL symbol with no
* baseline row of its own. So the defect had no lane that could report it: no
* function in the corpus both exhibits the shape and is directly executed.
* Every function here is `int32_t`-returning and scalar-argument, so every one
* of them is.
*
* THE NEGATIVE CONTROLS ARE THE POINT. A reinterpretation is right here and
* wrong for `cvttss2si`, and the two are one instruction apart. `f201_*_values`
* do the same arithmetic on the same values and TRUNCATE, so a recovery that
* satisfies the positives by never converting fails exactly there; and
* `f201_scalar_control` has no floating point at all, so a recovery that broke
* ordinary integer stores while fixing these is separable from one that did not.
*
* `memcpy` rather than a union or a pointer cast: it is the one spelling
* defined under every aliasing rule, and both compilers turn a four- or
* eight-byte copy into a single register move. Every value is a small integer
* converted to `float`/`double`, so it is exactly representable in both widths
* and the differential compares exact values rather than rounding artifacts. */
#define F201_SLOTS 2
/* ---- positives: a float's BITS reach an integer destination ---------------- */
/* The reported shape at binary32. At `-O0` both compilers emit
* `cvtsi2ss ... ; movss %xmm0, -N(%rbp)` for each slot and then read the same
* bytes back with an integer `mov`. The exponent fields are the part a
* truncating conversion destroys: `(float)(seed + 1)` for a small `seed` has
* bits around 0x4000_0000 and a value around 1, so the two disagree in every
* bit that this function returns. */
__attribute__((noinline)) int32_t f201_f32_slot_bits(int32_t seed) {
float slots[F201_SLOTS];
uint32_t words[F201_SLOTS];
slots[0] = (float)(seed + 1);
slots[1] = (float)(seed * 2 + 3);
memcpy(words, slots, sizeof words);
/* Distinct coefficients, so recovering the right total from permuted or
* duplicated slots is caught rather than passing by luck. */
return (int32_t)((words[0] >> 23) * 3u + (words[1] >> 20) * 5u);
}
/* The same at binary64, which is a different instruction (`movsd`), a different
* access width, and a different recovered pointee (`long`, not `int`). */
__attribute__((noinline)) int32_t f201_f64_slot_bits(int32_t seed) {
double slots[F201_SLOTS];
uint64_t words[F201_SLOTS];
slots[0] = (double)(seed + 1);
slots[1] = (double)(seed * 2 + 3);
memcpy(words, slots, sizeof words);
return (int32_t)((uint32_t)(words[0] >> 52) * 3u + (uint32_t)(words[1] >> 48) * 5u);
}
/* The single-value form, with no array indexing between the store and the read.
* This is `174`'s `fp174_float_bits` promoted to an exported, executable
* function: the whole body is one `movss` to the frame and one `mov` back. */
__attribute__((noinline)) int32_t f201_f32_single_bits(int32_t seed) {
float value = (float)(seed * 4 + 1);
uint32_t word;
memcpy(&word, &value, sizeof word);
return (int32_t)(word >> 16);
}
/* Through a CALLER-OWNED pointer rather than a frame slot, so the destination
* is not a promoted local and the store cannot be recovered as a plain
* variable assignment. */
__attribute__((noinline)) int32_t f201_store_through_pointer(int32_t *out, int32_t seed) {
float value = (float)(seed + 7);
if (out == 0) {
return -1;
}
memcpy(out, &value, sizeof *out);
return (int32_t)(((uint32_t)*out) >> 21);
}
/* ---- the mirror: an integer bit pattern read back as a float --------------- */
/* `word` is built with a pinned exponent field, so `value` is finite, normal
* and inside [8, 16) for every input the harness can draw — the multiply and
* the truncation below are therefore defined for all of them, and a NaN or an
* out-of-range conversion can never be reached. */
__attribute__((noinline)) int32_t f201_word_to_value(int32_t seed) {
uint32_t word = 0x41000000u | (((uint32_t)seed & 0x7Fu) << 8);
float value;
memcpy(&value, &word, sizeof value);
return (int32_t)(value * 256.0f);
}
/* ---- negative controls: conversions that must stay conversions ------------- */
/* THE FIRST NEGATIVE. Identical storage, identical arithmetic, but the slots
* are read as NUMBERS. `cvttss2si` truncates toward zero, and a recovery that
* reinterpreted every float reaching an integer destination would return the
* exponent fields here instead of the values — off by seven orders of
* magnitude, not by a rounding step. Bounded well inside the int32 range so no
* conversion is undefined. */
__attribute__((noinline)) int32_t f201_f32_slot_values(int32_t seed) {
float slots[F201_SLOTS];
slots[0] = (float)(seed + 1) / 2.0f;
slots[1] = (float)(seed * 2 + 3) / 4.0f;
return (int32_t)slots[0] * 3 + (int32_t)slots[1] * 5;
}
/* THE SECOND NEGATIVE, at binary64 and through a `memcpy` of the FLOAT — the
* copy is a bit move, the read that follows is a conversion, and both happen in
* one function. A recovery that decides "this buffer holds bits" or "this
* buffer holds numbers" once per object rather than once per access is wrong
* here whichever way it decides. */
__attribute__((noinline)) int32_t f201_f64_copy_then_convert(int32_t seed) {
double value = (double)(seed * 3 + 1) / 8.0;
double copy;
memcpy(©, &value, sizeof copy);
return (int32_t)copy * 7;
}
/* THE THIRD NEGATIVE: the same buffer traffic with no floating point anywhere,
* so a recovery that damaged ordinary integer stores while fixing the positives
* fails here and only here. */
__attribute__((noinline)) int32_t f201_scalar_control(int32_t seed) {
int32_t slots[F201_SLOTS];
uint32_t words[F201_SLOTS];
slots[0] = seed + 1;
slots[1] = seed * 2 + 3;
memcpy(words, slots, sizeof words);
return (int32_t)(words[0] * 3u + words[1] * 5u);
} 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.
gcc -O2
5/8f201_f32_single_bits pass 4 lines
// glaurung: f201_f32_single_bits @ 0x1180
int32_t f201_f32_single_bits(int32_t arg0) {
return (unsigned int)(((unsigned long)((unsigned int)(((union { unsigned int bits; float value; }){ .value = (float)((int)((unsigned long)((unsigned int)(((0 + (arg0 * 4)) + 1))))) }).bits)) >> 16));
} f201_f32_slot_bits pass 8 lines
// glaurung: f201_f32_slot_bits @ 0x1100
int32_t f201_f32_slot_bits(int32_t arg0) {
long var19;
long var22;
var19 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((union { unsigned int bits; float value; }){ .value = (float)((int)((unsigned long)((unsigned int)((arg0 + 1))))) }).bits)) >> 23)));
var22 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((union { unsigned int bits; float value; }){ .value = (float)((int)((unsigned long)((unsigned int)(((arg0 + arg0) + 3))))) }).bits)) >> 20)));
return (unsigned int)(((unsigned long)((unsigned int)((var19 + (var19 * 2)))) + (unsigned long)((unsigned int)((var22 + (var22 * 4))))));
} f201_f32_slot_values fail 11 lines
// glaurung: f201_f32_slot_values @ 0x1200
int32_t f201_f32_slot_values(int32_t arg0) {
long ret;
long var11;
long var20;
var11 = (int)(((float)((int)((unsigned long)((unsigned int)(((arg0 + arg0) + 3))))) * ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0x3e800000) }).value));
ret = ((union { unsigned int bits; float value; }){ .value = ((float)((int)((unsigned long)((unsigned int)((arg0 + 1))))) * ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0x3f000000) }).value) }).bits;
ret = (unsigned long)((unsigned int)((var11 + (var11 * 4))));
var20 = (int)(((union { unsigned int bits; float value; }){ .bits = (unsigned int)(ret) }).value);
return (unsigned int)((ret + (unsigned long)((unsigned int)((var20 + (var20 * 2))))));
} f201_f64_copy_then_convert pass 6 lines
// glaurung: f201_f64_copy_then_convert @ 0x1240
int32_t f201_f64_copy_then_convert(int32_t arg0) {
int var11;
var11 = (int)(((double)((int)((unsigned long)((unsigned int)(((arg0 + (arg0 * 2)) + 1))))) * ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0x3fc0000000000000) }).value));
return (unsigned int)(((unsigned long)((unsigned int)((var11 * 8))) - var11));
} f201_f64_slot_bits fail 8 lines
// glaurung: f201_f64_slot_bits @ 0x1140
int32_t f201_f64_slot_bits(int32_t arg0) {
double var19;
double var20;
var19 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(((unsigned long)((double)((int)((unsigned long)((unsigned int)((arg0 + 1)))))) >> 52)) }).value;
var20 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(((unsigned long)((double)((int)((unsigned long)((unsigned int)(((arg0 + arg0) + 3)))))) >> 48)) }).value;
return (unsigned int)(((unsigned long)((unsigned int)(((union { unsigned long long bits; double value; }){ .value = (var19 + (var19 * ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(2) }).value)) }).bits)) + (unsigned long)((unsigned int)(((union { unsigned long long bits; double value; }){ .value = (var20 + (var20 * ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(4) }).value)) }).bits))));
} f201_scalar_control pass 6 lines
// glaurung: f201_scalar_control @ 0x1270
int32_t f201_scalar_control(int32_t arg0) {
long var0;
var0 = (unsigned long)((unsigned int)(((arg0 + arg0) + 3)));
return (unsigned int)(((unsigned long)((unsigned int)(((arg0 + (arg0 * 2)) + 3))) + (unsigned long)((unsigned int)((var0 + (var0 * 4))))));
} f201_store_through_pointer pass 11 lines
// glaurung: f201_store_through_pointer @ 0x11a0
int32_t f201_store_through_pointer(int32_t * arg0, int32_t arg1) {
float value;
float var7;
var7 = (float)((int)((unsigned long)((unsigned int)((arg1 + 7)))));
if ((arg0 == 0)) {
return 0xffffffff;
}
*(float *)(((long)arg0)) = var7;
return (unsigned int)(((unsigned long)((unsigned int)(((union { unsigned int bits; float value; }){ .value = var7 }).bits)) >> 21));
} f201_word_to_value fail 4 lines
// glaurung: f201_word_to_value @ 0x11d0
int32_t f201_word_to_value(int32_t arg0) {
return ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 << 8))) & 0x7f00))) | 0x41000000))) * 0x43800000);
} clang -O2
6/8f201_f32_single_bits pass 6 lines
// glaurung: f201_f32_single_bits @ 0x1160
int32_t f201_f32_single_bits(int32_t arg0) {
float value;
unsigned int word;
return (unsigned int)(((unsigned long)((unsigned int)(((union { unsigned int bits; float value; }){ .value = (float)((int)((unsigned long)((unsigned int)(((0 + (arg0 * 4)) + 1))))) }).bits)) >> 16));
} f201_f32_slot_bits pass 8 lines
// glaurung: f201_f32_slot_bits @ 0x1100
int32_t f201_f32_slot_bits(int32_t arg0) {
long var12;
long var16;
var12 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((union { unsigned int bits; float value; }){ .value = (float)((int)((unsigned long)((unsigned int)((arg0 + 1))))) }).bits)) >> 23)));
var16 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((union { unsigned int bits; float value; }){ .value = (float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + arg0))) + 3))))) }).bits)) >> 20)));
return (unsigned int)(((unsigned long)((unsigned int)((var16 + (var16 * 4)))) + (unsigned long)((unsigned int)((var12 + (var12 * 2))))));
} f201_f32_slot_values pass 8 lines
// glaurung: f201_f32_slot_values @ 0x11c0
int32_t f201_f32_slot_values(int32_t arg0) {
int var11;
int var13;
var11 = (int)(((float)((int)((unsigned long)((unsigned int)((arg0 + 1))))) * ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0x3f000000) }).value));
var13 = (int)(((float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + arg0))) + 3))))) * ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0x3e800000) }).value));
return (unsigned int)(((unsigned long)((unsigned int)((var13 + (var13 * 4)))) + (unsigned long)((unsigned int)((var11 + (var11 * 2))))));
} f201_f64_copy_then_convert pass 8 lines
// glaurung: f201_f64_copy_then_convert @ 0x1200
int32_t f201_f64_copy_then_convert(int32_t arg0) {
double copy;
double value;
int var9;
var9 = (int)(((double)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + (arg0 * 2)))) + 1))))) * ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0x3fc0000000000000) }).value));
return (unsigned int)(((unsigned long)((unsigned int)((var9 * 8))) - var9));
} f201_f64_slot_bits fail 8 lines
// glaurung: f201_f64_slot_bits @ 0x1130
int32_t f201_f64_slot_bits(int32_t arg0) {
double var11;
double var13;
var11 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(((unsigned long)((double)((int)((unsigned long)((unsigned int)((arg0 + 1)))))) >> 52)) }).value;
var13 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(((unsigned long)((double)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + arg0))) + 3)))))) >> 48)) }).value;
return (unsigned int)(((unsigned long)((unsigned int)(((union { unsigned long long bits; double value; }){ .value = (var13 + (var13 * ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(4) }).value)) }).bits)) + (unsigned long)((unsigned int)(((union { unsigned long long bits; double value; }){ .value = (var11 + (var11 * ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(2) }).value)) }).bits))));
} f201_scalar_control pass 4 lines
// glaurung: f201_scalar_control @ 0x1220
int32_t f201_scalar_control(int32_t arg0) {
return (unsigned int)(((unsigned long)((unsigned int)((arg0 + ((unsigned long)((unsigned int)((arg0 + (arg0 * 2)))) * 4)))) + 18));
} f201_store_through_pointer pass 11 lines
// glaurung: f201_store_through_pointer @ 0x1180
int32_t f201_store_through_pointer(int32_t * arg0, int32_t arg1) {
float value;
float var2;
if ((arg0 == 0)) {
return 0xffffffff;
}
var2 = (float)((int)((unsigned long)((unsigned int)((arg1 + 7)))));
*(float *)(((long)arg0)) = var2;
return (unsigned int)(((unsigned long)((unsigned int)(((union { unsigned int bits; float value; }){ .value = var2 }).bits)) >> 21));
} f201_word_to_value fail 6 lines
// glaurung: f201_word_to_value @ 0x11a0
int32_t f201_word_to_value(int32_t arg0) {
float value;
unsigned int word;
return ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 & 127))) << 8))) | 0x41000000))) * 0x43800000);
} clang -O0
7/8f201_f32_single_bits pass 10 lines
// glaurung: f201_f32_single_bits @ 0x11b0
int32_t f201_f32_single_bits(int32_t arg0) {
float value;
unsigned int word;
// x86-64 prologue: save rbp
value = (float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) << 2))) + 1)))));
word = ((union { unsigned int bits; float value; }){ .value = value }).bits;
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)(word) >> 16));
} f201_f32_slot_bits pass 11 lines
// glaurung: f201_f32_slot_bits @ 0x1100
__attribute__((no_stack_protector)) int32_t f201_f32_slot_bits(int32_t arg0) {
unsigned char local_14[8];
unsigned char local_c[8];
// x86-64 prologue: save rbp
*(float *)(&local_c[0]) = (float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + 1)))));
*(float *)((&local_c[0] + 4)) = (float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) << 1))) + 3)))));
*(long *)(&local_14[0]) = *(long *)(&local_c[0]);
// x86-64 epilogue: restore rbp
return (unsigned int)((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)(&local_14[0]))) >> 23))) * 3) + ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)((&local_14[0] + 4)))) >> 20))) * 5)));
} f201_f32_slot_values pass 9 lines
// glaurung: f201_f32_slot_values @ 0x1270
__attribute__((no_stack_protector)) int32_t f201_f32_slot_values(int32_t arg0) {
unsigned char local_c[8];
// x86-64 prologue: save rbp
*(float *)(&local_c[0]) = ((float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + 1))))) / ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0x40000000) }).value);
*(float *)((&local_c[0] + 4)) = ((float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) << 1))) + 3))))) / ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0x40800000) }).value);
// x86-64 epilogue: restore rbp
return (unsigned int)((((int)(*(float *)(&local_c[0])) * 3) + ((int)(*(float *)((&local_c[0] + 4))) * 5)));
} f201_f64_copy_then_convert pass 10 lines
// glaurung: f201_f64_copy_then_convert @ 0x12d0
int32_t f201_f64_copy_then_convert(int32_t arg0) {
double value;
double copy;
// x86-64 prologue: save rbp
value = ((double)((int)((unsigned long)((unsigned int)(((arg0 * 3) + 1))))) / ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0x4020000000000000) }).value);
copy = value;
// x86-64 epilogue: restore rbp
return ((int)(copy) * 7);
} f201_f64_slot_bits pass 12 lines
// glaurung: f201_f64_slot_bits @ 0x1150
__attribute__((no_stack_protector)) int32_t f201_f64_slot_bits(int32_t arg0) {
unsigned char local_20[16];
unsigned char local_30[16];
// x86-64 prologue: save rbp
*(double *)(&local_20[0]) = (double)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + 1)))));
*(double *)((&local_20[0] + 8)) = (double)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) << 1))) + 3)))));
*(long *)(&local_30[0]) = *(long *)(&local_20[0]);
*(long *)((&local_30[0] + 8)) = *(long *)((&local_20[0] + 8));
// x86-64 epilogue: restore rbp
return (unsigned int)(((((unsigned long)(*(long *)(&local_30[0])) >> 52) * 3) + (((unsigned long)(*(long *)((&local_30[0] + 8))) >> 48) * 5)));
} f201_scalar_control pass 11 lines
// glaurung: f201_scalar_control @ 0x1310
__attribute__((no_stack_protector)) int32_t f201_scalar_control(int32_t arg0) {
unsigned char local_14[8];
unsigned char local_c[8];
// x86-64 prologue: save rbp
*(int *)(&local_c[0]) = ((unsigned long)((unsigned int)(arg0)) + 1);
*(int *)((&local_c[0] + 4)) = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) << 1))) + 3);
*(long *)(&local_14[0]) = *(long *)(&local_c[0]);
// x86-64 epilogue: restore rbp
return (unsigned int)(((*(int *)(&local_14[0]) * 3) + (*(int *)((&local_14[0] + 4)) * 5)));
} f201_store_through_pointer pass 12 lines
// glaurung: f201_store_through_pointer @ 0x11e0
int32_t f201_store_through_pointer(int32_t * arg0, int32_t arg1) {
float value;
// x86-64 prologue: save rbp
value = (float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + 7)))));
if ((arg0 != 0)) {
*(float *)((long)arg0) = value;
return (unsigned int)(((unsigned long)((unsigned int)(*(int *)((long)arg0))) >> 21));
} else {
return (unsigned int)(-1);
}
} f201_word_to_value fail 10 lines
// glaurung: f201_word_to_value @ 0x1230
int32_t f201_word_to_value(int32_t arg0) {
unsigned int word;
float value;
// x86-64 prologue: save rbp
word = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 127))) << 8)) | 0x41000000);
value = ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(word) }).value;
// x86-64 epilogue: restore rbp
return ((union { unsigned int bits; float value; }){ .value = (((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0x43800000) }).value * value) }).bits;
} gcc -O0
7/8f201_f32_single_bits pass 18 lines
// glaurung: f201_f32_single_bits @ 0x122d
int32_t f201_f32_single_bits(int32_t arg0) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
float value;
unsigned int word;
long local_8;
long ret;
// x86-64 prologue: save rbp, frame 32 bytes
local_8 = (long)(0x28);
value = (float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) << 2))) + 1)))));
word = ((union { unsigned int bits; float value; }){ .value = value }).bits;
ret = (unsigned long)((unsigned int)(((unsigned int)(word) >> 16)));
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} f201_f32_slot_bits pass 23 lines
// glaurung: f201_f32_slot_bits @ 0x1119
int32_t f201_f32_slot_bits(int32_t arg0) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
unsigned char local_10[8];
unsigned char local_18[8];
long local_8;
long ret;
long var28;
long var37;
// x86-64 prologue: save rbp, frame 48 bytes
local_8 = (long)(0x28);
*(float *)(&local_18[0]) = (float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + 1)))));
*(float *)((&local_18[0] + 4)) = (float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + (unsigned long)((unsigned int)(arg0))))) + 3)))));
*(long *)(&local_10[0]) = *(long *)(&local_18[0]);
var28 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)(&local_10[0]))) >> 23)));
var37 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)((&local_10[0] + 4)))) >> 20)));
ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var37)) << 2))) + var37))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var28)) + (unsigned long)((unsigned int)(var28))))) + var28))))));
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} f201_f32_slot_values pass 21 lines
// glaurung: f201_f32_slot_values @ 0x1350
int32_t f201_f32_slot_values(int32_t arg0) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
unsigned char local_10[8];
long local_8;
long ret;
int var42;
int var52;
// x86-64 prologue: save rbp, frame 32 bytes
local_8 = (long)(0x28);
*(float *)(&local_10[0]) = ((float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + 1))))) / ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0x40000000) }).value);
*(float *)((&local_10[0] + 4)) = ((float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + (unsigned long)((unsigned int)(arg0))))) + 3))))) / ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0x40800000) }).value);
var42 = (int)(*(float *)(&local_10[0]));
var52 = (int)(*(float *)((&local_10[0] + 4)));
ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var52)) << 2))) + var52))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var42)) + (unsigned long)((unsigned int)(var42))))) + var42))))));
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} f201_f64_copy_then_convert pass 20 lines
// glaurung: f201_f64_copy_then_convert @ 0x13e6
int32_t f201_f64_copy_then_convert(int32_t arg0) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
double value;
double copy;
long local_8;
long ret;
int var32;
// x86-64 prologue: save rbp, frame 48 bytes
local_8 = (long)(0x28);
value = ((double)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((unsigned long)((unsigned int)(arg0)))) + (unsigned long)((unsigned int)((unsigned long)((unsigned int)(arg0))))))) + (unsigned long)((unsigned int)(arg0))))) + 1))))) / ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0x4020000000000000) }).value);
copy = value;
var32 = (int)(copy);
ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var32)) << 3))) - var32)));
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} f201_f64_slot_bits pass 26 lines
// glaurung: f201_f64_slot_bits @ 0x119d
int32_t f201_f64_slot_bits(int32_t arg0) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
unsigned char local_20[16];
unsigned char local_30[16];
long local_8;
long ret;
long var26;
long var29;
long var36;
// x86-64 prologue: save rbp, frame 64 bytes
local_8 = (long)(0x28);
*(double *)(&local_30[0]) = (double)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + 1)))));
*(double *)((&local_30[0] + 8)) = (double)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + (unsigned long)((unsigned int)(arg0))))) + 3)))));
var26 = *(long *)((&local_30[0] + 8));
*(long *)(&local_20[0]) = *(long *)(&local_30[0]);
*(long *)((&local_20[0] + 8)) = var26;
var29 = (unsigned long)((unsigned int)(((unsigned long)(*(long *)(&local_20[0])) >> 52)));
var36 = (unsigned long)((unsigned int)(((unsigned long)(*(long *)((&local_20[0] + 8))) >> 48)));
ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var36)) << 2))) + var36))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var29)) + (unsigned long)((unsigned int)(var29))))) + var29))))));
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} f201_scalar_control pass 23 lines
// glaurung: f201_scalar_control @ 0x1457
int32_t f201_scalar_control(int32_t arg0) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
unsigned char local_10[8];
unsigned char local_18[8];
long local_8;
long ret;
long var12;
long var17;
// x86-64 prologue: save rbp, frame 48 bytes
local_8 = (long)(0x28);
*(int *)(&local_18[0]) = ((unsigned long)((unsigned int)(arg0)) + 1);
*(int *)((&local_18[0] + 4)) = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) + (unsigned long)((unsigned int)(arg0))))) + 3);
*(long *)(&local_10[0]) = *(long *)(&local_18[0]);
var12 = (unsigned long)((unsigned int)(*(int *)(&local_10[0])));
var17 = (unsigned long)((unsigned int)(*(int *)((&local_10[0] + 4))));
ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var17)) << 2))) + var17))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var12)) + (unsigned long)((unsigned int)(var12))))) + var12))))));
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} f201_store_through_pointer pass 22 lines
// glaurung: f201_store_through_pointer @ 0x1283
int32_t f201_store_through_pointer(int32_t * arg0, int32_t arg1) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
float value;
long local_8;
long ret;
// x86-64 prologue: save rbp, frame 32 bytes
local_8 = (long)(0x28);
ret = 0;
value = (float)((int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + 7)))));
if ((arg0 != 0)) {
*(float *)((long)arg0) = value;
ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)((long)arg0))) >> 21)));
} else {
ret = 0xffffffff;
}
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} f201_word_to_value fail 18 lines
// glaurung: f201_word_to_value @ 0x12ee
int32_t f201_word_to_value(int32_t arg0) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
unsigned int word;
float value;
long local_8;
long ret;
// x86-64 prologue: save rbp, frame 32 bytes
local_8 = (long)(0x28);
word = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) << 8))) & 0x7f00)) | 0x41000000);
value = ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(word) }).value;
ret = ((union { unsigned int bits; float value; }){ .value = (((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0x43800000) }).value * value) }).bits;
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
}