Fixture 58

rational

C · 2 functions · 4 lanes · 5 of 8 function-lanes behave identically

2 of 4 lanes have a function that returns a different result after decompilation: gcc-O0 (0/2), clang-O2 (1/2).

Exact rational arithmetic in lowest terms. Every operation normalises by the greatest common divisor and moves the sign to the numerator, so the recovered code needs both the division idiom and the sign fixup.

tests/decompiler_fixtures/src/58_rational.c source
#include <stdint.h>

/* Exact rational arithmetic in lowest terms.  Every operation normalises by
 * the greatest common divisor and moves the sign to the numerator, so the
 * recovered code needs both the division idiom and the sign fixup. */

static int32_t rational_gcd(int32_t a, int32_t b) {
    int32_t guard;
    if (a < 0) {
        a = -a;
    }
    if (b < 0) {
        b = -b;
    }
    for (guard = 0; guard < 64 && b != 0; ++guard) {
        int32_t remainder = a % b;
        a = b;
        b = remainder;
    }
    return (a == 0) ? 1 : a;
}

__attribute__((noinline)) int32_t
rational_add(int32_t left_num, int32_t left_den, int32_t right_num,
             int32_t right_den, int32_t *out_num, int32_t *out_den) {
    int32_t numerator;
    int32_t denominator;
    int32_t divisor;
    if (out_num == 0 || out_den == 0 || left_den == 0 || right_den == 0 ||
        left_num < -10000 || left_num > 10000 || right_num < -10000 ||
        right_num > 10000 || left_den < -10000 || left_den > 10000 ||
        right_den < -10000 || right_den > 10000) {
        return -1;
    }
    numerator = left_num * right_den + right_num * left_den;
    denominator = left_den * right_den;
    if (denominator < 0) {
        numerator = -numerator;
        denominator = -denominator;
    }
    divisor = rational_gcd(numerator, denominator);
    *out_num = numerator / divisor;
    *out_den = denominator / divisor;
    return 1;
}

__attribute__((noinline)) int32_t
rational_compare(int32_t left_num, int32_t left_den, int32_t right_num,
                 int32_t right_den) {
    int64_t left;
    int64_t right;
    if (left_den == 0 || right_den == 0 || left_num < -10000 ||
        left_num > 10000 || right_num < -10000 || right_num > 10000 ||
        left_den < -10000 || left_den > 10000 || right_den < -10000 ||
        right_den > 10000) {
        return -2;
    }
    if (left_den < 0) {
        left_num = -left_num;
        left_den = -left_den;
    }
    if (right_den < 0) {
        right_num = -right_num;
        right_den = -right_den;
    }
    left = (int64_t)left_num * (int64_t)right_den;
    right = (int64_t)right_num * (int64_t)left_den;
    if (left < right) {
        return -1;
    }
    if (left > right) {
        return 1;
    }
    return 0;
}

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

