Fixture 47
huffman
C · 2 functions · 4 lanes · 8 of 8 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
Huffman code lengths by repeated two-smallest merging over a flat node array, then the Kraft sum of the resulting lengths. The two-minimum scan carries two indices and two values through one loop body.
#include <stdint.h>
/* Huffman code lengths by repeated two-smallest merging over a flat node
* array, then the Kraft sum of the resulting lengths. The two-minimum scan
* carries two indices and two values through one loop body. */
#define HUFF_SYMBOLS 8
#define HUFF_NODES (2 * HUFF_SYMBOLS)
__attribute__((noinline)) int32_t
huffman_code_lengths(const int32_t *frequencies, int32_t symbols,
int32_t *lengths) {
int32_t weight[HUFF_NODES];
int32_t parent[HUFF_NODES];
int32_t alive[HUFF_NODES];
int32_t nodes;
int32_t index;
int32_t total = 0;
if (frequencies == 0 || lengths == 0 || symbols < 1 ||
symbols > HUFF_SYMBOLS) {
return -1;
}
for (index = 0; index < HUFF_NODES; ++index) {
weight[index] = 0;
parent[index] = -1;
alive[index] = 0;
}
for (index = 0; index < symbols; ++index) {
if (frequencies[index] < 0 || frequencies[index] > 1000) {
return -2;
}
weight[index] = frequencies[index];
alive[index] = 1;
lengths[index] = 0;
}
nodes = symbols;
while (nodes < HUFF_NODES) {
int32_t first = -1;
int32_t second = -1;
int32_t scan;
for (scan = 0; scan < nodes; ++scan) {
if (!alive[scan]) {
continue;
}
if (first < 0 || weight[scan] < weight[first]) {
second = first;
first = scan;
} else if (second < 0 || weight[scan] < weight[second]) {
second = scan;
}
}
if (first < 0 || second < 0) {
break;
}
weight[nodes] = weight[first] + weight[second];
alive[nodes] = 1;
alive[first] = 0;
alive[second] = 0;
parent[first] = nodes;
parent[second] = nodes;
nodes += 1;
}
for (index = 0; index < symbols; ++index) {
int32_t depth = 0;
int32_t walk = index;
while (parent[walk] >= 0 && depth < HUFF_NODES) {
walk = parent[walk];
depth += 1;
}
lengths[index] = depth;
total += depth;
}
return total;
}
__attribute__((noinline)) uint32_t
kraft_sum_q16(const int32_t *lengths, int32_t symbols) {
uint32_t total = 0;
int32_t index;
if (lengths == 0 || symbols < 0 || symbols > HUFF_SYMBOLS) {
return 0;
}
for (index = 0; index < symbols; ++index) {
int32_t length = lengths[index];
if (length > 0 && length < 16) {
total += (uint32_t)65536 >> (uint32_t)length;
}
}
return total;
} 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/2huffman_code_lengths pass 142 lines
// glaurung: huffman_code_lengths @ 0x1100
__attribute__((no_stack_protector)) int32_t huffman_code_lengths(const int32_t * arg0, int32_t arg1, int32_t * arg2) {
int total;
int index;
int nodes;
int first;
int second;
int scan;
int depth;
int walk;
signed char local_101;
int local_4;
unsigned char local_60[64];
unsigned char local_a0[64];
unsigned char local_e0[64];
long t197;
long t204;
total = 0;
if ((arg0 != 0)) {
if ((arg2 != 0)) {
if ((1 <= (long)(arg1))) {
if ((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8))) {
goto L_1156;
}
}
}
}
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_1156: ;
index = 0;
L_1160: ;
if (((long)(index) < 16)) {
*(int *)((&local_60[0] + ((long)(index) * 4))) = 0;
*(int *)((&local_a0[0] + ((long)(index) * 4))) = -1;
*(int *)((&local_e0[0] + ((long)(index) * 4))) = 0;
index = ((unsigned int)(index) + 1);
goto L_1160;
}
index = 0;
L_11be: ;
if ((arg1 <= index)) {
goto L_1257;
}
if ((0 <= (long)((int)(arg0[(long)(index)])))) {
t197 = arg0[(long)(index)];
if ((((unsigned long)((unsigned int)(t197)) == 1000) | ((long)((int)(t197)) < 1000))) {
goto L_1206;
}
}
local_4 = -2;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_1206: ;
*(int *)((&local_60[0] + ((long)(index) * 4))) = arg0[(long)(index)];
*(int *)((&local_e0[0] + ((long)(index) * 4))) = 1;
arg2[(long)(index)] = 0;
index = ((unsigned int)(index) + 1);
goto L_11be;
L_1257: ;
nodes = arg1;
L_1260: ;
if ((16 <= (long)(nodes))) {
goto L_1402;
}
first = -1;
second = -1;
scan = 0;
L_128b: ;
if ((nodes <= scan)) {
goto L_1350;
}
if (((unsigned long)((unsigned int)(*(int *)((&local_e0[0] + ((long)(scan) * 4))))) == 0)) {
goto L_133c;
}
if ((0 <= (long)(first))) {
if (((long)((int)(*(int *)((&local_60[0] + ((long)(first) * 4))))) <= (long)((int)(*(int *)((&local_60[0] + ((long)(scan) * 4))))))) {
goto L_12fd;
}
}
second = first;
first = scan;
goto L_1337;
L_12fd: ;
if ((0 <= (long)(second))) {
if (((long)((int)(*(int *)((&local_60[0] + ((long)(second) * 4))))) <= (long)((int)(*(int *)((&local_60[0] + ((long)(scan) * 4))))))) {
goto L_1332;
}
}
second = scan;
L_1332: ;
goto L_1337;
L_1337: ;
goto L_133c;
L_133c: ;
scan = ((unsigned int)(scan) + 1);
goto L_128b;
L_1350: ;
if ((0 <= (long)(first))) {
if ((0 <= (long)(second))) {
goto L_136f;
}
}
goto L_1402;
L_136f: ;
*(int *)((&local_60[0] + ((long)(nodes) * 4))) = ((unsigned long)((unsigned int)(*(int *)((&local_60[0] + ((long)(first) * 4))))) + *(int *)((&local_60[0] + ((long)(second) * 4))));
*(int *)((&local_e0[0] + ((long)(nodes) * 4))) = 1;
*(int *)((&local_e0[0] + ((long)(first) * 4))) = 0;
*(int *)((&local_e0[0] + ((long)(second) * 4))) = 0;
*(int *)((&local_a0[0] + ((long)(first) * 4))) = nodes;
*(int *)((&local_a0[0] + ((long)(second) * 4))) = nodes;
nodes = ((unsigned int)(nodes) + 1);
goto L_1260;
L_1402: ;
index = 0;
L_140c: ;
if ((arg1 <= index)) {
goto L_14d3;
}
depth = 0;
walk = index;
L_1431: ;
t204 = *(int *)((&local_a0[0] + ((long)(walk) * 4)));
local_101 = 0;
if ((0 <= (long)((int)(t204)))) {
local_101 = ((long)(depth) < 16);
}
if (((unsigned long)((unsigned char)((local_101 & 1))) != 0)) {
walk = *(int *)((&local_a0[0] + ((long)(walk) * 4)));
depth = ((unsigned int)(depth) + 1);
goto L_1431;
}
arg2[(long)(index)] = depth;
total = ((unsigned int)(depth) + total);
index = ((unsigned int)(index) + 1);
goto L_140c;
L_14d3: ;
local_4 = total;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} kraft_sum_q16 pass 32 lines
// glaurung: kraft_sum_q16 @ 0x14f0
uint32_t kraft_sum_q16(const int32_t * arg0, int32_t arg1) {
unsigned int total;
int index;
int length;
int local_4;
// x86-64 prologue: save rbp
total = 0;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if (((long)(arg1) < 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
for (index = 0; (index < arg1); index++) {
length = arg0[(long)(index)];
if (((((unsigned long)((unsigned int)(length)) == 0) | ((long)(length) < 0)) == 0)) {
if (((long)(length) < 16)) {
total = ((unsigned int)(((unsigned long)(0x10000) >> ((unsigned long)((unsigned int)(length)) & 31))) + total);
}
}
}
local_4 = total;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
2/2huffman_code_lengths pass 337 lines
// glaurung: huffman_code_lengths @ 0x1100
__attribute__((no_stack_protector)) int32_t huffman_code_lengths(const int32_t * arg0, int32_t arg1, int32_t * arg2) {
int second;
int nodes;
int first;
int scan;
int index;
int depth;
int total;
int walk;
unsigned char local_48[72];
unsigned char local_88[64];
unsigned char local_c8[64];
long ret;
long t369;
long t373;
long var10;
long var11;
long var13;
long var19;
long var24;
long var25;
long var29;
long var42;
long var44;
long var45;
long var46;
long var47;
long var48;
long var49;
long var50;
long var53;
long var58;
long var61;
long var62;
long var63;
int var64;
long var65;
long var72;
long var73;
long var79;
long var81;
int var85;
long var86;
long var88;
long var91;
// x86-64 prologue: save callee registers, frame 8 bytes
ret = 0xffffffff;
if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 9)))) < (unsigned long)(0xfffffff8))) {
// x86-64 epilogue: restore callee registers
return ret;
}
if ((arg0 == 0)) {
// x86-64 epilogue: restore callee registers
return ret;
}
if ((arg2 == 0)) {
// x86-64 epilogue: restore callee registers
return ret;
}
*(int *)((&local_c8[0] + 48)) = 0;
*(int *)((&local_c8[0] + 52)) = 0;
*(int *)((&local_c8[0] + 56)) = 0;
*(int *)((&local_c8[0] + 60)) = 0;
*(int *)((&local_c8[0] + 32)) = 0;
*(int *)((&local_c8[0] + 36)) = 0;
*(int *)((&local_c8[0] + 40)) = 0;
*(int *)((&local_c8[0] + 44)) = 0;
*(int *)((&local_c8[0] + 16)) = 0;
*(int *)((&local_c8[0] + 20)) = 0;
*(int *)((&local_c8[0] + 24)) = 0;
*(int *)((&local_c8[0] + 28)) = 0;
*(int *)(&local_c8[0]) = 0;
*(int *)((&local_c8[0] + 4)) = 0;
*(int *)((&local_c8[0] + 8)) = 0;
*(int *)((&local_c8[0] + 12)) = 0;
*(int *)(&local_48[0]) = -1;
*(int *)((&local_48[0] + 4)) = -1;
*(int *)((&local_48[0] + 8)) = -1;
*(int *)((&local_48[0] + 12)) = -1;
*(int *)((&local_48[0] + 16)) = -1;
*(int *)((&local_48[0] + 20)) = -1;
*(int *)((&local_48[0] + 24)) = -1;
*(int *)((&local_48[0] + 28)) = -1;
*(int *)((&local_48[0] + 32)) = -1;
*(int *)((&local_48[0] + 36)) = -1;
*(int *)((&local_48[0] + 40)) = -1;
*(int *)((&local_48[0] + 44)) = -1;
*(int *)((&local_48[0] + 48)) = -1;
*(int *)((&local_48[0] + 52)) = -1;
*(int *)((&local_48[0] + 56)) = -1;
*(int *)((&local_48[0] + 60)) = -1;
*(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;
var10 = (unsigned long)((unsigned int)(*(int *)(((long)arg0))));
ret = 0xfffffffe;
if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var10))))) {
// x86-64 epilogue: restore callee registers
return ret;
}
*(int *)(&local_c8[0]) = var10;
*(int *)(&local_88[0]) = 1;
*(int *)(((long)arg2)) = 0;
if (((unsigned long)((unsigned int)(arg1)) != 1)) {
goto L_1277;
}
L_119c: ;
var11 = (unsigned long)((unsigned int)(arg1));
if (((((unsigned long)((unsigned int)(arg1)) == 15) | ((long)(arg1) < 15)) == 0)) {
goto L_125a;
}
second = var13;
nodes = (long)(arg1);
L_11b0: ;
if ((nodes <= 0)) {
goto L_125a;
}
var19 = (unsigned long)((unsigned int)(nodes));
second = 0xffffffff;
var24 = 0;
var25 = 0xffffffff;
goto L_11db;
L_11d0: ;
var25 = (unsigned long)((unsigned int)(first));
L_11d2: ;
scan = (var24 + 1);
var24 = (unsigned long)((unsigned int)(scan));
if ((var19 == scan)) {
goto L_1210;
}
L_11db: ;
first = (unsigned long)((unsigned int)(var25));
if (((unsigned long)((unsigned int)(*(int *)((&local_88[0] + (var24 * 4))))) == 0)) {
goto L_11d0;
}
if ((0 <= (long)(first))) {
var29 = (unsigned long)((unsigned int)(*(int *)((&local_c8[0] + (var24 * 4)))));
if (((long)((int)(*(int *)((&local_c8[0] + ((unsigned long)((unsigned int)(first)) * 4))))) <= (long)((int)(var29)))) {
goto L_11fb;
}
}
second = (unsigned long)((unsigned int)(first));
var25 = (unsigned long)((unsigned int)(var24));
goto L_11d2;
L_11fb: ;
if ((0 <= (long)(second))) {
if (((long)((int)(*(int *)((&local_c8[0] + ((unsigned long)((unsigned int)(second)) * 4))))) <= (long)((int)(var29)))) {
goto L_11d0;
}
}
second = (unsigned long)((unsigned int)(var24));
var25 = (unsigned long)((unsigned int)(first));
goto L_11d2;
L_1210: ;
if (((long)((int)(var25)) < 0)) {
goto L_125a;
}
if (((long)(second) < 0)) {
goto L_125a;
}
*(int *)((&local_c8[0] + (nodes * 4))) = ((unsigned long)((unsigned int)(*(int *)((&local_c8[0] + ((unsigned long)((unsigned int)(second)) * 4))))) + *(int *)((&local_c8[0] + ((unsigned long)((unsigned int)(var25)) * 4))));
*(int *)((&local_88[0] + (nodes * 4))) = 1;
*(int *)((&local_88[0] + ((unsigned long)((unsigned int)(var25)) * 4))) = 0;
*(int *)((&local_88[0] + ((unsigned long)((unsigned int)(second)) * 4))) = 0;
*(int *)((&local_48[0] + ((unsigned long)((unsigned int)(var25)) * 4))) = nodes;
*(int *)((&local_48[0] + ((unsigned long)((unsigned int)(second)) * 4))) = nodes;
nodes = (nodes + 1);
if (((unsigned long)((unsigned int)(nodes)) != 16)) {
goto L_11b0;
}
L_125a: ;
if (((unsigned long)((unsigned int)(arg1)) != 1)) {
goto L_13a0;
}
var42 = 0;
index = 0;
if (((unsigned long)((unsigned char)((var11 & 1))) != 0)) {
goto L_1433;
}
// x86-64 epilogue: restore callee registers
return var42;
L_1277: ;
var44 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x4))));
if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var44))))) {
// x86-64 epilogue: restore callee registers
return ret;
}
*(int *)((&local_c8[0] + 4)) = var44;
*(int *)((&local_88[0] + 4)) = 1;
*(int *)(((long)arg2 + 0x4)) = 0;
if (((unsigned long)((unsigned int)(arg1)) == 2)) {
goto L_119c;
}
var45 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x8))));
if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var45))))) {
// x86-64 epilogue: restore callee registers
return ret;
}
*(int *)((&local_c8[0] + 8)) = var45;
*(int *)((&local_88[0] + 8)) = 1;
*(int *)(((long)arg2 + 0x8)) = 0;
if (((unsigned long)((unsigned int)(arg1)) == 3)) {
goto L_119c;
}
var46 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0xc))));
if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var46))))) {
// x86-64 epilogue: restore callee registers
return ret;
}
*(int *)((&local_c8[0] + 12)) = var46;
*(int *)((&local_88[0] + 12)) = 1;
*(int *)(((long)arg2 + 0xc)) = 0;
if (((unsigned long)((unsigned int)(arg1)) == 4)) {
goto L_119c;
}
var47 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x10))));
if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var47))))) {
// x86-64 epilogue: restore callee registers
return ret;
}
*(int *)((&local_c8[0] + 16)) = var47;
*(int *)((&local_88[0] + 16)) = 1;
*(int *)(((long)arg2 + 0x10)) = 0;
if (((unsigned long)((unsigned int)(arg1)) == 5)) {
goto L_119c;
}
var48 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x14))));
if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var48))))) {
// x86-64 epilogue: restore callee registers
return ret;
}
*(int *)((&local_c8[0] + 20)) = var48;
*(int *)((&local_88[0] + 20)) = 1;
*(int *)(((long)arg2 + 0x14)) = 0;
if (((unsigned long)((unsigned int)(arg1)) == 6)) {
goto L_119c;
}
var49 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x18))));
if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var49))))) {
// x86-64 epilogue: restore callee registers
return ret;
}
*(int *)((&local_c8[0] + 24)) = var49;
*(int *)((&local_88[0] + 24)) = 1;
*(int *)(((long)arg2 + 0x18)) = 0;
if (((unsigned long)((unsigned int)(arg1)) == 7)) {
goto L_119c;
}
var50 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x1c))));
if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var50))))) {
// x86-64 epilogue: restore callee registers
return ret;
}
*(int *)((&local_c8[0] + 28)) = var50;
*(int *)((&local_88[0] + 28)) = 1;
*(int *)(((long)arg2 + 0x1c)) = 0;
goto L_119c;
L_13a0: ;
var53 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var11)) & -2)));
index = 0;
var58 = 0;
goto L_13c9;
L_13b0: ;
*(int *)(((long)arg2 + var61 * 4)) = (depth - 1);
var64 = (var62 + var63);
var65 = (unsigned long)((unsigned int)(var64));
index = (index + 2);
var58 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((depth + (unsigned long)((unsigned int)(var64))))) - 2)));
if ((index == var53)) {
goto L_1426;
}
L_13c9: ;
var62 = (unsigned long)((unsigned int)(var58));
var72 = 0;
var73 = (unsigned long)((unsigned int)(index));
L_13e0: ;
var73 = (unsigned long)((unsigned int)(*(int *)((&local_48[0] + ((long)((int)(var73)) * 4)))));
var63 = (unsigned long)((unsigned int)((var72 + 1)));
if ((0 <= (long)((int)(var73)))) {
t369 = (unsigned long)((unsigned int)(var72));
var72 = (unsigned long)((unsigned int)(var63));
if (((unsigned long)(t369) < (unsigned long)(16))) {
goto L_13e0;
}
}
*(int *)(((long)arg2 + index * 4)) = (var63 - 1);
var61 = ((unsigned long)((unsigned int)(index)) | 1);
var79 = 0;
var81 = (unsigned long)((unsigned int)(var61));
do {
var81 = (unsigned long)((unsigned int)(*(int *)((&local_48[0] + ((long)((int)(var81)) * 4)))));
depth = (unsigned long)((unsigned int)((var79 + 1)));
if (((long)((int)(var81)) < 0)) {
goto L_13b0;
}
t373 = (unsigned long)((unsigned int)(var79));
var79 = (unsigned long)((unsigned int)(depth));
} while (((unsigned long)(t373) < (unsigned long)(16)));
goto L_13b0;
L_1426: ;
var85 = ((unsigned int)((depth + var65)) - 2);
var42 = (unsigned long)((unsigned int)(var85));
ret = (unsigned long)((unsigned int)(var85));
if (((unsigned long)((unsigned char)((var11 & 1))) == 0)) {
// x86-64 epilogue: restore callee registers
return ret;
}
L_1433: ;
var86 = 0xffffffff;
var88 = (unsigned long)((unsigned int)(index));
L_1440: ;
var86 = (unsigned long)((unsigned int)((var86 + 1)));
var91 = (unsigned long)((unsigned int)(*(int *)((&local_48[0] + ((long)((int)(var88)) * 4)))));
if ((0 <= (long)((int)(var91)))) {
var88 = var91;
if (((unsigned long)((unsigned long)((unsigned int)(var86))) < (unsigned long)(16))) {
goto L_1440;
}
}
*(int *)(((long)arg2 + index * 4)) = var86;
// x86-64 epilogue: restore callee registers
return (unsigned int)((var42 + var86));
} kraft_sum_q16 pass 79 lines
// glaurung: kraft_sum_q16 @ 0x1460
uint32_t kraft_sum_q16(const int32_t * arg0, int32_t arg1) {
int index;
int length;
unsigned int total;
long ret;
long var12;
long var13;
int var19;
long var21;
long var3;
int var32;
long var34;
int var40;
long var42;
int var53;
long var55;
int var61;
long var63;
int var70;
long var72;
int var74;
long var75;
long var76;
ret = 0;
if (((unsigned long)((unsigned long)((unsigned int)((arg1 - 1)))) <= (unsigned long)(7))) {
ret = 0;
if ((arg0 == 0)) {
return ret;
}
var3 = (unsigned long)((unsigned int)(*(int *)(((long)arg0))));
var12 = (((unsigned long)(15) <= (unsigned long)((unsigned long)((unsigned int)((var3 - 1))))) ? 0 : (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var3 & 31)))));
ret = var12;
if (((unsigned long)((unsigned int)(arg1)) == 1)) {
return ret;
}
var13 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x4))));
var19 = (var12 + (((unsigned long)((unsigned long)((unsigned int)((var13 - 1)))) < (unsigned long)(15)) ? (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var13 & 31)))) : 0));
ret = (unsigned long)((unsigned int)(var19));
if (((unsigned long)((unsigned int)(arg1)) == 2)) {
return ret;
}
var21 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x8))));
var32 = ((unsigned int)(var19) + (((unsigned long)(15) <= (unsigned long)((unsigned long)((unsigned int)((var21 - 1))))) ? 0 : (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var21 & 31))))));
ret = (unsigned long)((unsigned int)(var32));
if (((unsigned long)((unsigned int)(arg1)) == 3)) {
return ret;
}
var34 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0xc))));
var40 = ((unsigned int)(var32) + (((unsigned long)((unsigned long)((unsigned int)((var34 - 1)))) < (unsigned long)(15)) ? (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var34 & 31)))) : 0));
ret = (unsigned long)((unsigned int)(var40));
if (((unsigned long)((unsigned int)(arg1)) == 4)) {
return ret;
}
var42 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x10))));
var53 = ((unsigned int)(var40) + (((unsigned long)(15) <= (unsigned long)((unsigned long)((unsigned int)((var42 - 1))))) ? 0 : (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var42 & 31))))));
ret = (unsigned long)((unsigned int)(var53));
if (((unsigned long)((unsigned int)(arg1)) == 5)) {
return ret;
}
var55 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x14))));
var61 = ((unsigned int)(var53) + (((unsigned long)((unsigned long)((unsigned int)((var55 - 1)))) < (unsigned long)(15)) ? (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var55 & 31)))) : 0));
ret = (unsigned long)((unsigned int)(var61));
if (((unsigned long)((unsigned int)(arg1)) == 6)) {
return ret;
}
var63 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x18))));
var70 = 0x10000;
var72 = 0;
var74 = ((unsigned int)(var61) + (((unsigned long)(15) <= (unsigned long)((unsigned long)((unsigned int)((var63 - 1))))) ? 0 : (unsigned long)((unsigned int)(((unsigned long)(0x10000) >> (var63 & 31))))));
var75 = (unsigned long)((unsigned int)(var74));
ret = (unsigned long)((unsigned int)(var74));
if (((unsigned long)((unsigned int)(arg1)) != 7)) {
var76 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + 0x1c))));
ret = (unsigned long)((unsigned int)((var75 + (((unsigned long)((unsigned long)((unsigned int)((var76 - 1)))) < (unsigned long)(15)) ? (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var70)) >> (var76 & 31)))) : var72))));
}
}
return ret;
} gcc -O0
2/2huffman_code_lengths pass 146 lines
// glaurung: huffman_code_lengths @ 0x1119
int32_t huffman_code_lengths(const int32_t * arg0, int32_t arg1, int32_t * arg2) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int total;
int index;
int nodes;
int first;
int second;
int scan;
int depth;
int walk;
unsigned char local_50[64];
long local_8;
unsigned char local_90[64];
unsigned char local_d0[64];
long ret;
long var20;
local_8 = (long)(0x28);
total = 0;
if ((arg0 != 0)) {
if ((arg2 != 0)) {
if (((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0)) == 0)) {
if ((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8))) {
goto L_1185;
}
}
}
}
ret = 0xffffffff;
goto L_14e6;
L_1185: ;
index = 0;
goto L_11ce;
L_1191: ;
*(int *)((&local_d0[0] + ((long)(index) * 4))) = 0;
*(int *)((&local_90[0] + ((long)(index) * 4))) = -1;
*(int *)((&local_50[0] + ((long)(index) * 4))) = 0;
index = (index + 1);
L_11ce: ;
if ((((unsigned long)((unsigned int)(index)) == 15) | ((long)(index) < 15))) {
goto L_1191;
}
index = 0;
goto L_1295;
L_11e6: ;
if ((0 <= (long)((int)(arg0[(long)(index)])))) {
var20 = (unsigned long)((unsigned int)(arg0[(long)(index)]));
if ((((unsigned long)((unsigned int)(var20)) == 1000) | ((long)((int)(var20)) < 1000))) {
goto L_1233;
}
}
ret = 0xfffffffe;
goto L_14e6;
L_1233: ;
*(int *)((&local_d0[0] + ((long)(index) * 4))) = arg0[(long)(index)];
*(int *)((&local_50[0] + ((long)(index) * 4))) = 1;
arg2[(long)(index)] = 0;
index = (index + 1);
L_1295: ;
if ((index < arg1)) {
goto L_11e6;
}
nodes = arg1;
goto L_142d;
L_12b8: ;
first = -1;
second = -1;
scan = 0;
goto L_1371;
L_12db: ;
if (((unsigned long)((unsigned int)(*(int *)((&local_50[0] + ((long)(scan) * 4))))) == 0)) {
goto L_1369;
}
if ((0 <= (long)(first))) {
if (((long)((int)(*(int *)((&local_d0[0] + ((long)(first) * 4))))) <= (long)((int)(*(int *)((&local_d0[0] + ((long)(scan) * 4))))))) {
goto L_1330;
}
}
second = first;
first = scan;
goto L_136a;
L_1330: ;
if ((0 <= (long)(second))) {
if (((long)((int)(*(int *)((&local_d0[0] + ((long)(second) * 4))))) <= (long)((int)(*(int *)((&local_d0[0] + ((long)(scan) * 4))))))) {
goto L_136a;
}
}
second = scan;
goto L_136a;
L_1369: ;
L_136a: ;
scan = (scan + 1);
L_1371: ;
if ((scan < nodes)) {
goto L_12db;
}
if (((long)(first) < 0)) {
goto L_143a;
}
if (((long)(second) < 0)) {
goto L_143a;
}
*(int *)((&local_d0[0] + ((long)(nodes) * 4))) = ((unsigned long)((unsigned int)(*(int *)((&local_d0[0] + ((long)(first) * 4))))) + (unsigned long)((unsigned int)(*(int *)((&local_d0[0] + ((long)(second) * 4))))));
*(int *)((&local_50[0] + ((long)(nodes) * 4))) = 1;
*(int *)((&local_50[0] + ((long)(first) * 4))) = 0;
*(int *)((&local_50[0] + ((long)(second) * 4))) = 0;
*(int *)((&local_90[0] + ((long)(first) * 4))) = nodes;
*(int *)((&local_90[0] + ((long)(second) * 4))) = nodes;
nodes = (nodes + 1);
L_142d: ;
if ((((unsigned long)((unsigned int)(nodes)) == 15) | ((long)(nodes) < 15))) {
goto L_12b8;
}
L_143a: ;
index = 0;
goto L_14ce;
L_1449: ;
depth = 0;
walk = index;
goto L_147d;
L_1461: ;
walk = *(int *)((&local_90[0] + ((long)(walk) * 4)));
depth = (depth + 1);
L_147d: ;
if ((0 <= (long)((int)(*(int *)((&local_90[0] + ((long)(walk) * 4))))))) {
if ((((unsigned long)((unsigned int)(depth)) == 15) | ((long)(depth) < 15))) {
goto L_1461;
}
}
arg2[(long)(index)] = depth;
total = (total + (unsigned int)(depth));
index = (index + 1);
L_14ce: ;
if ((index < arg1)) {
goto L_1449;
}
ret = (unsigned long)((unsigned int)(total));
L_14e6: ;
if ((local_8 == 0x28)) {
// x86-64 epilogue: restore rbp
return ret;
}
__stack_chk_fail();
// x86-64 epilogue: restore rbp
return ret;
} kraft_sum_q16 pass 30 lines
// glaurung: kraft_sum_q16 @ 0x14fc
uint32_t kraft_sum_q16(const int32_t * arg0, int32_t arg1) {
unsigned int total;
int index;
int length;
// x86-64 prologue: save rbp
total = 0;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if (((long)(arg1) < 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
if (((((unsigned long)((unsigned int)(arg1)) == 8) | ((long)(arg1) < 8)) == 0)) {
// x86-64 epilogue: restore rbp
return 0;
}
for (index = 0; (index < arg1); index++) {
length = arg0[(long)(index)];
if (((((unsigned long)((unsigned int)(length)) == 0) | ((long)(length) < 0)) == 0)) {
if (((((unsigned long)((unsigned int)(length)) == 15) | ((long)(length) < 15)) != 0)) {
total = (total + (unsigned int)(((unsigned long)(0x10000) >> ((unsigned long)((unsigned int)(length)) & 31))));
}
}
}
// x86-64 epilogue: restore rbp
return total;
} gcc -O2
2/2huffman_code_lengths pass 221 lines
// glaurung: huffman_code_lengths @ 0x1120
int32_t huffman_code_lengths(const int32_t * arg0, int32_t arg1, int32_t * arg2) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int index;
int nodes;
int second;
int first;
int depth;
int scan;
int total;
int walk;
long rbp;
unsigned char stack_0[64];
unsigned char stack_1[64];
unsigned char stack_2[120];
long var16;
long var18;
long var21;
long var23;
long var25;
long var3;
long var32;
long var35;
long var36;
long var37;
int var44;
long var46;
long var48;
long var5;
long var50;
long var52;
long var57;
long var58;
// x86-64 prologue: save callee registers, frame 32 bytes
*(long *)((&stack_2[0] + 72)) = (long)((long)(0x28));
if ((arg0 == 0)) {
goto L_1350;
}
var3 = (long)arg2;
if ((arg2 == 0)) {
goto L_1350;
}
var5 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)(7) < (unsigned long)((unsigned long)((unsigned int)((arg1 - 1)))))) {
goto L_1350;
}
index = 0;
*(int *)(&stack_0[0]) = 0;
*(int *)((&stack_0[0] + 4)) = 0;
*(int *)((&stack_0[0] + 8)) = 0;
*(int *)((&stack_0[0] + 12)) = 0;
*(int *)((&stack_0[0] + 16)) = 0;
*(int *)((&stack_0[0] + 20)) = 0;
*(int *)((&stack_0[0] + 24)) = 0;
*(int *)((&stack_0[0] + 28)) = 0;
*(int *)((&stack_0[0] + 32)) = 0;
*(int *)((&stack_0[0] + 36)) = 0;
*(int *)((&stack_0[0] + 40)) = 0;
*(int *)((&stack_0[0] + 44)) = 0;
*(int *)((&stack_0[0] + 48)) = 0;
*(int *)((&stack_0[0] + 52)) = 0;
*(int *)((&stack_0[0] + 56)) = 0;
*(int *)((&stack_0[0] + 60)) = 0;
*(int *)(&stack_1[0]) = -1;
*(int *)((&stack_1[0] + 4)) = -1;
*(int *)((&stack_1[0] + 8)) = -1;
*(int *)((&stack_1[0] + 12)) = -1;
*(int *)((&stack_1[0] + 16)) = -1;
*(int *)((&stack_1[0] + 20)) = -1;
*(int *)((&stack_1[0] + 24)) = -1;
*(int *)((&stack_1[0] + 28)) = -1;
*(int *)((&stack_1[0] + 32)) = -1;
*(int *)((&stack_1[0] + 36)) = -1;
*(int *)((&stack_1[0] + 40)) = -1;
*(int *)((&stack_1[0] + 44)) = -1;
*(int *)((&stack_1[0] + 48)) = -1;
*(int *)((&stack_1[0] + 52)) = -1;
*(int *)((&stack_1[0] + 56)) = -1;
*(int *)((&stack_1[0] + 60)) = -1;
*(int *)(&stack_2[0]) = 0;
*(int *)((&stack_2[0] + 4)) = 0;
*(int *)((&stack_2[0] + 8)) = 0;
*(int *)((&stack_2[0] + 12)) = 0;
*(int *)((&stack_2[0] + 16)) = 0;
*(int *)((&stack_2[0] + 20)) = 0;
*(int *)((&stack_2[0] + 24)) = 0;
*(int *)((&stack_2[0] + 28)) = 0;
*(int *)((&stack_2[0] + 32)) = 0;
*(int *)((&stack_2[0] + 36)) = 0;
*(int *)((&stack_2[0] + 40)) = 0;
*(int *)((&stack_2[0] + 44)) = 0;
*(int *)((&stack_2[0] + 48)) = 0;
*(int *)((&stack_2[0] + 52)) = 0;
*(int *)((&stack_2[0] + 56)) = 0;
*(int *)((&stack_2[0] + 60)) = 0;
do {
var16 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + index * 4))));
if (((unsigned long)(1000) < (unsigned long)((unsigned long)((unsigned int)(var16))))) {
goto L_1348;
}
rbp = (long)(&stack_0[0]);
*(int *)((var3 + index * 4)) = 0;
*(int *)((rbp + index * 4)) = var16;
*(int *)((&stack_2[0] + (index * 4))) = 1;
var18 = ((unsigned long)((unsigned int)(index)) + 1);
index = var18;
} while (((((unsigned int)(var5) == (unsigned int)(var18)) | ((long)((int)(var5)) < (long)((int)(var18)))) == 0));
nodes = (long)((int)(var5));
L_1200: ;
var23 = (unsigned long)((unsigned int)(nodes));
var25 = 0;
var21 = 0;
second = -1;
first = -1;
goto L_124d;
L_1220: ;
var32 = (unsigned long)((unsigned int)(*(int *)((rbp + var25))));
if (((long)((int)(var32)) < (long)((int)(*(int *)((&stack_0[0] + ((long)(first) * 4))))))) {
goto L_1270;
}
if (((unsigned long)((unsigned int)(second)) == 0xffffffff)) {
goto L_1330;
}
second = (((long)((int)(var32)) < (long)((int)(*(int *)((&stack_0[0] + ((long)(second) * 4)))))) ? var21 : (unsigned long)((unsigned int)(second)));
L_1242: ;
var36 = (unsigned long)((unsigned int)(second));
var37 = (unsigned long)((unsigned int)(first));
if (((long)(nodes) <= (long)((int)(var35)))) {
goto L_127a;
}
L_1246: ;
var25 = (var25 + 4);
var21 = (long)((int)(var35));
L_124d: ;
var32 = (unsigned long)((unsigned int)(*(int *)((&stack_2[0] + var25))));
var35 = (unsigned long)((unsigned int)((var21 + 1)));
if (((unsigned long)((unsigned int)(var32)) == 0)) {
goto L_1242;
}
if (((unsigned long)((unsigned int)(first)) != 0xffffffff)) {
goto L_1220;
}
if (((long)(nodes) <= (long)((int)(var35)))) {
goto L_12bf;
}
second = -1;
first = (long)((int)(var21));
goto L_1246;
L_1270: ;
var36 = (long)(first);
var37 = (long)((int)(var21));
second = (long)(first);
first = (long)((int)(var21));
if (((long)((int)(var35)) < (long)(nodes))) {
goto L_1246;
}
L_127a: ;
if (((long)((int)(((unsigned long)((unsigned int)(var37)) | var36))) < 0)) {
goto L_12bf;
}
var44 = ((unsigned int)(*(int *)((&stack_0[0] + (var36 * 4)))) + *(int *)((&stack_0[0] + (var37 * 4))));
var18 = (unsigned long)((unsigned int)(var44));
*(int *)((&stack_1[0] + (var37 * 4))) = var23;
*(int *)((&stack_2[0] + (nodes * 4))) = 1;
*(int *)((rbp + nodes * 4)) = var44;
nodes = (nodes + 1);
*(int *)((&stack_2[0] + (var37 * 4))) = 0;
*(int *)((&stack_1[0] + (var36 * 4))) = var23;
*(int *)((&stack_2[0] + (var36 * 4))) = 0;
if (((unsigned long)((unsigned int)(nodes)) != 16)) {
goto L_1200;
}
L_12bf: ;
var46 = 0;
var48 = 0;
L_12d0: ;
var50 = (long)((int)(*(int *)((&stack_1[0] + (var46 * 4)))));
var52 = 0;
depth = 0;
if (((long)((int)(var50)) < 0)) {
goto L_12f5;
}
depth = var52;
do {
var50 = (long)((int)(*(int *)((&stack_1[0] + (var50 * 4)))));
depth = (unsigned long)((unsigned int)((depth + 1)));
if (((long)((int)(var50)) < 0)) {
goto L_1340;
}
} while (((unsigned long)((unsigned int)(depth)) != 16));
var48 = (unsigned long)((unsigned int)((var48 + 16)));
L_12f5: ;
*(int *)((var3 + var46 * 4)) = depth;
var57 = (var46 + 1);
var46 = var57;
var35 = (unsigned long)((unsigned int)(depth));
var58 = var48;
if (((((unsigned int)(var5) == (unsigned int)(var57)) | ((long)((int)(var5)) < (long)((int)(var57)))) == 0)) {
goto L_12d0;
}
L_1302: ;
if ((*(long *)((&stack_2[0] + 72)) != 0x28)) {
goto L_1358;
}
// x86-64 epilogue: restore callee registers
return (unsigned int)(var58);
L_1330: ;
second = (long)((int)(var21));
goto L_1242;
L_1340: ;
var48 = (unsigned long)((unsigned int)((var48 + depth)));
goto L_12f5;
L_1348: ;
var58 = 0xfffffffe;
goto L_1302;
L_1350: ;
var58 = 0xffffffff;
goto L_1302;
L_1358: ;
__stack_chk_fail();
} kraft_sum_q16 pass 31 lines
// glaurung: kraft_sum_q16 @ 0x1360
uint32_t kraft_sum_q16(const int32_t * arg0, int32_t arg1) {
int index;
int length;
unsigned int total;
long ret;
long var2;
long var3;
int var4;
long var5;
long var6;
long var7;
ret = 0;
if ((arg0 != 0)) {
var2 = (unsigned long)((unsigned int)((arg1 - 1)));
if (((unsigned long)(7) < (unsigned long)((unsigned long)((unsigned int)(var2))))) {
return ret;
}
var3 = (long)((((long)arg0 + (var2 * 4)) + 4));
var4 = 0x10000;
var5 = 0;
var6 = (long)arg0;
do {
var7 = (unsigned long)((unsigned int)(*(int *)((var6))));
ret = (((unsigned long)(15) <= (unsigned long)((unsigned long)((unsigned int)((var7 - 1))))) ? (unsigned long)((unsigned int)(var5)) : (unsigned long)((unsigned int)((var5 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var4)) >> (var7 & 31))))))));
var6 = (var6 + 4);
var5 = ret;
} while ((var6 != var3));
}
return ret;
}