Fixture 175

float matrix kernel

C · 6 functions · 4 lanes · 15 of 24 function-lanes behave identically

4 of 4 lanes have a function that returns a different result after decompilation: clang-O2 (3/6), gcc-O2 (3/6), clang-O0 (4/6), gcc-O0 (5/6).

A small floating-point numeric kernel over CALLER-OWNED buffers: a dot product at both widths, and the 2x2 matrix operations built on it.

This is the shape the SysV ABI stresses hardest — floating values arriving in xmm0..7 while the pointers arrive in the integer registers, and a loop whose accumulator lives in a register the integer corpus never made the decompiler account for. The buffers also give the differential something to compare besides a return value: matrix2_multiply writes its result through a pointer, so a recovery that computes the right numbers and stores them in the wrong cells still fails.

Every count is validated against a literal bound before it indexes anything, every loop is bounded by that count, and the fixed-size matrix entry points touch exactly four elements of buffers the harness allocates with sixteen.

tests/decompiler_fixtures/src/175_float_matrix_kernel.c source
#include <stdint.h>

/* A small floating-point numeric kernel over CALLER-OWNED buffers: a dot
 * product at both widths, and the 2x2 matrix operations built on it.
 *
 * This is the shape the SysV ABI stresses hardest — floating values arriving in
 * xmm0..7 while the pointers arrive in the integer registers, and a loop whose
 * accumulator lives in a register the integer corpus never made the decompiler
 * account for.  The buffers also give the differential something to compare
 * besides a return value: `matrix2_multiply` writes its result through a
 * pointer, so a recovery that computes the right numbers and stores them in the
 * wrong cells still fails.
 *
 * Every count is validated against a literal bound before it indexes anything,
 * every loop is bounded by that count, and the fixed-size matrix entry points
 * touch exactly four elements of buffers the harness allocates with sixteen. */

#define FP175_MAX_ELEMENTS 16
#define FP175_MATRIX_CELLS 4

static float fp175_dot_f32(const float *left, const float *right,
                           int32_t count) {
    float total = 0.0f;
    int32_t index;
    for (index = 0; index < count; ++index) {
        total += left[index] * right[index];
    }
    return total;
}

static int fp175_count_ok(int32_t count) {
    return count >= 0 && count <= FP175_MAX_ELEMENTS;
}

__attribute__((noinline)) float dot_product_f32(const float *left,
                                                const float *right,
                                                int32_t count) {
    if (left == 0 || right == 0 || !fp175_count_ok(count)) {
        return 0.0f;
    }
    return fp175_dot_f32(left, right, count);
}

/* The binary64 twin.  Same source, one width up: the element loads, the
 * multiply and the accumulator all change instruction, and a recovery that
 * types one from the other disagrees on any inexact input. */
__attribute__((noinline)) double dot_product_f64(const double *left,
                                                 const double *right,
                                                 int32_t count) {
    double total = 0.0;
    int32_t index;
    if (left == 0 || right == 0 || !fp175_count_ok(count)) {
        return 0.0;
    }
    for (index = 0; index < count; ++index) {
        total += left[index] * right[index];
    }
    return total;
}

/* Squares accumulated one width above the elements, so the total keeps digits a
 * binary32 accumulator drops. */
__attribute__((noinline)) double sum_of_squares_f32(const float *series,
                                                    int32_t count) {
    double total = 0.0;
    int32_t index;
    if (series == 0 || !fp175_count_ok(count)) {
        return 0.0;
    }
    for (index = 0; index < count; ++index) {
        total += (double)series[index] * (double)series[index];
    }
    return total;
}

/* Row-major 2x2: cells[0] cells[1] / cells[2] cells[3]. */
__attribute__((noinline)) float matrix2_determinant(const float *cells) {
    if (cells == 0) {
        return 0.0f;
    }
    return cells[0] * cells[3] - cells[1] * cells[2];
}

/* result = left * right, four dot products of length two.  `result` is a
 * distinct caller-owned buffer, so no cell is read after it is overwritten. */
__attribute__((noinline)) int32_t matrix2_multiply(const float *left,
                                                   const float *right,
                                                   float *result) {
    if (left == 0 || right == 0 || result == 0) {
        return -1;
    }
    result[0] = left[0] * right[0] + left[1] * right[2];
    result[1] = left[0] * right[1] + left[1] * right[3];
    result[2] = left[2] * right[0] + left[3] * right[2];
    result[3] = left[2] * right[1] + left[3] * right[3];
    return FP175_MATRIX_CELLS;
}

