Fixture 21
graph dfs
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)) int32_t graph_dfs(const int32_t *adjacency, int32_t n,
int32_t start, int32_t *order) {
int32_t stack[16];
uint8_t seen[16] = {0};
int32_t top = 0;
int32_t count = 0;
if (adjacency == 0 || order == 0 || n <= 0 || n > 4 || start < 0 ||
start >= n) {
return 0;
}
stack[top++] = start;
while (top > 0) {
int32_t vertex = stack[--top];
int32_t next;
if (seen[vertex] != 0) {
continue;
}
seen[vertex] = 1;
order[count++] = vertex;
for (next = n - 1; next >= 0; --next) {
if (adjacency[vertex * n + next] != 0 && seen[next] == 0) {
stack[top++] = next;
}
}
}
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 -O0
1/1graph_dfs pass 73 lines
// glaurung: graph_dfs @ 0x1110
__attribute__((no_stack_protector)) int32_t graph_dfs(const int32_t * arg0, int32_t arg1, int32_t arg2, int32_t * arg3) {
extern void * memset(void *, int, __SIZE_TYPE__);
int top;
int count;
int vertex;
int next;
int local_4;
unsigned char local_60[64];
unsigned char local_70[16];
void * var1;
int var11;
long var20;
long var38;
long var5;
// x86-64 prologue: save rbp, frame 128 bytes
var1 = memset((void *)(&local_70[0]), 0, (__SIZE_TYPE__)(16));
top = 0;
count = 0;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if ((arg3 == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
// x86-64 epilogue: restore rbp
return 0;
}
if (((((unsigned long)((unsigned int)(arg1)) == 4) | ((long)(arg1) < 4)) == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if (((long)(arg2) < 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if ((arg1 <= arg2)) {
// x86-64 epilogue: restore rbp
return 0;
}
var5 = (unsigned long)((unsigned int)(top));
top = ((unsigned int)(top) + 1);
*(int *)((&local_60[0] + ((long)((int)(var5)) * 4))) = arg2;
while (((((unsigned long)((unsigned int)(top)) == 0) | ((long)(top) < 0)) == 0)) {
var11 = ((unsigned int)(top) - 1);
top = var11;
vertex = *(int *)((&local_60[0] + ((long)((int)(var11)) * 4)));
if (((unsigned long)((unsigned int)((unsigned char)(*(char *)((&local_70[0] + (long)(vertex)))))) == 0)) {
*(signed char *)((&local_70[0] + (long)(vertex))) = 1;
var20 = (unsigned long)((unsigned int)(count));
count = ((unsigned int)(count) + 1);
arg3[(long)((int)(var20))] = vertex;
next = ((unsigned int)(arg1) - 1);
while ((0 <= (long)(next))) {
if (((unsigned long)((unsigned int)(arg0[(long)((int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(vertex)) * arg1))) + next)))])) != 0)) {
if (((unsigned long)((unsigned int)((unsigned char)(*(char *)((&local_70[0] + (long)(next)))))) == 0)) {
var38 = (unsigned long)((unsigned int)(top));
top = ((unsigned int)(top) + 1);
*(int *)((&local_60[0] + ((long)((int)(var38)) * 4))) = next;
}
}
next = ((unsigned int)(next) - 1);
}
} else {
}
}
local_4 = count;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
1/1graph_dfs pass 82 lines
// glaurung: graph_dfs @ 0x1100
__attribute__((no_stack_protector)) int32_t graph_dfs(const int32_t * arg0, int32_t arg1, int32_t arg2, int32_t * arg3) {
int count;
int top;
int vertex;
unsigned char local_48[72];
unsigned char local_59[17];
long ret;
long var10;
long var11;
int var12;
long var13;
long var15;
long var16;
long var22;
long var23;
long var24;
long var25;
long var6;
long var7;
// x86-64 prologue: save callee registers, frame 8 bytes
*(int *)((&local_59[0] + 1)) = 0;
*(int *)((&local_59[0] + 5)) = 0;
*(int *)((&local_59[0] + 9)) = 0;
*(int *)((&local_59[0] + 13)) = 0;
ret = 0;
if ((arg1 <= arg2)) {
// x86-64 epilogue: restore callee registers
return ret;
}
if (((long)(arg2) < 0)) {
// x86-64 epilogue: restore callee registers
return ret;
}
if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 5)))) < (unsigned long)(0xfffffffc))) {
// x86-64 epilogue: restore callee registers
return ret;
}
if ((arg0 == 0)) {
// x86-64 epilogue: restore callee registers
return ret;
}
if ((arg3 == 0)) {
// x86-64 epilogue: restore callee registers
return ret;
}
*(int *)(&local_48[0]) = arg2;
var6 = (unsigned long)((unsigned int)(arg1));
var7 = (long)((arg0 - 1));
ret = 0;
var10 = 1;
var11 = 0;
do {
var12 = (var10 - 1);
var13 = (unsigned long)((unsigned int)(var12));
var15 = (long)((int)(*(int *)((&local_48[0] + ((unsigned long)((unsigned int)(var12)) * 4)))));
var16 = var11;
if (((unsigned long)((unsigned char)(*(char *)((&local_59[0] + (var15 + 1))))) == 0)) {
*(signed char *)((&local_59[0] + (var15 + 1))) = 1;
ret = (unsigned long)((unsigned int)((var11 + 1)));
arg3[(long)((int)(var11))] = var15;
var22 = (var7 + ((long)((int)((var15 * arg1))) * 4));
var23 = var6;
var24 = var13;
do {
var25 = var23;
var23 = (var23 - 1);
var13 = var24;
if ((((unsigned long)((unsigned int)(*(int *)((var22 + var25 * 4)))) != 0) && ((unsigned long)((unsigned char)(*(char *)((&local_59[0] + var25)))) == 0))) {
var13 = (unsigned long)((unsigned int)((var24 + 1)));
*(int *)((&local_48[0] + ((long)((int)(var24)) * 4))) = (var25 - 1);
}
var16 = ret;
var24 = var13;
} while ((1 < (var23 + 1)));
}
var10 = var13;
var11 = var16;
} while (((((unsigned long)((unsigned int)(var13)) == 0) | ((long)((int)(var13)) < 0)) == 0));
// x86-64 epilogue: restore callee registers
return ret;
} gcc -O0
1/1graph_dfs pass 56 lines
// glaurung: graph_dfs @ 0x1119
int32_t graph_dfs(const int32_t * arg0, int32_t arg1, int32_t arg2, int32_t * arg3) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int top;
int count;
int vertex;
int next;
unsigned char local_20[16];
unsigned char local_60[64];
long local_8;
long ret;
long var16;
long var4;
long var41;
// x86-64 prologue: save rbp, frame 144 bytes
local_8 = (long)(0x28);
*(long *)(&local_20[0]) = 0;
*(long *)((&local_20[0] + 8)) = 0;
top = 0;
count = 0;
if (((((((arg0 == 0) || (arg3 == 0)) || (((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) || ((((unsigned long)((unsigned int)(arg1)) == 4) | ((long)(arg1) < 4)) == 0)) || ((long)(arg2) < 0)) || (arg1 <= arg2))) {
ret = 0;
} else {
var4 = (unsigned long)((unsigned int)(top));
top = ((unsigned int)(top) + 1);
*(int *)((&local_60[0] + ((long)((int)(var4)) * 4))) = arg2;
while (((((unsigned long)((unsigned int)(top)) == 0) | ((long)(top) < 0)) == 0)) {
top = (top - 1);
vertex = *(int *)((&local_60[0] + ((long)(top) * 4)));
if (((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((&local_20[0] + (long)(vertex))))) & 255))) == 0)) {
*(signed char *)((&local_20[0] + (long)(vertex))) = 1;
var16 = (unsigned long)((unsigned int)(count));
count = ((unsigned int)(count) + 1);
arg3[(long)((int)(var16))] = vertex;
next = ((unsigned int)(arg1) - 1);
while ((0 <= (long)(next))) {
if (((unsigned long)((unsigned int)(arg0[(long)((int)(((unsigned long)((unsigned int)(next)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(vertex)) * arg1))))))])) != 0)) {
if (((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((&local_20[0] + (long)(next))))) & 255))) == 0)) {
var41 = (unsigned long)((unsigned int)(top));
top = ((unsigned int)(top) + 1);
*(int *)((&local_60[0] + ((long)((int)(var41)) * 4))) = next;
}
}
next = (next - 1);
}
} else {
}
}
ret = (unsigned long)((unsigned int)(count));
}
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} gcc -O2
1/1graph_dfs pass 100 lines
// glaurung: graph_dfs @ 0x1120
int32_t graph_dfs(const int32_t * arg0, int32_t arg1, int32_t arg2, int32_t * arg3) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int top;
int vertex;
int next;
int count;
long rbp;
unsigned char stack_0[64];
unsigned char stack_1[56];
long var10;
long var11;
long var12;
long var13;
long var14;
long var17;
long var22;
long var25;
long var26;
long var31;
long var33;
long var35;
long var39;
long var5;
long var6;
// x86-64 prologue: save callee registers, frame 8 bytes
var5 = (long)arg0;
*(long *)((&stack_1[0] + 40)) = rbp;
*(long *)((&stack_1[0] + 32)) = var6;
*(long *)((&stack_1[0] + 24)) = (long)((long)(0x28));
*(int *)(&stack_1[0]) = 0;
*(int *)((&stack_1[0] + 4)) = 0;
*(int *)((&stack_1[0] + 8)) = 0;
*(int *)((&stack_1[0] + 12)) = 0;
var10 = var11;
if ((arg0 == 0)) {
goto L_11f0;
}
var12 = (long)arg3;
var10 = var11;
if ((arg3 == 0)) {
goto L_11f0;
}
var13 = (unsigned long)((unsigned int)((arg1 - 1)));
var14 = (unsigned long)((unsigned int)(arg1));
var10 = 0;
if (((unsigned long)(3) < (unsigned long)((unsigned long)((unsigned int)(var13))))) {
goto L_11f3;
}
if (((long)(arg2) < 0)) {
goto L_11f0;
}
if ((((unsigned int)(arg1) == (unsigned int)(arg2)) | (arg1 < arg2))) {
goto L_11f0;
}
*(int *)(&stack_0[0]) = arg2;
var17 = 0;
rbp = (long)(&stack_0[0]);
top = 1;
L_118b: ;
var10 = (unsigned long)((unsigned int)(var17));
var22 = (rbp + ((long)(top) * 4));
do {
if (((unsigned long)((unsigned int)(top)) == 0)) {
goto L_11f3;
}
vertex = (long)((int)(*(int *)((var22 - 0x4))));
var25 = (unsigned long)((unsigned int)((top - 1)));
var22 = (var22 - 4);
var26 = (unsigned long)((unsigned int)(vertex));
top = var25;
} while (((unsigned long)((unsigned char)(*(char *)((&stack_1[0] + vertex)))) != 0));
*(signed char *)((&stack_1[0] + vertex)) = 1;
*(int *)((var12 + var17 * 4)) = vertex;
var31 = (var5 + ((long)((int)((var26 * var14))) * 4));
next = (long)((int)(var13));
var33 = var25;
do {
var35 = var33;
if ((((unsigned long)((unsigned int)(*(int *)((var31 + next * 4)))) != 0) && ((unsigned long)((unsigned char)(*(char *)((&stack_1[0] + next)))) == 0))) {
*(int *)((&stack_0[0] + ((long)((int)(var33)) * 4))) = next;
var35 = (unsigned long)((unsigned int)((var33 + 1)));
}
var39 = ((unsigned long)((unsigned int)(next)) - 1);
next = var39;
var33 = var35;
} while (((unsigned long)((unsigned int)(var39)) != 0xffffffff));
var17 = (var17 + 1);
top = var35;
goto L_118b;
L_11f0: ;
var10 = 0;
L_11f3: ;
if ((*(long *)((&stack_1[0] + 24)) == 0x28)) {
rbp = *(long *)((&stack_1[0] + 40));
// x86-64 epilogue: restore callee registers
return (unsigned int)(var10);
}
__stack_chk_fail();
}