0/2
rational_add fail 69 lines
// glaurung: rational_add @ 0x115a
int32_t rational_add(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t * arg4, int32_t * arg5) {
    extern int rational_gcd(int, int);
    int numerator;
    int denominator;
    int divisor;
    int var14;
    // x86-64 prologue: save rbp, frame 48 bytes
    if ((arg4 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if ((arg5 == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((unsigned long)((unsigned int)(arg3)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((long)(arg0) < -0x2710LL)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg0)) == 0x2710) | ((long)(arg0) < 0x2710)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((long)(arg2) < -0x2710LL)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 0x2710) | ((long)(arg2) < 0x2710)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((long)(arg1) < -0x2710LL)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 0x2710) | ((long)(arg1) < 0x2710)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((long)(arg3) < -0x2710LL)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    if (((((unsigned long)((unsigned int)(arg3)) == 0x2710) | ((long)(arg3) < 0x2710)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xffffffff;
    }
    numerator = ((unsigned int)(((unsigned long)((unsigned int)(arg2)) * arg1)) + (unsigned int)(((unsigned long)((unsigned int)(arg0)) * arg3)));
    denominator = ((unsigned int)(arg1) * arg3);
    if (((long)(denominator) < 0)) {
        /* asm: neg */
        /* asm: neg */
    }
    var14 = rational_gcd((unsigned long)((unsigned int)(numerator)), (unsigned long)((unsigned int)(denominator)));
    divisor = var14;
    *(int *)((long)arg4) = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(numerator))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(numerator)))) / (int)(divisor)));
    *(int *)((long)arg5) = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(denominator))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(denominator)))) / (int)(divisor)));
    // x86-64 epilogue: restore rbp
    return 1;
}
rational_compare fail 65 lines
// glaurung: rational_compare @ 0x1245
int32_t rational_compare(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) {
    long left;
    long right;
    // x86-64 prologue: save rbp
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xfffffffe;
    }
    if (((unsigned long)((unsigned int)(arg3)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xfffffffe;
    }
    if (((long)(arg0) < -0x2710LL)) {
        // x86-64 epilogue: restore rbp
        return 0xfffffffe;
    }
    if (((((unsigned long)((unsigned int)(arg0)) == 0x2710) | ((long)(arg0) < 0x2710)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xfffffffe;
    }
    if (((long)(arg2) < -0x2710LL)) {
        // x86-64 epilogue: restore rbp
        return 0xfffffffe;
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 0x2710) | ((long)(arg2) < 0x2710)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xfffffffe;
    }
    if (((long)(arg1) < -0x2710LL)) {
        // x86-64 epilogue: restore rbp
        return 0xfffffffe;
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 0x2710) | ((long)(arg1) < 0x2710)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xfffffffe;
    }
    if (((long)(arg3) < -0x2710LL)) {
        // x86-64 epilogue: restore rbp
        return 0xfffffffe;
    }
    if (((((unsigned long)((unsigned int)(arg3)) == 0x2710) | ((long)(arg3) < 0x2710)) == 0)) {
        // x86-64 epilogue: restore rbp
        return 0xfffffffe;
    }
    if (((long)(arg1) < 0)) {
        /* asm: neg */
        /* asm: neg */
    }
    if (((long)(arg3) < 0)) {
        /* asm: neg */
        /* asm: neg */
    }
    left = ((long)(arg3) * (long)(arg0));
    right = ((long)(arg1) * (long)(arg2));
    if ((right <= left)) {
        if ((left <= right)) {
            return 0;
        } else {
            return 1;
        }
    } else {
        return 0xffffffff;
    }
}

clang -O2

1/2
rational_add pass 76 lines
// glaurung: rational_add @ 0x1100
int32_t rational_add(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t * arg4, int32_t * arg5) {
    int numerator;
    int divisor;
    int denominator;
    int guard;
    long t147;
    long t149;
    int var1;
    long var12;
    int var16;
    int var20;
    long var21;
    long var25;
    long var26;
    long var27;
    long var30;
    int var9;
    var1 = 0xffffffff;
    if (((unsigned long)((unsigned long)((unsigned int)((arg3 - 0x2711)))) < (unsigned long)(0xffffb1df))) {
        return (unsigned int)(var1);
    }
    if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 0x2711)))) < (unsigned long)(0xffffb1df))) {
        return (unsigned int)(var1);
    }
    if (((unsigned long)((unsigned long)((unsigned int)((arg2 - 0x2711)))) < (unsigned long)(0xffffb1df))) {
        return (unsigned int)(var1);
    }
    if (((unsigned long)((unsigned long)((unsigned int)((arg0 - 0x2711)))) < (unsigned long)(0xffffb1df))) {
        return (unsigned int)(var1);
    }
    if (((unsigned long)((unsigned int)(arg3)) == 0)) {
        return (unsigned int)(var1);
    }
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        return (unsigned int)(var1);
    }
    if ((arg4 == 0)) {
        return (unsigned int)(var1);
    }
    if ((arg5 == 0)) {
        return (unsigned int)(var1);
    }
    var9 = ((unsigned int)((arg2 * arg1)) + (unsigned int)((arg0 * arg3)));
    var12 = (unsigned long)((unsigned int)((arg3 * arg1)));
    t147 = (-(unsigned long)((unsigned int)(var9)));
    var16 = ((0 <= (long)((int)(t147))) ? t147 : (unsigned long)((unsigned int)(var9)));
    numerator = ((0 <= (long)((int)(var12))) ? (unsigned long)((unsigned int)(var9)) : t147);
    t149 = (-(unsigned long)((unsigned int)(var12)));
    var20 = (((long)((int)(t149)) < 0) ? var12 : t149);
    if (((unsigned long)((unsigned int)(var20)) == 0)) {
        var21 = (unsigned long)((unsigned int)(var16));
    } else {
        var25 = (unsigned long)((unsigned int)(var16));
        var26 = 0;
        var27 = (unsigned long)((unsigned int)(var20));
        while (1) {
            var21 = (unsigned long)((unsigned int)(var27));
            var30 = ((int)((((long long)(int)((((unsigned long)((long)((int)(var25))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(var25)) % (int)((unsigned long)((unsigned int)(var27)))));
            if (((unsigned long)(62) < (unsigned long)((unsigned long)((unsigned int)(var26))))) {
                break;
            }
            var26 = (unsigned long)((unsigned int)((var26 + 1)));
            var25 = (unsigned long)((unsigned int)(var21));
            var27 = var30;
            if (((unsigned long)((unsigned int)(var30)) == 0)) {
                break;
            }
        }
    }
    var1 = 1;
    divisor = (((unsigned long)((unsigned int)(var21)) == 0) ? 1 : var21);
    *(int *)(((long)arg4)) = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(numerator))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(numerator)))) / (int)(divisor)));
    *(int *)(((long)arg5)) = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(var20))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(var20)))) / (int)(divisor)));
    return 1;
}
rational_compare fail 41 lines
// glaurung: rational_compare @ 0x11d0
int32_t rational_compare(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) {
    long left;
    long right;
    long of_15;
    long ret;
    long sf_15;
    long t145;
    long t149;
    long zf_15;
    ret = 0xfffffffe;
    if (((unsigned long)(0xffffb1df) <= (unsigned long)((unsigned long)((unsigned int)((arg3 - 0x2711)))))) {
        if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 0x2711)))) < (unsigned long)(0xffffb1df))) {
            return ret;
        }
        if (((unsigned long)((unsigned long)((unsigned int)((arg2 - 0x2711)))) < (unsigned long)(0xffffb1df))) {
            return ret;
        }
        if (((unsigned long)((unsigned long)((unsigned int)((arg0 - 0x2711)))) < (unsigned long)(0xffffb1df))) {
            return ret;
        }
        if (((unsigned long)((unsigned int)(arg1)) == 0)) {
            return ret;
        }
        if (((unsigned long)((unsigned int)(arg3)) == 0)) {
            return ret;
        }
        t145 = (-(unsigned long)((unsigned int)(arg1)));
        t149 = (-(unsigned long)((unsigned int)(arg3)));
        left = ((((long)((int)(t149)) < 0) ? arg3 : t149) * (long)((int)(((0 <= (long)(arg1)) ? arg0 : (-(unsigned long)((unsigned int)(arg0)))))));
        right = ((((long)((int)(t145)) < 0) ? arg1 : t145) * (long)((int)(((0 <= (long)(arg3)) ? arg2 : (-(unsigned long)((unsigned int)(arg2)))))));
        ret = 0xffffffff;
        zf_15 = (left == right);
        sf_15 = ((left - right) < 0);
        of_15 = ((left < right) ^ ((left - right) < 0));
        if ((right <= left)) {
            ret = ((zf_15 | (sf_15 ^ of_15)) == 0);
        }
    }
    return ret;
}

