Fixture 20
graph bfs
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_bfs(const int32_t *adjacency, int32_t n,
int32_t start, int32_t *order) {
int32_t queue[16];
uint8_t seen[16] = {0};
int32_t head = 0;
int32_t tail = 0;
int32_t count = 0;
if (adjacency == 0 || order == 0 || n <= 0 || n > 4 || start < 0 ||
start >= n) {
return 0;
}
queue[tail++] = start;
seen[start] = 1;
while (head < tail) {
int32_t vertex = queue[head++];
int32_t next;
order[count++] = vertex;
for (next = 0; next < n; ++next) {
if (adjacency[vertex * n + next] != 0 && seen[next] == 0) {
seen[next] = 1;
queue[tail++] = 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_bfs pass 71 lines
// glaurung: graph_bfs @ 0x1110
__attribute__((no_stack_protector)) int32_t graph_bfs(const int32_t * arg0, int32_t arg1, int32_t arg2, int32_t * arg3) {
extern void * memset(void *, int, __SIZE_TYPE__);
int head;
int tail;
int count;
int vertex;
int next;
int local_4;
unsigned char local_60[64];
unsigned char local_70[16];
void * var1;
long var12;
long var20;
long var37;
long var5;
// x86-64 prologue: save rbp, frame 144 bytes
var1 = memset((void *)(&local_70[0]), 0, (__SIZE_TYPE__)(16));
head = 0;
tail = 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)(tail));
tail = ((unsigned int)(tail) + 1);
*(int *)((&local_60[0] + ((long)((int)(var5)) * 4))) = arg2;
*(signed char *)((&local_70[0] + (long)(arg2))) = 1;
while ((head < tail)) {
var12 = (unsigned long)((unsigned int)(head));
head = ((unsigned int)(head) + 1);
vertex = *(int *)((&local_60[0] + ((long)((int)(var12)) * 4)));
var20 = (unsigned long)((unsigned int)(count));
count = ((unsigned int)(count) + 1);
arg3[(long)((int)(var20))] = vertex;
for (next = 0; (next < arg1); 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)) {
*(signed char *)((&local_70[0] + (long)(next))) = 1;
var37 = (unsigned long)((unsigned int)(tail));
tail = ((unsigned int)(tail) + 1);
*(int *)((&local_60[0] + ((long)((int)(var37)) * 4))) = next;
}
}
}
}
local_4 = count;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
1/1graph_bfs pass 113 lines
// glaurung: graph_bfs @ 0x1100
__attribute__((no_stack_protector)) int32_t graph_bfs(const int32_t * arg0, int32_t arg1, int32_t arg2, int32_t * arg3) {
int count;
int tail;
int vertex;
int next;
unsigned char local_58[88];
unsigned char local_68[16];
long var11;
long var13;
long var16;
long var21;
long var22;
long var25;
long var28;
long var31;
long var35;
long var5;
long var9;
// x86-64 prologue: save callee registers, frame 16 bytes
*(int *)(&local_68[0]) = 0;
*(int *)((&local_68[0] + 4)) = 0;
*(int *)((&local_68[0] + 8)) = 0;
*(int *)((&local_68[0] + 12)) = 0;
var5 = 0;
count = 0;
if ((arg1 <= arg2)) {
// x86-64 epilogue: restore callee registers
return count;
}
count = var5;
if (((long)(arg2) < 0)) {
// x86-64 epilogue: restore callee registers
return count;
}
count = var5;
if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 5)))) < (unsigned long)(0xfffffffc))) {
// x86-64 epilogue: restore callee registers
return count;
}
count = var5;
if ((arg0 == 0)) {
// x86-64 epilogue: restore callee registers
return count;
}
count = var5;
if ((arg3 == 0)) {
// x86-64 epilogue: restore callee registers
return count;
}
*(int *)(&local_58[0]) = arg2;
*(signed char *)((&local_68[0] + (unsigned long)((unsigned int)(arg2)))) = 1;
var9 = (*(char *)(&local_68[0]) & 255);
var11 = (*(char *)((&local_68[0] + 1)) & 255);
var13 = (*(char *)((&local_68[0] + 2)) & 255);
count = 1;
var16 = (*(char *)((&local_68[0] + 3)) & 255);
tail = 1;
vertex = arg2;
L_1170: ;
*(int *)(((long)arg3 + count * 4 - 0x4)) = vertex;
var21 = (long)((int)((vertex * arg1)));
if (((unsigned long)((unsigned int)(*(int *)(((long)arg0 + var21 * 4)))) != 0)) {
if (((unsigned long)((unsigned char)((var9 & 255))) == 0)) {
var22 = (long)(tail);
tail = (unsigned long)((unsigned int)((tail + 1)));
*(int *)((&local_58[0] + (var22 * 4))) = 0;
var9 = 1;
}
}
if (((unsigned long)((unsigned int)(arg1)) != 1)) {
if (((unsigned long)((unsigned int)(*(int *)(((long)arg0 + var21 * 4 + 0x4)))) != 0)) {
if (((unsigned long)((unsigned char)((var11 & 255))) == 0)) {
var25 = (long)(tail);
tail = (unsigned long)((unsigned int)((tail + 1)));
*(int *)((&local_58[0] + (var25 * 4))) = 1;
var11 = 1;
}
}
if (((unsigned long)((unsigned int)(arg1)) != 2)) {
if (((unsigned long)((unsigned int)(*(int *)(((long)arg0 + var21 * 4 + 0x8)))) != 0)) {
if (((unsigned long)((unsigned char)((var13 & 255))) == 0)) {
var28 = (long)(tail);
tail = (unsigned long)((unsigned int)((tail + 1)));
*(int *)((&local_58[0] + (var28 * 4))) = 2;
var13 = 1;
}
}
if (((unsigned long)((unsigned int)(arg1)) != 3)) {
if (((unsigned long)((unsigned int)(*(int *)(((long)arg0 + var21 * 4 + 0xc)))) != 0)) {
if (((unsigned long)((unsigned char)((var16 & 255))) == 0)) {
var31 = (long)(tail);
tail = (unsigned long)((unsigned int)((tail + 1)));
*(int *)((&local_58[0] + (var31 * 4))) = 3;
var16 = 1;
}
}
}
}
}
if ((count < (long)(tail))) {
var35 = (unsigned long)((unsigned int)(*(int *)((&local_58[0] + (count * 4)))));
count = (count + 1);
vertex = var35;
goto L_1170;
}
*(signed char *)(&local_68[0]) = var9;
*(signed char *)((&local_68[0] + 1)) = var11;
*(signed char *)((&local_68[0] + 2)) = var13;
*(signed char *)((&local_68[0] + 3)) = var16;
// x86-64 epilogue: restore callee registers
return count;
} gcc -O0
1/1graph_bfs pass 56 lines
// glaurung: graph_bfs @ 0x1119
int32_t graph_bfs(const int32_t * arg0, int32_t arg1, int32_t arg2, int32_t * arg3) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int head;
int tail;
int count;
int vertex;
int next;
unsigned char local_20[16];
unsigned char local_60[64];
long local_8;
long ret;
long var11;
long var15;
long var4;
long var40;
// x86-64 prologue: save rbp, frame 160 bytes
local_8 = (long)(0x28);
*(long *)(&local_20[0]) = 0;
*(long *)((&local_20[0] + 8)) = 0;
head = 0;
tail = 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)(tail));
tail = ((unsigned int)(tail) + 1);
*(int *)((&local_60[0] + ((long)((int)(var4)) * 4))) = arg2;
*(signed char *)((&local_20[0] + (long)(arg2))) = 1;
while ((head < tail)) {
var11 = (unsigned long)((unsigned int)(head));
head = ((unsigned int)(head) + 1);
vertex = *(int *)((&local_60[0] + ((long)((int)(var11)) * 4)));
var15 = (unsigned long)((unsigned int)(count));
count = ((unsigned int)(count) + 1);
arg3[(long)((int)(var15))] = vertex;
for (next = 0; (next < arg1); 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)) {
*(signed char *)((&local_20[0] + (long)(next))) = 1;
var40 = (unsigned long)((unsigned int)(tail));
tail = ((unsigned int)(tail) + 1);
*(int *)((&local_60[0] + ((long)((int)(var40)) * 4))) = next;
}
}
}
}
ret = (unsigned long)((unsigned int)(count));
}
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} gcc -O2
1/1graph_bfs pass 79 lines
// glaurung: graph_bfs @ 0x1120
int32_t graph_bfs(const int32_t * arg0, int32_t arg1, int32_t arg2, int32_t * arg3) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int count;
int tail;
int next;
long local_10;
unsigned char local_28[16];
unsigned char local_68[64];
long var10;
long var13;
long var14;
long var20;
long var26;
long var28;
long var8;
long var9;
local_10 = (long)(0x28);
*(int *)(&local_28[0]) = 0;
*(int *)((&local_28[0] + 4)) = 0;
*(int *)((&local_28[0] + 8)) = 0;
*(int *)((&local_28[0] + 12)) = 0;
var8 = var9;
if ((arg0 == 0)) {
goto L_11d0;
}
var10 = (long)arg3;
var8 = var9;
if ((arg3 == 0)) {
goto L_11d0;
}
var8 = 0;
if (((unsigned long)(3) < (unsigned long)((unsigned long)((unsigned int)((arg1 - 1)))))) {
goto L_11d3;
}
if (((long)(arg2) < 0)) {
goto L_11d0;
}
if ((((unsigned int)(arg1) == (unsigned int)(arg2)) | (arg1 < arg2))) {
goto L_11d0;
}
var13 = (long)(arg2);
var14 = (long)arg0;
*(signed char *)((&local_28[0] + (long)(arg2))) = 1;
count = 1;
tail = 1;
var20 = (unsigned long)((unsigned int)(arg2));
L_1188: ;
*(int *)((var10 + count * 4 - 0x4)) = var20;
var8 = (unsigned long)((unsigned int)(count));
var26 = (var14 + ((long)((int)((var20 * arg1))) * 4));
next = 0;
var28 = (unsigned long)((unsigned int)(tail));
do {
tail = var28;
if ((((unsigned long)((unsigned int)(*(int *)((var26 + next * 4)))) != 0) && ((unsigned long)((unsigned char)(*(char *)((&local_28[0] + next)))) == 0))) {
*(signed char *)((&local_28[0] + next)) = 1;
*(int *)((&local_68[0] + ((long)((int)(var28)) * 4))) = next;
tail = (unsigned long)((unsigned int)((var28 + 1)));
}
var13 = ((unsigned long)((unsigned int)(next)) + 1);
next = var13;
var28 = (unsigned long)((unsigned int)(tail));
} while (((((unsigned int)(arg1) == (unsigned int)(var13)) | ((long)(arg1) < (long)((int)(var13)))) == 0));
if ((((unsigned int)(tail) == (unsigned int)(count)) | (tail < count))) {
goto L_11d3;
}
var20 = (unsigned long)((unsigned int)(*(int *)((&local_68[0] + (count * 4)))));
count = (count + 1);
goto L_1188;
L_11d0: ;
var8 = 0;
L_11d3: ;
if ((local_10 == 0x28)) {
// x86-64 epilogue: tear down frame
return (unsigned int)(var8);
}
__stack_chk_fail();
}