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.
#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/1newton_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/1newton_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/1newton_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/1newton_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;
}