clang -O0

2/2
rational_add pass 82 lines
// glaurung: rational_add @ 0x1100
int32_t rational_add(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t * arg4, int32_t * arg5) {
    extern int rational_gcd(int, int);
    int numerator;
    int denominator;
    int divisor;
    int local_4;
    int var19;
    // x86-64 prologue: save rbp, frame 64 bytes
    if ((arg4 == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if ((arg5 == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((unsigned long)((unsigned int)(arg3)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg0) < -0x2710LL)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg0)) == 0x2710) | ((long)(arg0) < 0x2710)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg2) < -0x2710LL)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 0x2710) | ((long)(arg2) < 0x2710)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg1) < -0x2710LL)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 0x2710) | ((long)(arg1) < 0x2710)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg3) < -0x2710LL)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg3)) == 0x2710) | ((long)(arg3) < 0x2710)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    numerator = ((unsigned int)(((unsigned long)((unsigned int)(arg0)) * arg3)) + (unsigned int)(((unsigned long)((unsigned int)(arg2)) * arg1)));
    denominator = ((unsigned int)(arg1) * arg3);
    if (((long)(denominator) < 0)) {
        numerator = (0 - numerator);
        denominator = (0 - denominator);
    }
    var19 = rational_gcd((unsigned long)((unsigned int)(numerator)), (unsigned long)((unsigned int)(denominator)));
    divisor = var19;
    *(int *)((long)arg4) = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(numerator))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(numerator)))) / (int)(divisor)));
    *(int *)((long)arg5) = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(denominator))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(denominator)))) / (int)(divisor)));
    // x86-64 epilogue: restore rbp
    return 1;
}
rational_compare pass 76 lines
// glaurung: rational_compare @ 0x12e0
int32_t rational_compare(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) {
    long left;
    long right;
    int local_4;
    // x86-64 prologue: save rbp
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        local_4 = -2;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((unsigned long)((unsigned int)(arg3)) == 0)) {
        local_4 = -2;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg0) < -0x2710LL)) {
        local_4 = -2;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg0)) == 0x2710) | ((long)(arg0) < 0x2710)) == 0)) {
        local_4 = -2;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg2) < -0x2710LL)) {
        local_4 = -2;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg2)) == 0x2710) | ((long)(arg2) < 0x2710)) == 0)) {
        local_4 = -2;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg1) < -0x2710LL)) {
        local_4 = -2;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 0x2710) | ((long)(arg1) < 0x2710)) == 0)) {
        local_4 = -2;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg3) < -0x2710LL)) {
        local_4 = -2;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg3)) == 0x2710) | ((long)(arg3) < 0x2710)) == 0)) {
        local_4 = -2;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg1) < 0)) {
        arg0 = (0 - arg0);
        arg1 = (0 - arg1);
    }
    if (((long)(arg3) < 0)) {
        arg2 = (0 - arg2);
        arg3 = (0 - arg3);
    }
    left = ((long)(arg0) * (long)(arg3));
    right = ((long)(arg2) * (long)(arg1));
    if ((right <= left)) {
        if ((left <= right)) {
            return 0;
        } else {
            return 1;
        }
    } else {
        return (unsigned int)(-1);
    }
}

