Fixture 27

newton raphson

C · 1 functions · 4 lanes · 4 of 4 function-lanes behave identically

All 4 lanes recompile and return the same results as the original.

tests/decompiler_fixtures/src/27_newton_raphson.c source
#include <stdint.h>

__attribute__((noinline)) uint32_t newton_isqrt(uint32_t value) {
    uint32_t estimate;
    int32_t iteration;
    if (value < 2u) {
        return value;
    }
    estimate = value / 2u + 1u;
    for (iteration = 0; iteration < 32; ++iteration) {
        uint32_t next = (estimate + value / estimate) / 2u;
        if (next >= estimate) {
            return estimate;
        }
        estimate = next;
    }
    return estimate;
}

Recovered C

Generated by glaurung decompile --style decbench at b47f6b43. baseline.json records the result after recompiling the C and calling it beside the original with seeded inputs.

clang -O0

1/1
newton_isqrt pass 31 lines
// glaurung: newton_isqrt @ 0x1100
uint32_t newton_isqrt(uint32_t arg0) {
    unsigned int estimate;
    int iteration;
    unsigned int next;
    int local_18;
    int local_4;
    if (((unsigned long)(arg0) < (unsigned long)(2))) {
        local_4 = arg0;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    estimate = ((unsigned int)(((unsigned int)(arg0) >> 1)) + 1);
    iteration = 0;
    L_112f: ;
    if (((long)(iteration) < 32)) {
        local_18 = estimate;
        next = ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(local_18)) + (unsigned long)((unsigned int)(((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)(arg0)) / (unsigned int)(estimate))))))))) >> 1);
        if (((unsigned long)(estimate) <= (unsigned long)(next))) {
            local_4 = estimate;
            // x86-64 epilogue: restore rbp
            return (unsigned int)(local_4);
        }
        estimate = next;
        iteration = ((unsigned int)(iteration) + 1);
        goto L_112f;
    }
    local_4 = estimate;
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
}

clang -O2

1/1
newton_isqrt pass 37 lines
// glaurung: newton_isqrt @ 0x1100
uint32_t newton_isqrt(uint32_t arg0) {
    unsigned int next;
    unsigned int estimate;
    long ret;
    long var0;
    long var31;
    int var32;
    long var7;
    long var8;
    var0 = (unsigned long)(arg0);
    if (((unsigned long)(arg0) < (unsigned long)(2))) {
        return (unsigned int)(var0);
    }
    var7 = 32;
    var8 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)(arg0) >> 1))) + 1)));
    while (1) {
        next = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)((unsigned long)((unsigned int)(var0)))) / (unsigned int)(var8)))))) + var8))) >> 1)));
        ret = (unsigned long)((unsigned int)(var8));
        if (((unsigned long)((unsigned long)((unsigned int)(var8))) <= (unsigned long)(next))) {
            break;
        }
        var31 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)((unsigned long)((unsigned int)(var0)))) / (unsigned int)(next)))))) + next))) >> 1)));
        ret = (unsigned long)(next);
        if (((unsigned long)(next) <= (unsigned long)((unsigned long)((unsigned int)(var31))))) {
            break;
        }
        ret = (unsigned long)((unsigned int)(var31));
        var32 = (var7 - 2);
        var7 = (unsigned long)((unsigned int)(var32));
        var8 = var31;
        if (((unsigned long)((unsigned int)(var32)) == 0)) {
            break;
        }
    }
    return ret;
}

gcc -O0

1/1
newton_isqrt pass 27 lines
// glaurung: newton_isqrt @ 0x10f9
uint32_t newton_isqrt(uint32_t arg0) {
    unsigned int estimate;
    int iteration;
    unsigned int next;
    if (((unsigned long)(arg0) <= (unsigned long)(1))) {
        // x86-64 epilogue: restore rbp
        return arg0;
    }
    estimate = ((unsigned int)(((unsigned int)(arg0) >> 1)) + 1);
    iteration = 0;
    goto L_1151;
    L_1123: ;
    next = ((unsigned long)((unsigned int)((estimate + (unsigned long)((unsigned int)(((unsigned int)(((((unsigned long long)(unsigned int)(0) << 32) | (unsigned int)(arg0)) / (unsigned int)(estimate))))))))) >> 1);
    if (((unsigned long)(estimate) <= (unsigned long)(next))) {
        // x86-64 epilogue: restore rbp
        return estimate;
    }
    estimate = next;
    iteration = (iteration + 1);
    L_1151: ;
    if ((((unsigned long)((unsigned int)(iteration)) == 31) | ((long)(iteration) < 31))) {
        goto L_1123;
    }
    // x86-64 epilogue: restore rbp
    return estimate;
}

gcc -O2

1/1
newton_isqrt pass 28 lines
// glaurung: newton_isqrt @ 0x1100
uint32_t newton_isqrt(uint32_t arg0) {
    unsigned int estimate;
    unsigned int next;
    int iteration;
    int var21;
    long var3;
    long var9;
    estimate = arg0;
    if (((unsigned long)(1) < (unsigned long)(arg0))) {
        var3 = 32;
        var9 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)(arg0) >> 1))) + 1)));
        while (1) {
            estimate = (unsigned long)((unsigned int)(var9));
            next = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)(arg0)) / (unsigned int)((unsigned long)((unsigned int)(var9)))))) + (unsigned long)((unsigned int)(var9))))) >> 1)));
            if (((unsigned long)((unsigned long)((unsigned int)(var9))) <= (unsigned long)(next))) {
                break;
            }
            var21 = (var3 - 1);
            var3 = (unsigned long)((unsigned int)(var21));
            var9 = (unsigned long)(next);
            if (((unsigned long)((unsigned int)(var21)) == 0)) {
                return next;
            }
        }
    }
    return estimate;
}

← 213 fixtures