Fixture 39
counting radix sort
C · 2 functions · 4 lanes · 7 of 8 function-lanes behave identically
One lane has a function that returns a different result after decompilation: gcc-O2 (1/2).
Counting sort over a small key domain and an LSD radix sort over 4-bit digits. Both build a prefix-sum histogram and then scatter in reverse to remain stable; the scatter is an indirect write whose index is loaded.
#include <stdint.h>
/* Counting sort over a small key domain and an LSD radix sort over 4-bit
* digits. Both build a prefix-sum histogram and then scatter in reverse to
* remain stable; the scatter is an indirect write whose index is loaded. */
#define RADIX_MAX 16
#define RADIX_BUCKETS 16
__attribute__((noinline)) int32_t
counting_sort_u8(uint8_t *values, int32_t count) {
int32_t histogram[256];
int32_t index;
int32_t bucket;
int32_t out;
if (values == 0 || count < 0 || count > RADIX_MAX) {
return -1;
}
for (bucket = 0; bucket < 256; ++bucket) {
histogram[bucket] = 0;
}
for (index = 0; index < count; ++index) {
histogram[values[index]] += 1;
}
out = 0;
for (bucket = 0; bucket < 256; ++bucket) {
int32_t remaining = histogram[bucket];
while (remaining > 0 && out < count) {
values[out] = (uint8_t)bucket;
out += 1;
remaining -= 1;
}
}
return count;
}
__attribute__((noinline)) int32_t
radix_sort_u32(uint32_t *values, int32_t count) {
uint32_t scratch[RADIX_MAX];
int32_t histogram[RADIX_BUCKETS];
int32_t shift;
int32_t index;
int32_t bucket;
if (values == 0 || count < 0 || count > RADIX_MAX) {
return -1;
}
for (shift = 0; shift < 32; shift += 4) {
int32_t running = 0;
for (bucket = 0; bucket < RADIX_BUCKETS; ++bucket) {
histogram[bucket] = 0;
}
for (index = 0; index < count; ++index) {
histogram[(values[index] >> shift) & 0xFu] += 1;
}
for (bucket = 0; bucket < RADIX_BUCKETS; ++bucket) {
int32_t occupancy = histogram[bucket];
histogram[bucket] = running;
running += occupancy;
}
for (index = 0; index < count; ++index) {
int32_t slot = (int32_t)((values[index] >> shift) & 0xFu);
scratch[histogram[slot]] = values[index];
histogram[slot] += 1;
}
for (index = 0; index < count; ++index) {
values[index] = scratch[index];
}
}
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.
gcc -O2
1/2counting_sort_u8 pass 82 lines
// glaurung: counting_sort_u8 @ 0x1140
int32_t counting_sort_u8(uint8_t * arg0, int32_t arg1) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int bucket;
int remaining;
int out;
int index;
long df_1;
long local_10;
unsigned char local_418[1024];
long t1;
long t136;
long t153;
long var11;
long var12;
int var13;
long var17;
long var19;
long var2;
long var21;
long var22;
long var3;
long var31;
long var32;
long var5;
df_1 = 0;
local_10 = (long)(0x28);
var2 = 0;
if ((arg0 == 0)) {
L_121a: ;
var3 = 0xffffffff;
} else {
var3 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
goto L_121a;
} else {
var5 = (long)arg0;
t136 = (long)(&local_418[0]);
t1 = 128;
while ((t1 != 0)) {
*(long *)(t136) = var2;
t136 = (t136 + ((df_1 != 0) ? -8 : 8));
t1 = (t1 - 1);
}
if (((unsigned long)((unsigned int)(arg1)) != 0)) {
var11 = var5;
var12 = ((var5 + (unsigned long)((unsigned int)((arg1 - 1)))) + 1);
do {
var13 = (unsigned int)((unsigned char)(*(char *)((var11))));
var11 = (var11 + 1);
*(int *)((&local_418[0] + (var13 * 4))) = (*(int *)((&local_418[0] + (var13 * 4))) + 1);
} while ((var12 != var11));
}
bucket = 0;
var17 = 0;
do {
remaining = (unsigned long)((unsigned int)(*(int *)((&local_418[0] + (bucket * 4)))));
var19 = var17;
if ((((((unsigned int)(var3) == (unsigned int)(var17)) | ((long)((int)(var3)) < (long)((int)(var17)))) == 0) && ((((unsigned long)((unsigned int)(remaining)) == 0) | ((long)(remaining) < 0)) == 0))) {
var21 = (unsigned long)((unsigned int)(bucket));
var22 = (unsigned long)((unsigned int)((var17 + remaining)));
out = (long)((int)((var17 + 1)));
do {
*(signed char *)((var5 + out - 0x1)) = var21;
var19 = (unsigned long)((unsigned int)(out));
t153 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var22)) - out)));
var31 = ((((unsigned int)(var3) == (unsigned int)(out)) | ((long)((int)(var3)) < (long)(out))) == 0);
out = (out + 1);
} while (((unsigned long)((unsigned char)((((((unsigned long)((unsigned int)(t153)) == 0) | ((long)((int)(t153)) < 0)) == 0) & (var31 & 255)))) != 0));
}
var32 = ((unsigned long)((unsigned int)(bucket)) + 1);
bucket = var32;
var17 = var19;
} while ((var32 != 256));
}
}
if ((local_10 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: tear down frame
return (unsigned int)(var3);
} radix_sort_u32 fail 104 lines
// glaurung: radix_sort_u32 @ 0x1230
int32_t radix_sort_u32(uint32_t * arg0, int32_t arg1) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
extern void * memcpy(void *, const void *, __SIZE_TYPE__);
int occupancy;
int bucket;
int index;
int running;
int shift;
long local_40;
unsigned char local_88[64];
unsigned char local_c8[64];
int local_cc;
long var10;
long var12;
long var13;
long var19;
long var21;
long var26;
long var27;
long var3;
long var30;
long var34;
long var36;
long var37;
long var43;
long var44;
void * var50;
int var53;
long var8;
local_40 = (long)(0x28);
if ((arg0 == 0)) {
L_1372: ;
var3 = 0xffffffff;
} else {
var3 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
goto L_1372;
} else {
var8 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 1))) * 4)) + 4));
var10 = (long)((&local_88[0] + 64));
var12 = 0;
var13 = (long)arg0;
do {
var19 = var13;
*(int *)(&local_88[0]) = 0;
*(int *)((&local_88[0] + 4)) = 0;
*(int *)((&local_88[0] + 8)) = 0;
*(int *)((&local_88[0] + 12)) = 0;
*(int *)((&local_88[0] + 16)) = 0;
*(int *)((&local_88[0] + 20)) = 0;
*(int *)((&local_88[0] + 24)) = 0;
*(int *)((&local_88[0] + 28)) = 0;
*(int *)((&local_88[0] + 32)) = 0;
*(int *)((&local_88[0] + 36)) = 0;
*(int *)((&local_88[0] + 40)) = 0;
*(int *)((&local_88[0] + 44)) = 0;
*(int *)((&local_88[0] + 48)) = 0;
*(int *)((&local_88[0] + 52)) = 0;
*(int *)((&local_88[0] + 56)) = 0;
*(int *)((&local_88[0] + 60)) = 0;
if (((unsigned long)((unsigned int)(var3)) != 0)) {
do {
var21 = (unsigned long)((unsigned int)(*(int *)((var19))));
var19 = (var19 + 4);
var26 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var21)) >> (var12 & 31)))) & 15)));
*(int *)((&local_88[0] + (var26 * 4))) = (*(int *)((&local_88[0] + (var26 * 4))) + 1);
} while ((var8 != var19));
}
var27 = (long)(&local_88[0]);
var30 = 0;
do {
occupancy = (unsigned long)((unsigned int)(*(int *)((var27))));
*(int *)((var27)) = var30;
var27 = (var27 + 4);
var30 = (unsigned long)((unsigned int)((var30 + occupancy)));
} while ((var27 != var10));
var34 = var12;
if (((unsigned long)((unsigned int)(var3)) != 0)) {
var36 = var13;
do {
var37 = (unsigned long)((unsigned int)(*(int *)((var36))));
var36 = (var36 + 4);
var43 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var37)) >> (var12 & 31)))) & 15)));
var44 = (long)((int)(*(int *)((&local_88[0] + (var43 * 4)))));
*(int *)((&local_c8[0] + (var44 * 4))) = var37;
*(int *)((&local_88[0] + (var43 * 4))) = (var44 + 1);
} while ((var8 != var36));
local_cc = var12;
var50 = ((void * (*)(void))memcpy)();
var13 = (long)var50;
var34 = (unsigned long)((unsigned int)(local_cc));
}
var53 = (var34 + 4);
var12 = (unsigned long)((unsigned int)(var53));
} while (((unsigned long)((unsigned int)(var53)) != 32));
}
}
if ((local_40 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: tear down frame
return (unsigned int)(var3);
} clang -O0
2/2counting_sort_u8 pass 66 lines
// glaurung: counting_sort_u8 @ 0x1100
__attribute__((no_stack_protector)) int32_t counting_sort_u8(uint8_t * arg0, int32_t arg1) {
int bucket;
int index;
int out;
int remaining;
int local_4;
unsigned char local_420[1024];
signed char local_431;
long var15;
int var7;
if ((arg0 != 0)) {
if ((0 <= (long)(arg1))) {
if ((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16))) {
goto L_113d;
}
}
}
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_113d: ;
bucket = 0;
L_1147: ;
if (((long)(bucket) < 256)) {
*(int *)((&local_420[0] + ((long)(bucket) * 4))) = 0;
bucket = ((unsigned int)(bucket) + 1);
goto L_1147;
}
index = 0;
L_1187: ;
if ((index < arg1)) {
var7 = (unsigned int)((unsigned char)(arg0[index]));
*(int *)((&local_420[0] + (var7 * 4))) = ((unsigned long)((unsigned int)(*(int *)((&local_420[0] + (var7 * 4))))) + 1);
index = ((unsigned int)(index) + 1);
goto L_1187;
}
out = 0;
bucket = 0;
L_11de: ;
if ((256 <= (long)(bucket))) {
goto L_128e;
}
var15 = (unsigned long)((unsigned int)(*(int *)((&local_420[0] + ((long)(bucket) * 4)))));
remaining = var15;
L_1202: ;
local_431 = 0;
if (((((unsigned long)((unsigned int)(remaining)) == 0) | ((long)(remaining) < 0)) == 0)) {
local_431 = (out < arg1);
}
if (((unsigned long)((unsigned char)((local_431 & 1))) != 0)) {
arg0[out] = bucket;
out = ((unsigned int)(out) + 1);
var15 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(remaining)) - 1)));
remaining = var15;
goto L_1202;
}
goto L_127a;
L_127a: ;
bucket = ((unsigned int)(bucket) + 1);
goto L_11de;
L_128e: ;
local_4 = arg1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} radix_sort_u32 pass 57 lines
// glaurung: radix_sort_u32 @ 0x12a0
__attribute__((no_stack_protector)) int32_t radix_sort_u32(uint32_t * arg0, int32_t arg1) {
int shift;
int running;
int bucket;
int index;
int occupancy;
int slot;
int local_4;
unsigned char local_60[64];
unsigned char local_a0[64];
long var14;
// x86-64 prologue: save rbp, frame 64 bytes
if ((arg0 == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((long)(arg1) < 0)) {
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);
}
shift = 0;
while (((long)(shift) < 32)) {
running = 0;
for (bucket = 0; ((long)(bucket) < 16); bucket++) {
*(int *)((&local_a0[0] + ((long)(bucket) * 4))) = 0;
}
for (index = 0; (index < arg1); index++) {
var14 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(index)])) >> ((unsigned long)((unsigned int)(shift)) & 31)))) & 15)));
*(int *)((&local_a0[0] + (var14 * 4))) = ((unsigned long)((unsigned int)(*(int *)((&local_a0[0] + (var14 * 4))))) + 1);
}
for (bucket = 0; ((long)(bucket) < 16); bucket++) {
occupancy = *(int *)((&local_a0[0] + ((long)(bucket) * 4)));
*(int *)((&local_a0[0] + ((long)(bucket) * 4))) = running;
running = ((unsigned int)(occupancy) + running);
}
for (index = 0; (index < arg1); index++) {
slot = ((unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(index)])) >> ((unsigned long)((unsigned int)(shift)) & 31))) & 15);
*(int *)((&local_60[0] + ((long)((int)(*(int *)((&local_a0[0] + ((long)(slot) * 4))))) * 4))) = arg0[(long)(index)];
*(int *)((&local_a0[0] + ((long)(slot) * 4))) = ((unsigned long)((unsigned int)(*(int *)((&local_a0[0] + ((long)(slot) * 4))))) + 1);
}
for (index = 0; (index < arg1); index++) {
arg0[(long)(index)] = *(int *)((&local_60[0] + ((long)(index) * 4)));
}
shift = ((unsigned int)(shift) + 4);
}
local_4 = arg1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
2/2counting_sort_u8 pass 125 lines
// glaurung: counting_sort_u8 @ 0x1120
__attribute__((no_stack_protector)) int32_t counting_sort_u8(uint8_t * arg0, int32_t arg1) {
extern void * memset(void *, int, __SIZE_TYPE__);
int index;
int out;
int remaining;
int bucket;
unsigned char local_438[1080];
long of_45;
long rbp;
long ret;
long sf_45;
long var1;
void * var10;
long var12;
long var13;
long var17;
long var2;
int var21;
int var22;
int var23;
int var24;
long var25;
long var28;
long var3;
long var30;
int var31;
long var32;
long var35;
long var38;
long var39;
long var4;
void * var46;
long var48;
long var49;
long var5;
int var50;
long var6;
long var8;
ret = 0xffffffff;
if ((arg0 == 0)) {
return ret;
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
*(long *)((&local_438[0] + 1072)) = rbp;
*(long *)((&local_438[0] + 1064)) = var1;
*(long *)((&local_438[0] + 1056)) = var2;
*(long *)((&local_438[0] + 1048)) = var3;
*(long *)((&local_438[0] + 1040)) = var4;
*(long *)((&local_438[0] + 1032)) = var5;
var6 = (long)arg0;
var8 = 0;
var10 = memset((void *)(&local_438[0]), 0, (__SIZE_TYPE__)(1024));
var12 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)((unsigned int)(arg1)) != 0)) {
var13 = (unsigned long)((unsigned int)(var12));
var17 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var12)) & 3)));
if (((unsigned long)(3) <= (unsigned long)(((unsigned long)((unsigned int)(var12)) - 1)))) {
var13 = (unsigned long)((unsigned int)((var13 & -4)));
index = 0;
do {
var21 = (unsigned int)((unsigned char)(*(char *)((var6 + index))));
*(int *)((&local_438[0] + (var21 * 4))) = (*(int *)((&local_438[0] + (var21 * 4))) + 1);
var22 = (unsigned int)((unsigned char)(*(char *)((var6 + index + 0x1))));
*(int *)((&local_438[0] + (var22 * 4))) = (*(int *)((&local_438[0] + (var22 * 4))) + 1);
var23 = (unsigned int)((unsigned char)(*(char *)((var6 + index + 0x2))));
*(int *)((&local_438[0] + (var23 * 4))) = (*(int *)((&local_438[0] + (var23 * 4))) + 1);
var24 = (unsigned int)((unsigned char)(*(char *)((var6 + index + 0x3))));
*(int *)((&local_438[0] + (var24 * 4))) = (*(int *)((&local_438[0] + (var24 * 4))) + 1);
index = (index + 4);
var25 = (unsigned long)((unsigned int)(index));
} while ((var13 != index));
} else {
var25 = 0;
}
if ((var17 != 0)) {
var28 = (var25 + var6);
var30 = 0;
while ((var17 != var30)) {
var31 = (unsigned int)((unsigned char)(*(char *)((var28 + var30))));
*(int *)((&local_438[0] + (var31 * 4))) = (*(int *)((&local_438[0] + (var31 * 4))) + 1);
var30 = (var30 + 1);
}
}
}
var32 = (long)((int)(var12));
var35 = 0;
out = var8;
do {
remaining = (unsigned long)((unsigned int)(*(int *)((&local_438[0] + (var35 * 4)))));
if (((((unsigned long)((unsigned int)(remaining)) == 0) | ((long)(remaining) < 0)) == 0)) {
if (((long)(out) < (long)((int)(var12)))) {
var38 = (long)(out);
var39 = (unsigned long)((unsigned int)((remaining - 1)));
var46 = memset((void *)((var6 + (long)(out))), (int)((unsigned long)((unsigned int)(var35))), (__SIZE_TYPE__)(((((unsigned long)((unsigned int)(var39)) == 0) ? var39 : (((unsigned long)((unsigned long)((unsigned int)(var39))) <= (unsigned long)((unsigned long)((unsigned int)(((~(unsigned long)((unsigned int)(out))) + var12))))) ? var39 : (unsigned long)((unsigned int)(((~(unsigned long)((unsigned int)(out))) + var12))))) + 1)));
var12 = (unsigned long)((unsigned int)(arg1));
var48 = (var38 + 1);
var49 = (unsigned long)((unsigned int)(out));
while (1) {
var50 = (var49 + 1);
var49 = (unsigned long)((unsigned int)(var50));
out = (unsigned long)((unsigned int)(var50));
if (((unsigned long)((unsigned long)((unsigned int)(remaining))) < (unsigned long)(2))) {
break;
}
remaining = (unsigned long)((unsigned int)((remaining - 1)));
sf_45 = ((var48 - var32) < 0);
of_45 = ((var48 < var32) ^ ((var48 - var32) < 0));
var48 = (var48 + 1);
if (((sf_45 ^ of_45) == 0)) {
out = var49;
break;
}
}
}
}
bucket = (var35 + 1);
var35 = (unsigned long)((unsigned int)(bucket));
} while ((bucket != 256));
ret = (unsigned long)((unsigned int)(var12));
// x86-64 epilogue: tear down frame
return (unsigned int)(var12);
} radix_sort_u32 pass 255 lines
// glaurung: radix_sort_u32 @ 0x1270
__attribute__((no_stack_protector)) int32_t radix_sort_u32(uint32_t * arg0, int32_t arg1) {
extern void * memcpy(void *, const void *, __SIZE_TYPE__);
int shift;
int bucket;
int index;
int occupancy;
int running;
int slot;
long cf_44;
unsigned char local_78[120];
unsigned char local_d8[96];
unsigned char local_e8[16];
long ret;
long var0;
long var1;
int var10;
long var103;
long var104;
long var109;
int var11;
long var110;
long var113;
long var118;
long var119;
int var12;
long var122;
long var127;
long var128;
int var13;
void * var131;
long var25;
long var26;
long var27;
long var28;
long var29;
long var30;
long var31;
long var32;
long var33;
long var34;
long var35;
long var38;
long var43;
long var49;
long var53;
long var55;
long var56;
long var57;
long var58;
long var59;
long var6;
long var60;
long var61;
long var62;
long var65;
long var69;
int var70;
int var72;
int var74;
int var76;
int var78;
int var80;
int var82;
int var84;
int var86;
int var88;
int var91;
int var93;
int var96;
int var99;
// x86-64 prologue: save callee registers, frame 48 bytes
ret = 0xffffffff;
if ((arg0 == 0)) {
// x86-64 epilogue: restore callee registers
return ret;
}
var0 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
// x86-64 epilogue: restore callee registers
return ret;
}
var1 = (long)arg0;
*(long *)((&local_d8[0] + 88)) = ((unsigned long)((unsigned int)(var0)) * 4);
*(long *)((&local_d8[0] + 72)) = ((unsigned long)((unsigned int)(var0)) - 1);
*(long *)((&local_d8[0] + 80)) = (unsigned int)(var0);
var6 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) & -2)));
var10 = 0;
var11 = 0;
var12 = 0;
var13 = 0;
*(int *)((&local_d8[0] + 64)) = var0;
shift = 0;
do {
*(int *)((&local_d8[0] + 48)) = var10;
*(int *)((&local_d8[0] + 52)) = var11;
*(int *)((&local_d8[0] + 56)) = var12;
*(int *)((&local_d8[0] + 60)) = var13;
*(int *)((&local_d8[0] + 32)) = var10;
*(int *)((&local_d8[0] + 36)) = var11;
*(int *)((&local_d8[0] + 40)) = var12;
*(int *)((&local_d8[0] + 44)) = var13;
*(int *)((&local_d8[0] + 16)) = var10;
*(int *)((&local_d8[0] + 20)) = var11;
*(int *)((&local_d8[0] + 24)) = var12;
*(int *)((&local_d8[0] + 28)) = var13;
*(int *)(&local_d8[0]) = var10;
*(int *)((&local_d8[0] + 4)) = var11;
*(int *)((&local_d8[0] + 8)) = var12;
*(int *)((&local_d8[0] + 12)) = var13;
*(int *)((&local_e8[0] + 12)) = 0;
*(int *)((&local_e8[0] + 8)) = 0;
var25 = 0;
*(int *)((&local_e8[0] + 4)) = 0;
*(int *)(&local_e8[0]) = 0;
var26 = 0;
var27 = 0;
var28 = 0;
var29 = 0;
var30 = 0;
var31 = 0;
var32 = 0;
var33 = 0;
var34 = 0;
var35 = 0;
if (((unsigned long)((unsigned int)(var0)) != 0)) {
if ((*(long *)((&local_d8[0] + 72)) == 0)) {
var38 = 0;
if (((unsigned long)((unsigned char)((*(char *)((&local_d8[0] + 80)) & 1))) != 0)) {
L_139f: ;
var43 = (unsigned long)((unsigned int)((((unsigned long)((unsigned int)(*(int *)((var1 + var38 * 4)))) >> ((unsigned long)((unsigned int)(shift)) & 63)) & 15)));
*(int *)((&local_d8[0] + (var43 * 4))) = (*(int *)((&local_d8[0] + (var43 * 4))) + 1);
} else {
}
} else {
var38 = 0;
do {
var49 = (unsigned long)((unsigned int)((((unsigned long)((unsigned int)(*(int *)((var1 + var38 * 4)))) >> ((unsigned long)((unsigned int)(shift)) & 63)) & 15)));
*(int *)((&local_d8[0] + (var49 * 4))) = (*(int *)((&local_d8[0] + (var49 * 4))) + 1);
var53 = (unsigned long)((unsigned int)((((unsigned long)((unsigned int)(*(int *)((var1 + var38 * 4 + 0x4)))) >> ((unsigned long)((unsigned int)(shift)) & 63)) & 15)));
*(int *)((&local_d8[0] + (var53 * 4))) = (*(int *)((&local_d8[0] + (var53 * 4))) + 1);
var38 = (var38 + 2);
} while ((var6 != var38));
if (((unsigned long)((unsigned char)((*(char *)((&local_d8[0] + 80)) & 1))) == 0)) {
goto L_13af;
}
goto L_139f;
}
L_13af: ;
*(int *)((&local_e8[0] + 4)) = *(int *)(&local_d8[0]);
var25 = (unsigned long)((unsigned int)(*(int *)((&local_d8[0] + 4))));
var55 = (unsigned long)((unsigned int)(*(int *)((&local_d8[0] + 8))));
var56 = (unsigned long)((unsigned int)(*(int *)((&local_d8[0] + 12))));
var57 = (unsigned long)((unsigned int)(*(int *)((&local_d8[0] + 16))));
var58 = (unsigned long)((unsigned int)(*(int *)((&local_d8[0] + 20))));
var59 = (unsigned long)((unsigned int)(*(int *)((&local_d8[0] + 24))));
var60 = (unsigned long)((unsigned int)(*(int *)((&local_d8[0] + 28))));
var61 = (unsigned long)((unsigned int)(*(int *)((&local_d8[0] + 32))));
var62 = (unsigned long)((unsigned int)(*(int *)((&local_d8[0] + 36))));
*(int *)((&local_d8[0] + 68)) = *(int *)((&local_d8[0] + 40));
*(int *)((&local_e8[0] + 8)) = *(int *)((&local_d8[0] + 44));
var65 = (unsigned long)((unsigned int)(*(int *)((&local_d8[0] + 48))));
*(int *)((&local_e8[0] + 12)) = *(int *)((&local_d8[0] + 52));
*(int *)(&local_e8[0]) = *(int *)((&local_d8[0] + 56));
var26 = var57;
var27 = var65;
var28 = var58;
var29 = var56;
var30 = var55;
var31 = var62;
var32 = var61;
var33 = (unsigned long)((unsigned int)(*(int *)((&local_d8[0] + 68))));
var34 = var60;
var35 = var59;
}
var69 = (unsigned long)((unsigned int)(*(int *)((&local_e8[0] + 4))));
var70 = (var25 + var69);
*(int *)(&local_d8[0]) = 0;
*(int *)((&local_d8[0] + 4)) = var69;
var72 = (var30 + (unsigned int)(var70));
*(int *)((&local_d8[0] + 8)) = var70;
var74 = (var29 + (unsigned int)(var72));
*(int *)((&local_d8[0] + 12)) = var72;
var76 = (var26 + (unsigned int)(var74));
*(int *)((&local_d8[0] + 16)) = var74;
var78 = (var28 + (unsigned int)(var76));
*(int *)((&local_d8[0] + 20)) = var76;
var80 = (var35 + (unsigned int)(var78));
*(int *)((&local_d8[0] + 24)) = var78;
var82 = (var34 + (unsigned int)(var80));
*(int *)((&local_d8[0] + 28)) = var80;
var84 = (var32 + (unsigned int)(var82));
*(int *)((&local_d8[0] + 32)) = var82;
var86 = (var31 + (unsigned int)(var84));
*(int *)((&local_d8[0] + 36)) = var84;
var88 = (var33 + (unsigned int)(var86));
*(int *)((&local_d8[0] + 40)) = var86;
var91 = ((unsigned int)(*(int *)((&local_e8[0] + 8))) + (unsigned int)(var88));
*(int *)((&local_d8[0] + 44)) = var88;
var93 = (var27 + (unsigned int)(var91));
*(int *)((&local_d8[0] + 48)) = var91;
var96 = ((unsigned int)(*(int *)((&local_e8[0] + 12))) + (unsigned int)(var93));
*(int *)((&local_d8[0] + 52)) = var93;
var99 = ((unsigned int)(*(int *)(&local_e8[0])) + (unsigned int)(var96));
*(int *)((&local_d8[0] + 56)) = var96;
*(int *)((&local_d8[0] + 60)) = var99;
var0 = (unsigned long)((unsigned int)(*(int *)((&local_d8[0] + 64))));
if (((unsigned long)((unsigned int)(var0)) != 0)) {
if ((*(long *)((&local_d8[0] + 72)) == 0)) {
var103 = 0;
if (((unsigned long)((unsigned char)((*(char *)((&local_d8[0] + 80)) & 1))) != 0)) {
L_14fd: ;
var104 = (unsigned long)((unsigned int)(*(int *)((var1 + var103 * 4))));
var109 = (unsigned long)((unsigned int)((((unsigned long)(var104) >> ((unsigned long)((unsigned int)(shift)) & 63)) & 15)));
var110 = (long)((int)(*(int *)((&local_d8[0] + (var109 * 4)))));
*(int *)((&local_78[0] + (var110 * 4))) = var104;
*(int *)((&local_d8[0] + (var109 * 4))) = (var110 + 1);
} else {
}
} else {
var103 = 0;
do {
var113 = (unsigned long)((unsigned int)(*(int *)((var1 + var103 * 4))));
var118 = (unsigned long)((unsigned int)((((unsigned long)(var113) >> ((unsigned long)((unsigned int)(shift)) & 63)) & 15)));
var119 = (long)((int)(*(int *)((&local_d8[0] + (var118 * 4)))));
*(int *)((&local_78[0] + (var119 * 4))) = var113;
*(int *)((&local_d8[0] + (var118 * 4))) = (var119 + 1);
var122 = (unsigned long)((unsigned int)(*(int *)((var1 + var103 * 4 + 0x4))));
var127 = (unsigned long)((unsigned int)((((unsigned long)(var122) >> ((unsigned long)((unsigned int)(shift)) & 63)) & 15)));
var128 = (long)((int)(*(int *)((&local_d8[0] + (var127 * 4)))));
*(int *)((&local_78[0] + (var128 * 4))) = var122;
*(int *)((&local_d8[0] + (var127 * 4))) = (var128 + 1);
var103 = (var103 + 2);
} while ((var6 != var103));
if (((unsigned long)((unsigned char)((*(char *)((&local_d8[0] + 80)) & 1))) == 0)) {
goto L_151b;
}
goto L_14fd;
}
L_151b: ;
if (((unsigned long)((unsigned int)(var0)) != 0)) {
var131 = memcpy((void *)(var1), (const void *)(&local_78[0]), (__SIZE_TYPE__)(*(long *)((&local_d8[0] + 88))));
var10 = 0;
var11 = 0;
var12 = 0;
var13 = 0;
}
}
cf_44 = ((unsigned long)((unsigned long)((unsigned int)(shift))) < (unsigned long)(28));
shift = (unsigned long)((unsigned int)((shift + 4)));
} while ((cf_44 != 0));
ret = (unsigned long)((unsigned int)(var0));
// x86-64 epilogue: restore callee registers
return (unsigned int)(var0);
} gcc -O0
2/2counting_sort_u8 pass 43 lines
// glaurung: counting_sort_u8 @ 0x1119
int32_t counting_sort_u8(uint8_t * arg0, int32_t arg1) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int bucket;
int index;
int out;
int remaining;
unsigned char local_410[1024];
long local_8;
long ret;
// x86-64 prologue: save rbp, frame 1072 bytes
local_8 = (long)(0x28);
if ((((arg0 == 0) || ((long)(arg1) < 0)) || (((unsigned long)((unsigned int)(arg1)) != 16) && (16 <= (long)(arg1))))) {
ret = 0xffffffff;
} else {
for (bucket = 0; ((((unsigned long)((unsigned int)(bucket)) == 255) | ((long)(bucket) < 255)) != 0); bucket++) {
*(int *)((&local_410[0] + ((long)(bucket) * 4))) = 0;
}
for (index = 0; (index < arg1); index++) {
*(int *)((&local_410[0] + ((long)((int)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255)))) * 4))) = ((unsigned long)((unsigned int)(*(int *)((&local_410[0] + ((long)((int)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255)))) * 4))))) + 1);
}
out = 0;
bucket = 0;
while (((((unsigned long)((unsigned int)(bucket)) == 255) | ((long)(bucket) < 255)) != 0)) {
remaining = *(int *)((&local_410[0] + ((long)(bucket) * 4)));
while (((((unsigned long)((unsigned int)(remaining)) == 0) | ((long)(remaining) < 0)) == 0)) {
if ((arg1 <= out)) {
break;
}
arg0[out] = bucket;
out = (out + 1);
remaining = (remaining - 1);
}
bucket = (bucket + 1);
}
ret = (unsigned long)((unsigned int)(arg1));
}
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} radix_sort_u32 pass 50 lines
// glaurung: radix_sort_u32 @ 0x12a0
int32_t radix_sort_u32(uint32_t * arg0, int32_t arg1) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int shift;
int running;
int bucket;
int index;
int occupancy;
int slot;
unsigned char local_50[64];
long local_8;
unsigned char local_90[64];
long ret;
// x86-64 prologue: save rbp, frame 192 bytes
local_8 = (long)(0x28);
if ((((arg0 == 0) || ((long)(arg1) < 0)) || (((unsigned long)((unsigned int)(arg1)) != 16) && (16 <= (long)(arg1))))) {
ret = 0xffffffff;
} else {
shift = 0;
while (((((unsigned long)((unsigned int)(shift)) == 31) | ((long)(shift) < 31)) != 0)) {
running = 0;
for (bucket = 0; ((((unsigned long)((unsigned int)(bucket)) == 15) | ((long)(bucket) < 15)) != 0); bucket++) {
*(int *)((&local_50[0] + ((long)(bucket) * 4))) = 0;
}
for (index = 0; (index < arg1); index++) {
*(int *)((&local_50[0] + ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(index)])) >> ((unsigned long)((unsigned int)(shift)) & 31)))) & 15))) * 4))) = ((unsigned long)((unsigned int)(*(int *)((&local_50[0] + ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(index)])) >> ((unsigned long)((unsigned int)(shift)) & 31)))) & 15))) * 4))))) + 1);
}
for (bucket = 0; ((((unsigned long)((unsigned int)(bucket)) == 15) | ((long)(bucket) < 15)) != 0); bucket++) {
occupancy = *(int *)((&local_50[0] + ((long)(bucket) * 4)));
*(int *)((&local_50[0] + ((long)(bucket) * 4))) = running;
running = (running + (unsigned int)(occupancy));
}
for (index = 0; (index < arg1); index++) {
slot = ((unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(index)])) >> ((unsigned long)((unsigned int)(shift)) & 31))) & 15);
*(int *)((&local_90[0] + ((long)((int)(*(int *)((&local_50[0] + ((long)(slot) * 4))))) * 4))) = arg0[(long)(index)];
*(int *)((&local_50[0] + ((long)(slot) * 4))) = ((unsigned long)((unsigned int)(*(int *)((&local_50[0] + ((long)(slot) * 4))))) + 1);
}
for (index = 0; (index < arg1); index++) {
arg0[(long)(index)] = *(int *)((&local_90[0] + ((long)(index) * 4)));
}
shift = (shift + 4);
}
ret = (unsigned long)((unsigned int)(arg1));
}
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
}