gcc -O2

2/2
rational_add pass 102 lines
// glaurung: rational_add @ 0x1100
int32_t rational_add(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3, int32_t * arg4, int32_t * arg5) {
    int denominator;
    int numerator;
    int guard;
    int remainder;
    long t147;
    long var0;
    int var1;
    int var12;
    int var16;
    long var17;
    long var18;
    long var22;
    long var23;
    long var25;
    int var26;
    long var30;
    long var39;
    long zf_14;
    var0 = (unsigned long)((unsigned int)(arg1));
    if ((arg4 == 0)) {
        var1 = 0xffffffff;
        return 0xffffffff;
    }
    if ((arg5 == 0)) {
        var1 = 0xffffffff;
        return 0xffffffff;
    }
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        var1 = 0xffffffff;
        return 0xffffffff;
    }
    if (((unsigned long)((unsigned int)(arg3)) == 0)) {
        var1 = 0xffffffff;
        return 0xffffffff;
    }
    var1 = 0xffffffff;
    if (((unsigned long)(0x4e20) < (unsigned long)((unsigned long)((unsigned int)((arg0 + 0x2710)))))) {
        return (unsigned int)(var1);
    }
    if (((unsigned long)(0x4e20) < (unsigned long)((unsigned long)((unsigned int)((arg2 + 0x2710)))))) {
        return (unsigned int)(var1);
    }
    if (((unsigned long)(0x4e20) < (unsigned long)((unsigned long)((unsigned int)((var0 + 0x2710)))))) {
        return (unsigned int)(var1);
    }
    if (((unsigned long)(0x4e20) < (unsigned long)((unsigned long)((unsigned int)((arg3 + 0x2710)))))) {
        return (unsigned int)(var1);
    }
    denominator = (unsigned long)((unsigned int)((arg3 * var0)));
    var12 = ((unsigned int)((arg0 * arg3)) + (unsigned int)((arg2 * var0)));
    numerator = (unsigned long)((unsigned int)(var12));
    t147 = (-(unsigned long)((unsigned int)(var12)));
    var16 = (((long)((int)(t147)) < 0) ? (unsigned long)((unsigned int)(var12)) : t147);
    zf_14 = ((unsigned long)((unsigned int)(denominator)) == 0);
    if (((long)(denominator) < 0)) {
        var17 = (-(unsigned long)((unsigned int)(numerator)));
        var18 = (-(unsigned long)((unsigned int)(denominator)));
        L_1186: ;
        var22 = (unsigned long)((unsigned int)(var16));
        var23 = (unsigned long)((unsigned int)(var18));
        guard = 0;
        while (1) {
            var25 = (unsigned long)((unsigned int)(var23));
            var26 = (guard + 1);
            guard = (unsigned long)((unsigned int)(var26));
            remainder = ((int)((((long long)(int)((((unsigned long)((long)((int)(var22))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)(var22)) % (int)((unsigned long)((unsigned int)(var23)))));
            var30 = (unsigned long)((unsigned int)(var23));
            if (((((unsigned long)((unsigned int)(var26)) == 63) | ((long)((int)(var26)) < 63)) == 0)) {
                break;
            }
            var22 = var30;
            var23 = (unsigned long)((unsigned int)(remainder));
            if (((unsigned long)((unsigned int)(remainder)) == 0)) {
                break;
            }
        }
        L_11a6: ;
        numerator = (unsigned long)((unsigned int)(((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(var17))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(var17)))) / (int)(var25)))));
        var39 = ((int)((((long long)(int)((((unsigned long)((long)((int)((unsigned long)((unsigned int)(var18))))) >> 32) & 0xffffffff)) * (((long long)1) << 32)) + (unsigned int)((unsigned long)((unsigned int)(var18)))) / (int)(var25)));
    } else {
        var18 = (unsigned long)((unsigned int)(denominator));
        var17 = (unsigned long)((unsigned int)(numerator));
        if (zf_14) {
            if (((unsigned long)((unsigned int)(numerator)) != 0)) {
                var25 = (unsigned long)((unsigned int)(var16));
                var18 = (unsigned long)((unsigned int)(denominator));
                var17 = (unsigned long)((unsigned int)(numerator));
                goto L_11a6;
            } else {
                var39 = 0;
            }
        } else {
            goto L_1186;
        }
    }
    *(int *)(((long)arg4)) = numerator;
    *(int *)(((long)arg5)) = var39;
    var1 = 1;
    return 1;
}
rational_compare pass 45 lines
// glaurung: rational_compare @ 0x11f0
int32_t rational_compare(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3) {
    long left;
    long right;
    long var0;
    int var5;
    int var6;
    int var7;
    var0 = (unsigned long)((unsigned int)(arg1));
    if (((unsigned long)((unsigned int)(arg1)) == 0)) {
        return 0xfffffffe;
    }
    if (((unsigned long)((unsigned int)(arg3)) == 0)) {
        return 0xfffffffe;
    }
    if (((unsigned long)(0x4e20) < (unsigned long)((unsigned long)((unsigned int)((arg0 + 0x2710)))))) {
        return 0xfffffffe;
    }
    if (((unsigned long)(0x4e20) < (unsigned long)((unsigned long)((unsigned int)((arg2 + 0x2710)))))) {
        return 0xfffffffe;
    }
    if (((unsigned long)(0x4e20) < (unsigned long)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) + 0x2710)))))) {
        return 0xfffffffe;
    }
    if (((unsigned long)(0x4e20) < (unsigned long)((unsigned long)((unsigned int)((arg3 + 0x2710)))))) {
        return 0xfffffffe;
    }
    var5 = arg0;
    if (((long)(arg1) < 0)) {
        var5 = (-arg0);
        var0 = (-var0);
    }
    var6 = arg3;
    var7 = arg2;
    if (((long)(arg3) < 0)) {
        var7 = (-arg2);
        var6 = (-arg3);
    }
    left = ((long)((int)(var5)) * (long)((int)(var6)));
    right = ((long)((int)(var7)) * (long)((int)(var0)));
    if ((left < right)) {
        return 0xffffffff;
    }
    return (right < left);
}

← 213 fixtures