Fixture 86
flexible array member
C · 2 functions · 4 lanes · 8 of 8 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
C99 flexible array members: the trailing int32_t items[] contributes nothing to sizeof, so the header size and the element stride must both be recovered to walk the payload correctly.
#include <stdint.h>
/* C99 flexible array members: the trailing `int32_t items[]` contributes
* nothing to sizeof, so the header size and the element stride must both be
* recovered to walk the payload correctly. */
struct Packet {
int32_t length;
int32_t tag;
int32_t items[];
};
__attribute__((noinline)) int32_t
flexible_header_size(void) {
return (int32_t)sizeof(struct Packet);
}
__attribute__((noinline)) int32_t
flexible_sum(const int32_t *storage, int32_t available) {
const struct Packet *packet;
int32_t total = 0;
int32_t index;
int32_t count;
if (storage == 0 || available < 2 || available > 16) {
return -1;
}
packet = (const struct Packet *)(const void *)storage;
count = packet->length;
if (count < 0 || count > available - 2) {
return -2;
}
for (index = 0; index < count; ++index) {
total += packet->items[index];
}
return total + packet->tag;
} 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
2/2flexible_header_size pass 6 lines
// glaurung: flexible_header_size @ 0x1100
int32_t flexible_header_size(void) {
// x86-64 prologue: save rbp
// x86-64 epilogue: restore rbp
return 8;
} flexible_sum pass 46 lines
// glaurung: flexible_sum @ 0x1110
typedef struct Packet Packet;
__attribute__((no_stack_protector)) int32_t flexible_sum(const int32_t * arg0, int32_t arg1) {
int total;
unsigned char packet[8];
int count;
int index;
int local_4;
long var6;
// x86-64 prologue: save rbp
total = 0;
if ((arg0 == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((long)(arg1) < 2)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
*(long *)(&packet[0]) = (long)((long)arg0);
count = *(int *)(*(long *)(&packet[0]));
if (((long)(count) < 0)) {
local_4 = -2;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
var6 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) - 2)));
if (((((unsigned int)(count) == (unsigned int)(var6)) | ((long)(count) < (long)((int)(var6)))) == 0)) {
local_4 = -2;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
for (index = 0; (index < count); index++) {
total = ((unsigned int)(*(int *)(((*(long *)(&packet[0]) + ((long)(index) * 4)) + 8))) + total);
}
local_4 = ((unsigned int)(total) + *(int *)((*(long *)(&packet[0]) + 4)));
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
2/2flexible_header_size pass 4 lines
// glaurung: flexible_header_size @ 0x1100
int32_t flexible_header_size(void) {
return 8;
} flexible_sum pass 66 lines
// glaurung: flexible_sum @ 0x1110
int32_t flexible_sum(const int32_t * arg0, int32_t arg1) {
int count;
int index;
int total;
long ret;
long var10;
long var12;
long var17;
int var2;
int var32;
long var33;
long var39;
long var41;
long var42;
int var43;
long var6;
ret = 0xffffffff;
if ((arg0 == 0)) {
return ret;
}
if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 17)))) < (unsigned long)(0xfffffff1))) {
return ret;
}
count = (unsigned long)((unsigned int)(*(int *)(((long)arg0))));
ret = 0xfffffffe;
if (((long)(count) < 0)) {
return ret;
}
var2 = (arg1 - 2);
if (((((unsigned int)(count) == (unsigned int)(var2)) | (count < var2)) == 0)) {
return ret;
}
if ((count == 0)) {
var6 = 0;
} else {
var10 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(count)) & 7)));
if (((unsigned long)(7) <= (unsigned long)((count - 1)))) {
var12 = (unsigned long)((unsigned int)((count & -8)));
index = 0;
var17 = 0;
do {
var32 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var17 + *(int *)(((long)arg0 + index * 4 + 0x8))))) + *(int *)(((long)arg0 + index * 4 + 0xc))))) + *(int *)(((long)arg0 + index * 4 + 0x10))))) + *(int *)(((long)arg0 + index * 4 + 0x14))))) + *(int *)(((long)arg0 + index * 4 + 0x18))))) + *(int *)(((long)arg0 + index * 4 + 0x1c))))) + *(int *)(((long)arg0 + index * 4 + 0x20)))) + *(int *)(((long)arg0 + index * 4 + 0x24)));
var17 = (unsigned long)((unsigned int)(var32));
index = (index + 8);
var6 = (unsigned long)((unsigned int)(var32));
var33 = (unsigned long)((unsigned int)(index));
} while ((var12 != index));
} else {
var6 = 0;
var33 = 0;
}
if ((var10 != 0)) {
var39 = (long)((((long)arg0 + (var33 * 4)) + 8));
var41 = 0;
var42 = var6;
while ((var10 != var41)) {
var43 = (var42 + *(int *)((var39 + var41 * 4)));
var42 = (unsigned long)((unsigned int)(var43));
var41 = (var41 + 1);
var6 = (unsigned long)((unsigned int)(var43));
}
}
}
return (unsigned int)((var6 + *(int *)(((long)arg0 + 0x4))));
} gcc -O0
2/2flexible_header_size pass 6 lines
// glaurung: flexible_header_size @ 0x10f9
int32_t flexible_header_size(void) {
// x86-64 prologue: save rbp
// x86-64 epilogue: restore rbp
return 8;
} flexible_sum pass 37 lines
// glaurung: flexible_sum @ 0x1108
typedef struct Packet Packet;
int32_t flexible_sum(const int32_t * arg0, int32_t arg1) {
int total;
const Packet * packet;
int count;
int index;
// x86-64 prologue: save rbp
total = 0;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if ((((unsigned long)((unsigned int)(arg1)) == 1) | ((long)(arg1) < 1))) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
packet = (const Packet *)arg0;
count = *(int *)((long)packet);
if (((long)(count) < 0)) {
// x86-64 epilogue: restore rbp
return 0xfffffffe;
}
if (((long)((int)(((unsigned long)((unsigned int)(arg1)) - 1))) <= (long)(count))) {
// x86-64 epilogue: restore rbp
return 0xfffffffe;
}
for (index = 0; (index < count); index++) {
total = (total + (unsigned int)(*(int *)((((long)packet + ((long)(index) * 4)) + 8))));
}
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)((unsigned int)(total)) + (unsigned long)((unsigned int)(*(int *)(((long)packet + 0x4))))));
} gcc -O2
2/2flexible_header_size pass 4 lines
// glaurung: flexible_header_size @ 0x1100
int32_t flexible_header_size(void) {
return 8;
} flexible_sum pass 45 lines
// glaurung: flexible_sum @ 0x1110
int32_t flexible_sum(const int32_t * arg0, int32_t arg1) {
int count;
int total;
int index;
long t148;
long var12;
long var3;
long var4;
int var5;
long var8;
long var9;
if (((unsigned long)(14) < (unsigned long)((unsigned long)((unsigned int)((arg1 - 2)))))) {
return 0xffffffff;
}
if ((arg0 == 0)) {
return 0xffffffff;
}
count = (unsigned long)((unsigned int)(*(int *)(((long)arg0))));
if (((long)(count) < 0)) {
return 0xfffffffe;
}
var3 = (unsigned long)((unsigned int)((arg1 - 1)));
if ((((unsigned int)(var3) == (unsigned int)(count)) | ((long)((int)(var3)) < (long)(count)))) {
return 0xfffffffe;
}
var4 = (unsigned long)((unsigned int)(count));
if (((unsigned long)((unsigned int)(count)) == 0)) {
t148 = *(int *)(((long)arg0 + 0x4));
var5 = (var4 + t148);
return (unsigned int)(var5);
}
var8 = (long)((arg0 + 2));
var9 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((count - 1))) * 4)) + 12));
var12 = 0;
do {
total = (var12 + *(int *)((var8)));
var8 = (var8 + 4);
var12 = (unsigned long)((unsigned int)(total));
var4 = (unsigned long)((unsigned int)(total));
} while ((var8 != var9));
t148 = *(int *)(((long)arg0 + 0x4));
var5 = (var4 + t148);
return (unsigned int)(var5);
}