/* In-place scaling: the buffer mutation IS the observable, and the return value
 * only reports how many elements were touched. */
__attribute__((noinline)) int32_t scale_series_f32(float *series, int32_t count,
                                                   float factor) {
    int32_t index;
    if (series == 0 || !fp175_count_ok(count)) {
        return -1;
    }
    for (index = 0; index < count; ++index) {
        series[index] = series[index] * factor;
    }
    return count;
}

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 -O2

3/6
dot_product_f32 fail 57 lines
// glaurung: dot_product_f32 @ 0x1100
float dot_product_f32(const float * arg0, const float * arg1, int32_t arg2) {
    int index;
    float total;
    long ret;
    long var10;
    float var11;
    long var4;
    long var53;
    float var54;
    long var61;
    long var62;
    long var64;
    float var65;
    long var8;
    ret = 0;
    if ((arg0 != 0)) {
        if ((arg1 == 0)) {
            return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(ret) }).value;
        }
        ret = (unsigned long)((unsigned int)((arg2 - 1)));
        if (((unsigned long)(15) < (unsigned long)((unsigned long)((unsigned int)(ret))))) {
            return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(ret) }).value;
        }
        var4 = (unsigned long)((unsigned int)(arg2));
        var8 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) & 3)));
        if (((unsigned long)(3) <= (unsigned long)(((unsigned long)((unsigned int)(arg2)) - 1)))) {
            var10 = (unsigned long)((unsigned int)((var4 & -4)));
            var11 = ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
            index = 0;
            do {
                ret = ((union { unsigned int bits; float value; }){ .value = ((*(float *)(((long)arg0 + index * 4 + 0xc)) * *(float *)(((long)arg1 + index * 4 + 0xc))) + ((*(float *)(((long)arg0 + index * 4 + 0x8)) * *(float *)(((long)arg1 + index * 4 + 0x8))) + ((*(float *)(((long)arg0 + index * 4 + 0x4)) * *(float *)(((long)arg1 + index * 4 + 0x4))) + ((*(float *)(((long)arg0 + index * 4)) * *(float *)(((long)arg1 + index * 4))) + var11)))) }).bits;
                index = (index + 4);
                var11 = ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(ret) }).value;
                var53 = (unsigned long)((unsigned int)(index));
                var54 = ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(ret) }).value;
            } while ((var10 != index));
        } else {
            ret = 0;
            var53 = 0;
            var54 = ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
        }
        if ((var8 == 0)) {
            return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(ret) }).value;
        }
        var61 = (long)(((long)arg1 + (var53 * 4)));
        var62 = (long)(((long)arg0 + (var53 * 4)));
        var64 = 0;
        var65 = var54;
        do {
            ret = ((union { unsigned int bits; float value; }){ .value = (var65 + (*(float *)((var62 + var64 * 4)) * *(float *)((var61 + var64 * 4)))) }).bits;
            var64 = (var64 + 1);
            var65 = ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(ret) }).value;
        } while ((var8 != var64));
    }
    return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(ret) }).value;
}
dot_product_f64 pass 56 lines
// glaurung: dot_product_f64 @ 0x11d0
double dot_product_f64(const double * arg0, const double * arg1, int32_t arg2) {
    int index;
    double total;
    long ret;
    long var11;
    double var12;
    long var5;
    long var62;
    double var63;
    long var70;
    long var71;
    long var73;
    double var74;
    long var9;
    ret = 0;
    if (((unsigned long)(0xfffffff0) <= (unsigned long)((unsigned long)((unsigned int)((arg2 - 17)))))) {
        if ((arg0 == 0)) {
            return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
        }
        if ((arg1 == 0)) {
            return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
        }
        var5 = (unsigned long)((unsigned int)(arg2));
        var9 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) & 3)));
        if (((unsigned long)(3) <= (unsigned long)(((unsigned long)((unsigned int)(arg2)) - 1)))) {
            var11 = (unsigned long)((unsigned int)((var5 & -4)));
            var12 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
            index = 0;
            do {
                ret = ((union { unsigned long long bits; double value; }){ .value = ((*(double *)(((long)arg0 + index * 8 + 0x18)) * *(double *)(((long)arg1 + index * 8 + 0x18))) + ((*(double *)(((long)arg0 + index * 8 + 0x10)) * *(double *)(((long)arg1 + index * 8 + 0x10))) + ((*(double *)(((long)arg0 + index * 8 + 0x8)) * *(double *)(((long)arg1 + index * 8 + 0x8))) + ((*(double *)(((long)arg0 + index * 8)) * *(double *)(((long)arg1 + index * 8))) + var12)))) }).bits;
                index = (index + 4);
                var12 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
                var62 = (unsigned long)((unsigned int)(index));
                var63 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
            } while ((var11 != index));
        } else {
            ret = 0;
            var62 = 0;
            var63 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
        }
        if ((var9 == 0)) {
            return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
        }
        var70 = (long)(((long)arg1 + (var62 * 8)));
        var71 = (long)(((long)arg0 + (var62 * 8)));
        var73 = 0;
        var74 = var63;
        do {
            ret = ((union { unsigned long long bits; double value; }){ .value = (var74 + (*(double *)((var71 + var73 * 8)) * *(double *)((var70 + var73 * 8)))) }).bits;
            var73 = (var73 + 1);
            var74 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
        } while ((var9 != var73));
    }
    return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
}
matrix2_determinant pass 7 lines
// glaurung: matrix2_determinant @ 0x1360
float matrix2_determinant(const float * arg0) {
    if ((arg0 == 0)) {
        return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
    }
    return ((*(float *)(((long)arg0)) * *(float *)(((long)arg0 + 0xc))) - (*(float *)(((long)arg0 + 0x8)) * *(float *)(((long)arg0 + 0x4))));
}
matrix2_multiply fail 18 lines
// glaurung: matrix2_multiply @ 0x1390
int32_t matrix2_multiply(const float * arg0, const float * arg1, float * arg2) {
    long ret;
    ret = 0xffffffff;
    if ((arg0 != 0)) {
        if ((arg1 == 0)) {
            return ret;
        }
        if ((arg2 != 0)) {
            *(int *)(((long)arg2)) = ((*(int *)(((long)arg0)) * *(int *)(((long)arg1))) + (*(int *)(((long)arg0 + 0x4)) * *(int *)(((long)arg1 + 0x8))));
            *(int *)(((long)arg2 + 0x4)) = ((*(int *)(((long)arg0)) * *(int *)(((long)arg1 + 0x4))) + (*(int *)(((long)arg0 + 0x4)) * *(int *)(((long)arg1 + 0xc))));
            *(int *)(((long)arg2 + 0x8)) = ((*(int *)(((long)arg0 + 0x8)) * *(int *)(((long)arg1))) + (*(int *)(((long)arg0 + 0xc)) * *(int *)(((long)arg1 + 0x8))));
            *(int *)(((long)arg2 + 0xc)) = ((*(int *)(((long)arg0 + 0x8)) * *(int *)(((long)arg1 + 0x4))) + (*(int *)(((long)arg0 + 0xc)) * *(int *)(((long)arg1 + 0xc))));
            ret = 4;
        }
    }
    return ret;
}
scale_series_f32 fail 86 lines
// glaurung: scale_series_f32 @ 0x1420
int32_t scale_series_f32(float * arg0, int32_t arg1, float arg2) {
    extern long __unknown(long, ...);
    int index;
    long ret;
    long var1;
    int var19;
    int var20;
    int var21;
    int var23;
    int var24;
    int var25;
    int var27;
    int var28;
    int var29;
    int var31;
    int var32;
    int var33;
    float var39;
    long var4;
    ret = 0xffffffff;
    if ((arg0 == 0)) {
        return ret;
    }
    if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return ret;
    }
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        return 0;
    }
    var1 = (unsigned long)((unsigned int)(arg1));
    if (((unsigned long)(4) <= (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        var4 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var1)) & -4)));
        var19 = *(int *)(((long)arg0 + 0x4));
        var20 = *(int *)(((long)arg0 + 0x8));
        var21 = *(int *)(((long)arg0 + 0xc));
        /* asm: mulps */
        *(int *)(((long)arg0)) = *(int *)(((long)arg0));
        *(int *)(((long)arg0 + 0x4)) = var19;
        *(int *)(((long)arg0 + 0x8)) = var20;
        *(int *)(((long)arg0 + 0xc)) = var21;
        if ((var4 != 4)) {
            var23 = *(int *)(((long)arg0 + 0x14));
            var24 = *(int *)(((long)arg0 + 0x18));
            var25 = *(int *)(((long)arg0 + 0x1c));
            /* asm: mulps */
            *(int *)(((long)arg0 + 0x10)) = *(int *)(((long)arg0 + 0x10));
            *(int *)(((long)arg0 + 0x14)) = var23;
            *(int *)(((long)arg0 + 0x18)) = var24;
            *(int *)(((long)arg0 + 0x1c)) = var25;
            if (((unsigned long)((unsigned int)(var4)) != 8)) {
                var27 = *(int *)(((long)arg0 + 0x24));
                var28 = *(int *)(((long)arg0 + 0x28));
                var29 = *(int *)(((long)arg0 + 0x2c));
                /* asm: mulps */
                *(int *)(((long)arg0 + 0x20)) = *(int *)(((long)arg0 + 0x20));
                *(int *)(((long)arg0 + 0x24)) = var27;
                *(int *)(((long)arg0 + 0x28)) = var28;
                *(int *)(((long)arg0 + 0x2c)) = var29;
                if (((unsigned long)((unsigned int)(var4)) != 12)) {
                    var31 = *(int *)(((long)arg0 + 0x34));
                    var32 = *(int *)(((long)arg0 + 0x38));
                    var33 = *(int *)(((long)arg0 + 0x3c));
                    /* asm: mulps */
                    *(int *)(((long)arg0 + 0x30)) = *(int *)(((long)arg0 + 0x30));
                    *(int *)(((long)arg0 + 0x34)) = var31;
                    *(int *)(((long)arg0 + 0x38)) = var32;
                    *(int *)(((long)arg0 + 0x3c)) = var33;
                }
            }
        }
        if ((var4 != var1)) {
            L_1490: ;
            do {
                var39 = ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(__unknown(0)) }).value;
                *(float *)(((long)arg0 + var4 * 4)) = var39;
                index = (var4 + 1);
                var4 = (unsigned long)((unsigned int)(index));
            } while ((var1 != index));
        }
    } else {
        var4 = 0;
        goto L_1490;
    }
    return (unsigned int)(arg1);
}
sum_of_squares_f32 pass 61 lines
// glaurung: sum_of_squares_f32 @ 0x12a0
double sum_of_squares_f32(const float * arg0, int32_t arg1) {
    int index;
    double total;
    long ret;
    long var11;
    double var12;
    double var29;
    double var43;
    long var5;
    double var57;
    double var71;
    long var79;
    double var80;
    long var87;
    long var89;
    long var9;
    double var90;
    double var96;
    ret = 0;
    if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 1)))) <= (unsigned long)(15))) {
        if ((arg0 == 0)) {
            return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
        }
        var5 = (unsigned long)((unsigned int)(arg1));
        var9 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 3)));
        if (((unsigned long)(3) <= (unsigned long)(((unsigned long)((unsigned int)(arg1)) - 1)))) {
            var11 = (unsigned long)((unsigned int)((var5 & -4)));
            var12 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
            index = 0;
            do {
                var29 = (double)(*(float *)(((long)arg0 + index * 4)));
                var43 = (double)(*(float *)(((long)arg0 + index * 4 + 0x4)));
                var57 = (double)(*(float *)(((long)arg0 + index * 4 + 0x8)));
                var71 = (double)(*(float *)(((long)arg0 + index * 4 + 0xc)));
                ret = ((union { unsigned long long bits; double value; }){ .value = ((var71 * var71) + ((var57 * var57) + ((var43 * var43) + ((var29 * var29) + var12)))) }).bits;
                index = (index + 4);
                var12 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
                var79 = (unsigned long)((unsigned int)(index));
                var80 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
            } while ((var11 != index));
        } else {
            ret = 0;
            var79 = 0;
            var80 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
        }
        if ((var9 == 0)) {
            return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
        }
        var87 = (long)(((long)arg0 + (var79 * 4)));
        var89 = 0;
        var90 = var80;
        do {
            var96 = (double)(*(float *)((var87 + var89 * 4)));
            ret = ((union { unsigned long long bits; double value; }){ .value = (var90 + (var96 * var96)) }).bits;
            var89 = (var89 + 1);
            var90 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
        } while ((var9 != var89));
    }
    return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value;
}

