Fixture 30
finite difference
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 heat_step_1d(int32_t *destination,
const int32_t *source,
int32_t n) {
uint32_t checksum = 0;
int32_t i;
if (destination == 0 || source == 0 || n < 0 || n > 16) {
return 0;
}
if (n > 0) {
destination[0] = source[0];
}
for (i = 1; i + 1 < n; ++i) {
int64_t weighted = (int64_t)source[i - 1] +
2 * (int64_t)source[i] + source[i + 1];
destination[i] = (int32_t)(weighted / 4);
}
if (n > 1) {
destination[n - 1] = source[n - 1];
}
for (i = 0; i < n; ++i) {
checksum = checksum * 33u + (uint32_t)destination[i];
}
return checksum;
} 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/1heat_step_1d pass 41 lines
// glaurung: heat_step_1d @ 0x1100
uint32_t heat_step_1d(int32_t * arg0, const int32_t * arg1, int32_t arg2) {
unsigned int checksum;
int i;
long weighted;
int local_4;
// x86-64 prologue: save rbp
checksum = 0;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if ((arg1 == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if (((long)(arg2) < 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if (((((unsigned long)((unsigned int)(arg2)) == 16) | ((long)(arg2) < 16)) == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if (((((unsigned long)((unsigned int)(arg2)) == 0) | ((long)(arg2) < 0)) == 0)) {
*(int *)((long)arg0) = *(int *)((long)arg1);
}
for (i = 1; ((long)((int)(((unsigned long)((unsigned int)(i)) + 1))) < (long)(arg2)); i++) {
weighted = (((long)((int)(arg1[(long)((int)(((unsigned long)((unsigned int)(i)) - 1)))])) + ((long)((int)(arg1[(long)(i)])) << 1)) + (long)((int)(arg1[(long)((int)(((unsigned long)((unsigned int)(i)) + 1)))])));
arg0[(long)(i)] = ((long)((((__int128)(long)(((long)(weighted) >> 63)) * (((__int128)1) << 64)) + (unsigned long)(weighted)) / (long)(4)));
}
if (((((unsigned long)((unsigned int)(arg2)) == 1) | ((long)(arg2) < 1)) == 0)) {
arg0[(long)((int)(((unsigned long)((unsigned int)(arg2)) - 1)))] = arg1[(long)((int)(((unsigned long)((unsigned int)(arg2)) - 1)))];
}
for (i = 0; (i < arg2); i++) {
checksum = ((checksum * 33) + arg0[(long)(i)]);
}
local_4 = checksum;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
1/1heat_step_1d pass 100 lines
// glaurung: heat_step_1d @ 0x1100
uint32_t heat_step_1d(int32_t * arg0, const int32_t * arg1, int32_t arg2) {
long weighted;
int i;
unsigned int checksum;
long ret;
long var15;
long var16;
long var2;
long var20;
long var22;
long var27;
int var33;
long var4;
int var40;
int var47;
long var5;
int var54;
long var55;
long var56;
long var62;
long var64;
long var66;
int var71;
long var73;
long var8;
long var9;
var2 = 0;
ret = 0;
if (((unsigned long)((unsigned long)((unsigned int)((arg2 - 17)))) < (unsigned long)(0xfffffff0))) {
return ret;
}
ret = 0;
if ((arg0 == 0)) {
return ret;
}
ret = 0;
if ((arg1 == 0)) {
return ret;
}
*(int *)(((long)arg0)) = *(int *)(((long)arg1));
if (((unsigned long)(3) <= (unsigned long)((unsigned long)((unsigned int)(arg2))))) {
var4 = (unsigned long)((unsigned int)((arg2 - 1)));
var5 = 1;
do {
var8 = ((long)((int)(*(int *)(((long)arg1 + var5 * 4 - 0x4)))) + ((long)((int)(*(int *)(((long)arg1 + var5 * 4)))) * 2));
var9 = (long)((int)(*(int *)(((long)arg1 + var5 * 4 + 0x4))));
weighted = (var8 + var9);
*(int *)(((long)arg0 + var5 * 4)) = ((unsigned long)(((0 <= weighted) ? weighted : ((var9 + var8) + 3))) >> 2);
var15 = (var5 + 1);
var5 = var15;
} while ((var4 != var15));
}
if (((long)(arg2) < 2)) {
ret = var2;
if (((unsigned long)((unsigned int)(arg2)) != 1)) {
return ret;
}
L_118e: ;
var16 = (unsigned long)((unsigned int)(arg2));
var20 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) & 3)));
if (((unsigned long)(3) <= (unsigned long)(((unsigned long)((unsigned int)(arg2)) - 1)))) {
var22 = (unsigned long)((unsigned int)((var16 & -4)));
i = 0;
var27 = 0;
do {
var33 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var27)) << 5))) + var27)) + *(int *)(((long)arg0 + i * 4)));
var40 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var33)) << 5))) + (unsigned long)((unsigned int)(var33)))) + *(int *)(((long)arg0 + i * 4 + 0x4)));
var47 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var40)) << 5))) + (unsigned long)((unsigned int)(var40)))) + *(int *)(((long)arg0 + i * 4 + 0x8)));
var54 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var47)) << 5))) + (unsigned long)((unsigned int)(var47)))) + *(int *)(((long)arg0 + i * 4 + 0xc)));
var55 = (unsigned long)((unsigned int)(var54));
i = (i + 4);
var27 = (unsigned long)((unsigned int)(var54));
var56 = (unsigned long)((unsigned int)(i));
} while ((var22 != i));
} else {
var56 = 0;
var55 = 0;
}
ret = (unsigned long)((unsigned int)(var55));
if ((var20 == 0)) {
return ret;
}
var62 = (long)(((long)arg0 + (var56 * 4)));
var64 = 0;
var66 = (unsigned long)((unsigned int)(var55));
do {
var71 = ((unsigned int)(((unsigned long)((unsigned int)((var66 << 5))) + var55)) + *(int *)((var62 + var64 * 4)));
var66 = (unsigned long)((unsigned int)(var71));
var64 = (var64 + 1);
var55 = (unsigned long)((unsigned int)(var71));
ret = (unsigned long)((unsigned int)(var71));
} while ((var20 != var64));
} else {
var73 = (unsigned long)((unsigned int)((arg2 - 1)));
*(int *)(((long)arg0 + var73 * 4)) = *(int *)(((long)arg1 + var73 * 4));
goto L_118e;
}
return ret;
} gcc -O0
1/1heat_step_1d pass 48 lines
// glaurung: heat_step_1d @ 0x10f9
uint32_t heat_step_1d(int32_t * arg0, const int32_t * arg1, int32_t arg2) {
unsigned int checksum;
int i;
long weighted;
long var20;
int var4;
// x86-64 prologue: save rbp
checksum = 0;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if ((arg1 == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if (((long)(arg2) < 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if (((((unsigned long)((unsigned int)(arg2)) == 16) | ((long)(arg2) < 16)) == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if (((((unsigned long)((unsigned int)(arg2)) == 0) | ((long)(arg2) < 0)) == 0)) {
*(int *)((long)arg0) = *(int *)((long)arg1);
}
i = 1;
while (1) {
var4 = ((unsigned int)(i) + 1);
if (((((unsigned int)(arg2) == (unsigned int)(var4)) | (arg2 < var4)) != 0)) {
break;
}
var20 = (long)((int)(arg1[(long)(i)]));
weighted = ((long)((int)(arg1[((long)(i) + 1)])) + ((long)((int)(*(int *)(((long)arg1 + (((long)(i) << 2) - 4))))) + (var20 + var20)));
arg0[(long)(i)] = ((long)(((weighted < 0) ? (weighted + 3) : weighted)) >> 2);
i = (i + 1);
}
if (((((unsigned long)((unsigned int)(arg2)) == 1) | ((long)(arg2) < 1)) == 0)) {
*(int *)(((long)arg0 + (((long)(arg2) << 2) - 4))) = *(int *)(((long)arg1 + (((long)(arg2) << 2) - 4)));
}
for (i = 0; (i < arg2); i++) {
checksum = ((unsigned int)(arg0[(long)(i)]) + (unsigned int)(((unsigned long)((unsigned int)((checksum << 5))) + checksum)));
}
// x86-64 epilogue: restore rbp
return checksum;
} gcc -O2
1/1heat_step_1d pass 60 lines
// glaurung: heat_step_1d @ 0x1100
uint32_t heat_step_1d(int32_t * arg0, const int32_t * arg1, int32_t arg2) {
int i;
unsigned int checksum;
long ret;
long var0;
long var13;
long var15;
long var2;
long var21;
int var27;
long var4;
long var9;
long zf_6;
var0 = (unsigned long)((unsigned int)(arg2));
ret = 0;
if ((arg0 == 0)) {
return ret;
}
if ((arg1 == 0)) {
return ret;
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg2))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg2)) == 0)) {
return ret;
}
ret = (unsigned long)((unsigned int)(*(int *)(((long)arg1))));
*(int *)(((long)arg0)) = ret;
zf_6 = ((unsigned long)((unsigned int)(arg2)) == 2);
if ((((unsigned long)((unsigned int)(arg2)) == 2) | ((long)(arg2) < 2))) {
goto L_118c;
}
var2 = (unsigned long)((unsigned int)((arg2 - 3)));
var4 = 0;
do {
var9 = (((long)((int)(*(int *)(((long)arg1 + var4 * 4)))) + ((long)((int)(*(int *)(((long)arg1 + var4 * 4 + 0x4)))) * 2)) + (long)((int)(*(int *)(((long)arg1 + var4 * 4 + 0x8)))));
*(int *)(((long)arg0 + var4 * 4 + 0x4)) = ((long)(((0 <= var9) ? var9 : (var9 + 3))) >> 2);
var13 = var4;
var4 = (var4 + 1);
} while ((var2 != var13));
L_1161: ;
var15 = ((long)((int)(var0)) << 2);
*(int *)(((long)arg0 + var15 - 0x4)) = *(int *)(((long)arg1 + var15 - 0x4));
i = 0;
var21 = 0;
do {
var27 = ((unsigned int)((var21 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var21)) << 5))))) + *(int *)(((long)arg0 + i * 4)));
ret = (unsigned long)((unsigned int)(var27));
i = (i + 1);
var21 = (unsigned long)((unsigned int)(var27));
} while (((((unsigned int)(var0) == (unsigned int)(i)) | ((long)((int)(var0)) < (long)(i))) == 0));
return ret;
L_118c: ;
if (zf_6) {
goto L_1161;
}
return ret;
}