gcc -O2

3/6
dot_product_f32 fail 29 lines
// glaurung: dot_product_f32 @ 0x1100
float dot_product_f32(const float * arg0, const float * arg1, int32_t arg2) {
    int index;
    float total;
    long ret;
    long var10;
    float var13;
    if ((arg0 == 0)) {
        return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
    }
    if ((arg1 == 0)) {
        return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
    }
    if (((unsigned long)(15) < (unsigned long)((unsigned long)((unsigned int)((arg2 - 1)))))) {
        return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
    }
    var10 = (unsigned long)((unsigned int)(arg2));
    index = 0;
    var13 = ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
    do {
        ret = *(int *)(((long)arg0 + index * 4));
        ret = (ret * *(int *)(((long)arg1 + index * 4)));
        ret = ((unsigned long)((unsigned int)(index)) + 1);
        var13 = (var13 + ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(ret) }).value);
        index = ret;
    } while ((var10 != ret));
    ret = ((union { unsigned int bits; float value; }){ .value = var13 }).bits;
    return var13;
}
dot_product_f64 fail 29 lines
// glaurung: dot_product_f64 @ 0x1150
double dot_product_f64(const double * arg0, const double * arg1, int32_t arg2) {
    int index;
    double total;
    long ret;
    long var10;
    double var13;
    if ((arg0 == 0)) {
        return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    }
    if ((arg1 == 0)) {
        return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    }
    if (((unsigned long)(15) < (unsigned long)((unsigned long)((unsigned int)((arg2 - 1)))))) {
        return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    }
    var10 = (unsigned long)((unsigned int)(arg2));
    index = 0;
    var13 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    do {
        ret = *(long *)(((long)arg0 + index * 8));
        ret = (ret * *(long *)(((long)arg1 + index * 8)));
        ret = ((unsigned long)((unsigned int)(index)) + 1);
        var13 = (var13 + ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(ret) }).value);
        index = ret;
    } while ((var10 != ret));
    ret = ((union { unsigned long long bits; double value; }){ .value = var13 }).bits;
    return var13;
}
matrix2_determinant pass 7 lines
// glaurung: matrix2_determinant @ 0x11f0
float matrix2_determinant(const float * arg0) {
    if ((arg0 == 0)) {
        return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
    }
    return ((*(float *)(((long)arg0)) * *(float *)(((long)arg0 + 0xc))) - (*(float *)(((long)arg0 + 0x4)) * *(float *)(((long)arg0 + 0x8))));
}
matrix2_multiply fail 13 lines
// glaurung: matrix2_multiply @ 0x1220
int32_t matrix2_multiply(const float * arg0, const float * arg1, float * arg2) {
    if (((arg1 != 0) && (arg2 != 0))) {
        if ((arg0 != 0)) {
            *(int *)(((long)arg2)) = ((*(int *)(((long)arg0)) * *(int *)(((long)arg1))) + (*(int *)(((long)arg0 + 0x4)) * *(int *)(((long)arg1 + 0x8))));
            *(int *)(((long)arg2 + 0x4)) = ((*(int *)(((long)arg0)) * *(int *)(((long)arg1 + 0x4))) + (*(int *)(((long)arg0 + 0x4)) * *(int *)(((long)arg1 + 0xc))));
            *(int *)(((long)arg2 + 0x8)) = ((*(int *)(((long)arg0 + 0x8)) * *(int *)(((long)arg1))) + (*(int *)(((long)arg0 + 0xc)) * *(int *)(((long)arg1 + 0x8))));
            *(int *)(((long)arg2 + 0xc)) = ((*(int *)(((long)arg0 + 0x8)) * *(int *)(((long)arg1 + 0x4))) + (*(int *)(((long)arg0 + 0xc)) * *(int *)(((long)arg1 + 0xc))));
            return 4;
        }
    }
    return 0xffffffff;
}
scale_series_f32 pass 25 lines
// glaurung: scale_series_f32 @ 0x12c0
int32_t scale_series_f32(float * arg0, int32_t arg1, float arg2) {
    int index;
    long ret;
    long var1;
    long var2;
    float var3;
    ret = (unsigned long)((unsigned int)(arg1));
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        return 0xffffffff;
    }
    if (((unsigned long)((unsigned int)(arg1)) != 0)) {
        var1 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 1))) * 4)) + 4));
        var2 = (long)arg0;
        do {
            var3 = *(float *)((var2));
            var2 = (var2 + 4);
            *(float *)((var2 - 0x4)) = (var3 * arg2);
        } while ((var2 != var1));
    }
    return ret;
}
sum_of_squares_f32 pass 26 lines
// glaurung: sum_of_squares_f32 @ 0x11a0
double sum_of_squares_f32(const float * arg0, int32_t arg1) {
    int index;
    double total;
    long var10;
    long var11;
    double var12;
    long var17;
    double var23;
    if ((arg0 == 0)) {
        return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    }
    var10 = (unsigned long)((unsigned int)((arg1 - 1)));
    if (((unsigned long)(15) < (unsigned long)((unsigned long)((unsigned int)(var10))))) {
        return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    }
    var11 = (long)((((long)arg0 + (var10 * 4)) + 4));
    var12 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    var17 = (long)arg0;
    do {
        var17 = (var17 + 4);
        var23 = (double)(*(float *)((var17 - 0x4)));
        var12 = (var12 + (var23 * var23));
    } while ((var17 != var11));
    return var12;
}

clang -O0

4/6
dot_product_f32 pass 29 lines
// glaurung: dot_product_f32 @ 0x1100
float dot_product_f32(const float * arg0, const float * arg1, int32_t arg2) {
    extern int fp175_count_ok(int);
    extern float fp175_dot_f32(int *, int *, int);
    float local_4;
    float var11;
    int var9;
    // x86-64 prologue: save rbp, frame 32 bytes
    if ((arg0 == 0)) {
        local_4 = ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
        // x86-64 epilogue: restore rbp
        return local_4;
    }
    if ((arg1 == 0)) {
        local_4 = ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
        // x86-64 epilogue: restore rbp
        return local_4;
    }
    var9 = fp175_count_ok((unsigned long)((unsigned int)(arg2)));
    if (((unsigned long)((unsigned int)(var9)) == 0)) {
        local_4 = ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
        // x86-64 epilogue: restore rbp
        return local_4;
    }
    var11 = fp175_dot_f32((int *)(arg0), (int *)(arg1), (unsigned long)((unsigned int)(arg2)));
    local_4 = var11;
    // x86-64 epilogue: restore rbp
    return local_4;
}
dot_product_f64 pass 32 lines
// glaurung: dot_product_f64 @ 0x1210
double dot_product_f64(const double * arg0, const double * arg1, int32_t arg2) {
    extern int fp175_count_ok(int);
    double total;
    int index;
    double local_8;
    int var14;
    // x86-64 prologue: save rbp, frame 48 bytes
    total = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    if ((arg0 == 0)) {
        local_8 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
        // x86-64 epilogue: restore rbp
        return local_8;
    }
    if ((arg1 == 0)) {
        local_8 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
        // x86-64 epilogue: restore rbp
        return local_8;
    }
    var14 = fp175_count_ok((unsigned long)((unsigned int)(arg2)));
    if (((unsigned long)((unsigned int)(var14)) == 0)) {
        local_8 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
        // x86-64 epilogue: restore rbp
        return local_8;
    }
    for (index = 0; (index < arg2); index++) {
        total = ((*(double *)(((long)arg0 + ((long)(index) * 8))) * *(double *)(((long)arg1 + ((long)(index) * 8)))) + total);
    }
    local_8 = total;
    // x86-64 epilogue: restore rbp
    return local_8;
}
matrix2_determinant fail 9 lines
// glaurung: matrix2_determinant @ 0x1380
float matrix2_determinant(const float * arg0) {
    // x86-64 prologue: save rbp
    if ((arg0 != 0)) {
        return ((*(float *)((long)arg0) * *(float *)(((long)arg0 + 0xc))) + ((union { unsigned int bits; float value; }){ .bits = (unsigned int)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((*(int *)(((long)arg0 + 0x4)) * *(int *)(((long)arg0 + 0x8))))) ^ -0x80000000LL)))) }).value);
    } else {
        return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
    }
}
matrix2_multiply fail 26 lines
// glaurung: matrix2_multiply @ 0x13f0
int32_t matrix2_multiply(const float * arg0, const float * arg1, float * arg2) {
    int local_4;
    // x86-64 prologue: save rbp
    if ((arg0 == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if ((arg1 == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if ((arg2 == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    *(int *)((long)arg2) = ((*(int *)((long)arg0) * *(int *)((long)arg1)) + (*(int *)(((long)arg0 + 0x4)) * *(int *)(((long)arg1 + 0x8))));
    *(int *)(((long)arg2 + 0x4)) = ((*(int *)((long)arg0) * *(int *)(((long)arg1 + 0x4))) + (*(int *)(((long)arg0 + 0x4)) * *(int *)(((long)arg1 + 0xc))));
    *(int *)(((long)arg2 + 0x8)) = ((*(int *)(((long)arg0 + 0x8)) * *(int *)((long)arg1)) + (*(int *)(((long)arg0 + 0xc)) * *(int *)(((long)arg1 + 0x8))));
    *(int *)(((long)arg2 + 0xc)) = ((*(int *)(((long)arg0 + 0x8)) * *(int *)(((long)arg1 + 0x4))) + (*(int *)(((long)arg0 + 0xc)) * *(int *)(((long)arg1 + 0xc))));
    // x86-64 epilogue: restore rbp
    return 4;
}
scale_series_f32 pass 25 lines
// glaurung: scale_series_f32 @ 0x1510
int32_t scale_series_f32(float * arg0, int32_t arg1, float arg2) {
    extern int fp175_count_ok(int);
    int index;
    int local_4;
    int var0;
    // x86-64 prologue: save rbp, frame 32 bytes
    if ((arg0 == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    var0 = fp175_count_ok((unsigned long)((unsigned int)(arg1)));
    if (((unsigned long)((unsigned int)(var0)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    for (index = 0; (index < arg1); index++) {
        arg0[(long)(index)] = (arg0[(long)(index)] * arg2);
    }
    local_4 = arg1;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}
sum_of_squares_f32 pass 27 lines
// glaurung: sum_of_squares_f32 @ 0x12d0
double sum_of_squares_f32(const float * arg0, int32_t arg1) {
    extern int fp175_count_ok(int);
    double total;
    int index;
    double local_8;
    int var14;
    // x86-64 prologue: save rbp, frame 48 bytes
    total = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    if ((arg0 == 0)) {
        local_8 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
        // x86-64 epilogue: restore rbp
        return local_8;
    }
    var14 = fp175_count_ok((unsigned long)((unsigned int)(arg1)));
    if (((unsigned long)((unsigned int)(var14)) == 0)) {
        local_8 = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
        // x86-64 epilogue: restore rbp
        return local_8;
    }
    for (index = 0; (index < arg1); index++) {
        total = (((double)(*(float *)(((long)arg0 + ((long)(index) * 4)))) * (double)(*(float *)(((long)arg0 + ((long)(index) * 4))))) + total);
    }
    local_8 = total;
    // x86-64 epilogue: restore rbp
    return local_8;
}

gcc -O0

5/6
dot_product_f32 pass 24 lines
// glaurung: dot_product_f32 @ 0x1198
float dot_product_f32(const float * arg0, const float * arg1, int32_t arg2) {
    extern int fp175_count_ok(int);
    extern float fp175_dot_f32(int *, int *, int);
    float var10;
    int var6;
    // x86-64 prologue: save rbp, frame 24 bytes
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
    }
    if ((arg1 == 0)) {
        // x86-64 epilogue: restore rbp
        return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
    }
    var6 = fp175_count_ok((unsigned long)((unsigned int)(arg2)));
    if (((unsigned long)((unsigned int)(var6)) == 0)) {
        // x86-64 epilogue: restore rbp
        return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
    }
    var10 = fp175_dot_f32((int *)(arg0), (int *)(arg1), (unsigned long)((unsigned int)(arg2)));
    // x86-64 epilogue: restore rbp
    return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)((unsigned int)(((union { unsigned int bits; float value; }){ .value = var10 }).bits)) }).value;
}
dot_product_f64 pass 27 lines
// glaurung: dot_product_f64 @ 0x11f3
double dot_product_f64(const double * arg0, const double * arg1, int32_t arg2) {
    extern int fp175_count_ok(int);
    double total;
    int index;
    int var16;
    // x86-64 prologue: save rbp, frame 40 bytes
    total = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    }
    if ((arg1 == 0)) {
        // x86-64 epilogue: restore rbp
        return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    }
    var16 = fp175_count_ok((unsigned long)((unsigned int)(arg2)));
    if (((unsigned long)((unsigned int)(var16)) == 0)) {
        // x86-64 epilogue: restore rbp
        return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    }
    for (index = 0; (index < arg2); index++) {
        total = ((*(double *)(((long)arg1 + ((long)(index) * 8))) * *(double *)(((long)arg0 + ((long)(index) * 8)))) + total);
    }
    // x86-64 epilogue: restore rbp
    return total;
}
matrix2_determinant pass 9 lines
// glaurung: matrix2_determinant @ 0x1348
float matrix2_determinant(const float * arg0) {
    // x86-64 prologue: save rbp
    if ((arg0 != 0)) {
        return ((*(float *)((arg0 + 3)) * *(float *)((long)arg0)) - (*(float *)((arg0 + 2)) * *(float *)((arg0 + 1))));
    } else {
        return ((union { unsigned int bits; float value; }){ .bits = (unsigned int)(0) }).value;
    }
}
matrix2_multiply fail 27 lines
// glaurung: matrix2_multiply @ 0x139b
int32_t matrix2_multiply(const float * arg0, const float * arg1, float * arg2) {
    long ret;
    // x86-64 prologue: save rbp
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if ((arg1 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if ((arg2 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    ret = (long)arg2;
    *(int *)((long)arg2) = ((*(int *)((arg1 + 2)) * *(int *)((arg0 + 1))) + (*(int *)((long)arg0) * *(int *)((long)arg1)));
    ret = ((*(int *)((arg1 + 3)) * *(int *)((arg0 + 1))) + (*(int *)((long)arg0) * *(int *)((arg1 + 1))));
    *(int *)((ret)) = ret;
    ret = ((*(int *)((arg1 + 2)) * *(int *)((arg0 + 3))) + (*(int *)((arg0 + 2)) * *(int *)((long)arg1)));
    *(int *)((ret)) = ret;
    ret = ((*(int *)((arg1 + 3)) * *(int *)((arg0 + 3))) + (*(int *)((arg0 + 2)) * *(int *)((arg1 + 1))));
    *(int *)((ret)) = ret;
    // x86-64 epilogue: restore rbp
    return 4;
}
scale_series_f32 pass 24 lines
// glaurung: scale_series_f32 @ 0x14e1
int32_t scale_series_f32(float * arg0, int32_t arg1, float arg2) {
    extern int fp175_count_ok(int);
    int index;
    float local_20;
    int var1;
    // x86-64 prologue: save rbp, frame 32 bytes
    local_20 = arg2;
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    var1 = fp175_count_ok((unsigned long)((unsigned int)(arg1)));
    if (((unsigned long)((unsigned int)(var1)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    for (index = 0; (index < arg1); index++) {
        arg2 = (*(float *)(((long)arg0 + ((long)(index) * 4))) * local_20);
        arg0[(long)(index)] = arg2;
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(arg1);
}
sum_of_squares_f32 pass 23 lines
// glaurung: sum_of_squares_f32 @ 0x129d
double sum_of_squares_f32(const float * arg0, int32_t arg1) {
    extern int fp175_count_ok(int);
    double total;
    int index;
    int var16;
    // x86-64 prologue: save rbp, frame 32 bytes
    total = ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    if ((arg0 == 0)) {
        // x86-64 epilogue: restore rbp
        return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    }
    var16 = fp175_count_ok((unsigned long)((unsigned int)(arg1)));
    if (((unsigned long)((unsigned int)(var16)) == 0)) {
        // x86-64 epilogue: restore rbp
        return ((union { unsigned long long bits; double value; }){ .bits = (unsigned long long)(0) }).value;
    }
    for (index = 0; (index < arg1); index++) {
        total = (((double)(*(float *)(((long)arg0 + (0 + ((long)((int)((unsigned long)((unsigned int)(index)))) * 4))))) * (double)(*(float *)(((long)arg0 + (0 + ((long)((int)((unsigned long)((unsigned int)(index)))) * 4)))))) + total);
    }
    // x86-64 epilogue: restore rbp
    return total;
}

← 213 fixtures