Fixture 137
cpp templates
C++ · 5 functions · 4 lanes · 16 of 20 function-lanes behave identically
2 of 4 lanes have a function that returns a different result after decompilation: clang-O2 (3/5), gcc-O2 (3/5).
Templates are monomorphized: one source body becomes several distinct functions whose code differs only by operand width and operation. They are near-clones in the binary, mangled to different symbols, and a decompiler must neither merge them nor treat them as unrelated.
/* 137_cpp_templates.cpp
*
* Templates are monomorphized: one source body becomes several distinct
* functions whose code differs only by operand width and operation. They are
* near-clones in the binary, mangled to different symbols, and a decompiler must
* neither merge them nor treat them as unrelated.
*/
#include <stdint.h>
namespace {
template <typename T>
T accumulate_range(const T *values, int32_t count, T seed) {
T total = seed;
for (int32_t index = 0; index < count; ++index) {
total = static_cast<T>(total + values[index]);
}
return total;
}
template <typename T>
int32_t count_above(const T *values, int32_t count, T threshold) {
int32_t hits = 0;
for (int32_t index = 0; index < count; ++index) {
if (values[index] > threshold) {
hits += 1;
}
}
return hits;
}
/* A non-type template parameter: the bound is baked into each instantiation. */
template <int32_t Stride>
int32_t strided_sum(const int32_t *values, int32_t count) {
int32_t total = 0;
for (int32_t index = 0; index < count; index += Stride) {
total += values[index];
}
return total;
}
} // namespace
extern "C" int32_t cpp_template_int32(const int32_t *values, int32_t count) {
if (values == 0 || count < 0 || count > 16) {
return -1;
}
return accumulate_range<int32_t>(values, count, 0);
}
extern "C" int32_t cpp_template_int16(const int32_t *values, int32_t count) {
int16_t narrowed[16];
if (values == 0 || count < 0 || count > 16) {
return -1;
}
for (int32_t index = 0; index < count; ++index) {
narrowed[index] = static_cast<int16_t>(values[index]);
}
/* A distinct instantiation: 16-bit arithmetic wraps differently. */
return accumulate_range<int16_t>(narrowed, count, 0);
}
extern "C" int32_t cpp_template_uint8(const int32_t *values, int32_t count) {
uint8_t narrowed[16];
if (values == 0 || count < 0 || count > 16) {
return -1;
}
for (int32_t index = 0; index < count; ++index) {
narrowed[index] = static_cast<uint8_t>(values[index]);
}
return accumulate_range<uint8_t>(narrowed, count, 0);
}
extern "C" int32_t cpp_template_predicate(const int32_t *values, int32_t count,
int32_t threshold) {
if (values == 0 || count < 0 || count > 16) {
return -1;
}
return count_above<int32_t>(values, count, threshold);
}
extern "C" int32_t cpp_template_nontype(const int32_t *values, int32_t count,
int32_t which) {
if (values == 0 || count < 0 || count > 16) {
return -1;
}
/* Two instantiations with the stride folded in as a constant. */
return (which & 1) ? strided_sum<1>(values, count)
: strided_sum<2>(values, 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 -O2
3/5cpp_template_int16 fail 128 lines
// glaurung: cpp_template_int16 @ 0x1190
__attribute__((no_stack_protector)) int32_t cpp_template_int16(const int32_t * arg0, int32_t arg1) {
int index;
short total;
unsigned char local_28[40];
long ret;
long t270;
long t271;
long t272;
long t86;
long var0;
long var100;
long var118;
long var119;
long var122;
long var4;
long var77;
long var78;
long var81;
long var84;
long var85;
int var90;
long var92;
long var98;
var0 = 0xffffffff;
ret = 0xffffffff;
if ((arg0 == 0)) {
return ret;
}
ret = 0xffffffff;
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var0 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)(4) <= (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
var4 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) & -4)));
t86 = ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x8)))) | ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0xc)))) << 16));
*(int *)(&local_28[0]) = ((unsigned int)((unsigned short)(*(int *)(((long)arg0)))) | ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x4)))) << 16));
*(int *)((&local_28[0] + 4)) = t86;
if ((var4 != 4)) {
t270 = ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x18)))) | ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x1c)))) << 16));
*(int *)((&local_28[0] + 8)) = ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x10)))) | ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x14)))) << 16));
*(int *)((&local_28[0] + 12)) = t270;
if (((unsigned long)((unsigned int)(var4)) != 8)) {
t271 = ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x28)))) | ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x2c)))) << 16));
*(int *)((&local_28[0] + 16)) = ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x20)))) | ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x24)))) << 16));
*(int *)((&local_28[0] + 20)) = t271;
if (((unsigned long)((unsigned int)(var4)) != 12)) {
t272 = ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x38)))) | ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x3c)))) << 16));
*(int *)((&local_28[0] + 24)) = ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x30)))) | ((unsigned int)((unsigned short)(*(int *)(((long)arg0 + 0x34)))) << 16));
*(int *)((&local_28[0] + 28)) = t272;
}
}
}
if ((var4 != var0)) {
L_1240: ;
do {
*(short *)((&local_28[0] + (var4 * 2))) = *(short *)(((long)arg0 + var4 * 4));
index = (var4 + 1);
var4 = (unsigned long)((unsigned int)(index));
} while ((var0 != index));
}
} else {
var4 = 0;
goto L_1240;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
if (((unsigned long)(8) <= (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
var77 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) & -8)));
var78 = (var77 - 8);
var81 = (((unsigned long)(var78) >> 3) + 1);
var84 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var81)) & 7)));
if (((unsigned long)(56) <= (unsigned long)(var78))) {
var85 = (var81 & -8);
var90 = 0;
var92 = 0;
do {
/* asm: paddw */
/* asm: paddw */
/* asm: paddw */
/* asm: paddw */
/* asm: paddw */
/* asm: paddw */
/* asm: paddw */
/* asm: paddw */
var92 = (var92 + 64);
var85 = (var85 - 8);
var81 = var85;
} while ((var85 != 0));
} else {
var90 = 0;
}
if ((var84 != 0)) {
var98 = (var84 << 4);
var100 = 0;
do {
/* asm: paddw */
var100 = (var100 + 16);
} while ((var98 != var100));
}
/* asm: paddw */
ret = (unsigned long)((unsigned int)(var90));
/* asm: paddw */
/* asm: paddw */
var118 = (unsigned long)((unsigned int)(((unsigned int)(var90) >> 16)));
var119 = var118;
if ((var77 != var0)) {
L_1330: ;
do {
total = (((var118 & 0xffff) + *(short *)((&local_28[0] + (var77 * 2)))) & 0xffff);
var122 = (var77 + 1);
var77 = var122;
var118 = (unsigned long)((unsigned short)(total));
var119 = (unsigned long)((unsigned short)(total));
} while ((var0 != var122));
}
} else {
var77 = 0;
var118 = 0;
goto L_1330;
}
return (int)((short)((var119 & 0xffff)));
} cpp_template_int32 pass 68 lines
// glaurung: cpp_template_int32 @ 0x1100
int32_t cpp_template_int32(const int32_t * arg0, int32_t arg1) {
int total;
int index;
long ret;
long var2;
long var41;
long var5;
int var6;
int var7;
int var8;
int var9;
ret = 0xffffffff;
if ((arg0 == 0)) {
return ret;
}
ret = 0xffffffff;
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var2 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)(4) <= (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
var5 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var2)) & -4)));
var6 = *(int *)(((long)arg0));
var7 = *(int *)(((long)arg0 + 0x4));
var8 = *(int *)(((long)arg0 + 0x8));
var9 = *(int *)(((long)arg0 + 0xc));
if ((var5 != 4)) {
var6 = (var6 + *(int *)(((long)arg0 + 0x10)));
var7 = (var7 + *(int *)(((long)arg0 + 0x14)));
var8 = (var8 + *(int *)(((long)arg0 + 0x18)));
var9 = (var9 + *(int *)(((long)arg0 + 0x1c)));
if (((unsigned long)((unsigned int)(var5)) != 8)) {
var6 = (var6 + *(int *)(((long)arg0 + 0x20)));
var7 = (var7 + *(int *)(((long)arg0 + 0x24)));
var8 = (var8 + *(int *)(((long)arg0 + 0x28)));
var9 = (var9 + *(int *)(((long)arg0 + 0x2c)));
if (((unsigned long)((unsigned int)(var5)) != 12)) {
var6 = (var6 + *(int *)(((long)arg0 + 0x30)));
var7 = (var7 + *(int *)(((long)arg0 + 0x34)));
var8 = (var8 + *(int *)(((long)arg0 + 0x38)));
var9 = (var9 + *(int *)(((long)arg0 + 0x3c)));
}
}
}
var41 = (unsigned long)((unsigned int)(((var9 + var7) + (var8 + var6))));
ret = var41;
if ((var5 == var2)) {
return ret;
}
L_1180: ;
do {
total = (var41 + *(int *)(((long)arg0 + var5 * 4)));
index = (var5 + 1);
var41 = (unsigned long)((unsigned int)(total));
var5 = (unsigned long)((unsigned int)(index));
ret = (unsigned long)((unsigned int)(total));
} while ((var2 != index));
} else {
var41 = 0;
var5 = 0;
goto L_1180;
}
return ret;
} cpp_template_nontype pass 141 lines
// glaurung: cpp_template_nontype @ 0x1610
int32_t cpp_template_nontype(const int32_t * arg0, int32_t arg1, int32_t arg2) {
int total;
int index;
long ret;
long var1;
int var122;
long var124;
long var14;
long var15;
long var18;
long var2;
long var21;
long var24;
int var26;
int var27;
int var28;
int var29;
long var31;
int var33;
int var34;
int var35;
int var36;
long var7;
long var8;
long var83;
int var87;
int var88;
int var89;
long var9;
int var90;
ret = 0xffffffff;
if ((arg0 == 0)) {
return ret;
}
ret = 0xffffffff;
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned char)((arg2 & 1))) == 0)) {
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
goto L_165d;
}
var1 = (unsigned long)((unsigned int)(arg1));
var2 = ((unsigned long)((unsigned int)(arg1)) - 1);
if (((unsigned long)(16) <= (unsigned long)(var2))) {
goto L_1660;
}
var7 = 0;
var8 = 0;
goto L_16e0;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
goto L_165d;
}
var9 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)(4) <= (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
goto L_16ee;
}
var14 = 0;
var15 = 0;
goto L_1740;
L_165d: ;
return 0;
L_1660: ;
var18 = (((unsigned long)(var2) >> 1) + 1);
var21 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var18)) & 7)));
var24 = (var18 - ((var21 != 0) ? var21 : 8));
var8 = (var24 + var24);
var26 = 0;
var27 = 0;
var28 = 0;
var29 = 0;
var31 = 0;
var33 = 0;
var34 = 0;
var35 = 0;
var36 = 0;
do {
var26 = (var26 + *(int *)(((long)arg0 + var31 * 8)));
var27 = (var27 + *(int *)(((long)arg0 + var31 * 8 + 0x8)));
var28 = (var28 + *(int *)(((long)arg0 + var31 * 8 + 0x10)));
var29 = (var29 + *(int *)(((long)arg0 + var31 * 8 + 0x18)));
ret = ((unsigned long)((unsigned int)(var27)) | (unsigned long)((unsigned int)(var26)));
var33 = (var33 + *(int *)(((long)arg0 + var31 * 8 + 0x20)));
var34 = (var34 + *(int *)(((long)arg0 + var31 * 8 + 0x28)));
var35 = (var35 + *(int *)(((long)arg0 + var31 * 8 + 0x30)));
var36 = (var36 + *(int *)(((long)arg0 + var31 * 8 + 0x38)));
var31 = (var31 + 8);
} while ((var24 != var31));
var7 = (unsigned long)((unsigned int)((((var36 + var29) + (var34 + var27)) + ((var35 + var28) + (var33 + var26)))));
L_16e0: ;
total = (var7 + *(int *)(((long)arg0 + var8 * 4)));
var83 = (unsigned long)((unsigned int)(total));
index = (var8 + 2);
var7 = (unsigned long)((unsigned int)(total));
var8 = (unsigned long)((unsigned int)(index));
if (((unsigned long)(index) < (unsigned long)(var1))) {
goto L_16e0;
}
return var83;
L_16ee: ;
var15 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var9)) & -4)));
var87 = *(int *)(((long)arg0));
var88 = *(int *)(((long)arg0 + 0x4));
var89 = *(int *)(((long)arg0 + 0x8));
var90 = *(int *)(((long)arg0 + 0xc));
if ((var15 != 4)) {
var87 = (var87 + *(int *)(((long)arg0 + 0x10)));
var88 = (var88 + *(int *)(((long)arg0 + 0x14)));
var89 = (var89 + *(int *)(((long)arg0 + 0x18)));
var90 = (var90 + *(int *)(((long)arg0 + 0x1c)));
if (((unsigned long)((unsigned int)(var15)) != 8)) {
var87 = (var87 + *(int *)(((long)arg0 + 0x20)));
var88 = (var88 + *(int *)(((long)arg0 + 0x24)));
var89 = (var89 + *(int *)(((long)arg0 + 0x28)));
var90 = (var90 + *(int *)(((long)arg0 + 0x2c)));
if (((unsigned long)((unsigned int)(var15)) != 12)) {
var87 = (var87 + *(int *)(((long)arg0 + 0x30)));
var88 = (var88 + *(int *)(((long)arg0 + 0x34)));
var89 = (var89 + *(int *)(((long)arg0 + 0x38)));
var90 = (var90 + *(int *)(((long)arg0 + 0x3c)));
}
}
}
var14 = (unsigned long)((unsigned int)(((var90 + var88) + (var89 + var87))));
ret = var14;
if ((var15 == var9)) {
return ret;
}
L_1740: ;
var122 = (var14 + *(int *)(((long)arg0 + var15 * 4)));
var124 = (var15 + 1);
var14 = (unsigned long)((unsigned int)(var122));
var15 = var124;
ret = (unsigned long)((unsigned int)(var122));
if ((var9 != var124)) {
goto L_1740;
}
return ret;
} cpp_template_predicate pass 78 lines
// glaurung: cpp_template_predicate @ 0x1550
int32_t cpp_template_predicate(const int32_t * arg0, int32_t arg1, int32_t arg2) {
int hits;
int index;
long ret;
long t10;
int var10;
int var11;
int var12;
int var13;
long var2;
int var22;
int var23;
int var24;
int var25;
long var5;
long var69;
ret = 0xffffffff;
if ((arg0 == 0)) {
return ret;
}
ret = 0xffffffff;
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var2 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)(4) <= (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
var5 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var2)) & -4)));
var10 = arg2;
var11 = arg2;
var12 = arg2;
var13 = arg2;
var22 = ((unsigned int)((-(arg2 < *(int *)(((long)arg0))))) >> 31);
var23 = ((unsigned int)((-(arg2 < *(int *)(((long)arg0 + 0x4))))) >> 31);
var24 = ((unsigned int)((-(arg2 < *(int *)(((long)arg0 + 0x8))))) >> 31);
var25 = ((unsigned int)((-(arg2 < *(int *)(((long)arg0 + 0xc))))) >> 31);
if ((var5 != 4)) {
var22 = (var22 - (-(var10 < *(int *)(((long)arg0 + 0x10)))));
var23 = (var23 - (-(var11 < *(int *)(((long)arg0 + 0x14)))));
var24 = (var24 - (-(var12 < *(int *)(((long)arg0 + 0x18)))));
var25 = (var25 - (-(var13 < *(int *)(((long)arg0 + 0x1c)))));
if (((unsigned long)((unsigned int)(var5)) != 8)) {
var22 = (var22 - (-(var10 < *(int *)(((long)arg0 + 0x20)))));
var23 = (var23 - (-(var11 < *(int *)(((long)arg0 + 0x24)))));
var24 = (var24 - (-(var12 < *(int *)(((long)arg0 + 0x28)))));
var25 = (var25 - (-(var13 < *(int *)(((long)arg0 + 0x2c)))));
if (((unsigned long)((unsigned int)(var5)) != 12)) {
var22 = (var22 - (-(var10 < *(int *)(((long)arg0 + 0x30)))));
var23 = (var23 - (-(var11 < *(int *)(((long)arg0 + 0x34)))));
var24 = (var24 - (-(var12 < *(int *)(((long)arg0 + 0x38)))));
var25 = (var25 - (-(var13 < *(int *)(((long)arg0 + 0x3c)))));
}
}
}
var69 = (unsigned long)((unsigned int)(((var25 + var23) + (var24 + var22))));
ret = var69;
if ((var5 == var2)) {
return ret;
}
L_15f0: ;
do {
t10 = *(int *)(((long)arg0 + var5 * 4));
hits = (var69 + ((((unsigned int)(t10) == (unsigned int)(arg2)) | ((long)((int)(t10)) < (long)(arg2))) == 0));
index = (var5 + 1);
var69 = (unsigned long)((unsigned int)(hits));
var5 = (unsigned long)((unsigned int)(index));
ret = (unsigned long)((unsigned int)(hits));
} while ((var2 != index));
} else {
var69 = 0;
var5 = 0;
goto L_15f0;
}
return ret;
} cpp_template_uint8 fail 159 lines
// glaurung: cpp_template_uint8 @ 0x1350
__attribute__((no_stack_protector)) int32_t cpp_template_uint8(const int32_t * arg0, int32_t arg1) {
int index;
unsigned char total;
unsigned char local_14[20];
unsigned char local_18[4];
long ret;
long var0;
long var107;
long var3;
long var46;
long var50;
long var52;
long var53;
long var56;
int var58;
long var71;
long var72;
long var75;
long var78;
long var81;
long var89;
long var92;
long var95;
long var97;
var0 = 0xffffffff;
ret = 0xffffffff;
if ((arg0 == 0)) {
return ret;
}
ret = 0xffffffff;
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
goto L_1433;
}
var0 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)((unsigned long)((unsigned int)(arg1))) < (unsigned long)(4))) {
var3 = 0;
goto L_1410;
}
var3 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) & -4)));
/* asm: packuswb */
/* asm: packuswb */
*(int *)(&local_18[0]) = (*(int *)(((long)arg0)) & 255);
if ((var3 != 4)) {
/* asm: packuswb */
/* asm: packuswb */
*(int *)(&local_14[0]) = (*(int *)(((long)arg0 + 0x10)) & 255);
if (((unsigned long)((unsigned int)(var3)) != 8)) {
/* asm: packuswb */
/* asm: packuswb */
*(int *)((&local_14[0] + 4)) = (*(int *)(((long)arg0 + 0x20)) & 255);
if (((unsigned long)((unsigned int)(var3)) != 12)) {
/* asm: packuswb */
/* asm: packuswb */
*(int *)((&local_14[0] + 8)) = (*(int *)(((long)arg0 + 0x30)) & 255);
}
}
}
if ((var3 == var0)) {
goto L_1421;
}
L_1410: ;
*(signed char *)((&local_18[0] + var3)) = *(char *)(((long)arg0 + var3 * 4));
index = (var3 + 1);
var3 = (unsigned long)((unsigned int)(index));
if ((var0 != index)) {
goto L_1410;
}
L_1421: ;
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
goto L_1433;
}
if (((unsigned long)(8) <= (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
goto L_1436;
}
var46 = 0;
total = 0;
goto L_1530;
L_1433: ;
return 0;
L_1436: ;
if (((unsigned long)(16) <= (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
goto L_147d;
}
var50 = 0;
var52 = 0;
L_143f: ;
var53 = var52;
var56 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) & -8)));
var58 = (unsigned int)((unsigned char)((var50 & 255)));
do {
/* asm: paddb */
var53 = (var53 + 8);
} while ((var56 != var53));
/* asm: psadbw */
var71 = (unsigned long)((unsigned int)(var58));
var46 = var56;
total = (unsigned long)((unsigned int)(var58));
if ((var56 != var0)) {
goto L_1530;
}
var72 = var71;
return (unsigned int)((unsigned char)((var71 & 255)));
L_147d: ;
var52 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) & -16)));
var75 = (var52 - 16);
var78 = (((unsigned long)(var75) >> 4) + 1);
var81 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var78)) & 7)));
if (((unsigned long)(112) <= (unsigned long)(var75))) {
var89 = (var78 & -8);
var92 = 0;
do {
/* asm: paddb */
/* asm: paddb */
/* asm: paddb */
/* asm: paddb */
/* asm: paddb */
/* asm: paddb */
/* asm: paddb */
/* asm: paddb */
var92 = (var92 + 128);
var89 = (var89 - 8);
var78 = var89;
} while ((var89 != 0));
}
if ((var81 != 0)) {
var95 = (var81 << 4);
var97 = 0;
do {
/* asm: paddb */
var97 = (var97 + 16);
} while ((var95 != var97));
}
/* asm: paddb */
ret = 0;
/* asm: psadbw */
var50 = 0;
var72 = 0;
if ((var52 == var0)) {
return (unsigned int)((unsigned char)((var72 & 255)));
}
var46 = var52;
total = 0;
if (((unsigned long)((unsigned char)((var0 & 8))) != 0)) {
goto L_143f;
}
L_1530: ;
total = (((total & 255) + *(char *)((&local_18[0] + var46))) & 255);
var107 = (var46 + 1);
var46 = var107;
var72 = (unsigned long)(total);
if ((var0 != var107)) {
goto L_1530;
}
return (unsigned int)((unsigned char)((var72 & 255)));
} gcc -O2
3/5cpp_template_int16 fail 44 lines
// glaurung: cpp_template_int16 @ 0x1160
int32_t cpp_template_int16(const int32_t * arg0, int32_t arg1) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int index;
short total;
long local_10;
unsigned char local_38[32];
long ret;
long var12;
long var7;
long var8;
long zf_9;
local_10 = (long)(0x28);
index = 0;
if ((arg0 == 0)) {
L_11dc: ;
ret = 0xffffffff;
} else {
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
goto L_11dc;
} else {
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
ret = 0;
} else {
var7 = (unsigned long)((unsigned int)((arg1 - 1)));
var8 = (long)(&local_38[0]);
do {
*(short *)((var8 + index * 2)) = *(int *)(((long)arg0 + index * 4));
zf_9 = (var7 == index);
index = (index + 1);
} while ((zf_9 == 0));
var12 = (long)(((&local_38[0] + (var7 * 2)) + 2));
do {
var8 = (var8 + 2);
} while ((var12 != var8));
ret = (int)((short)(ret));
}
}
}
if ((local_10 != 0x28)) {
__stack_chk_fail();
}
return ret;
} cpp_template_int32 pass 25 lines
// glaurung: cpp_template_int32 @ 0x1120
int32_t cpp_template_int32(const int32_t * arg0, int32_t arg1) {
int index;
int total;
long ret;
long var2;
long var5;
if ((arg0 == 0)) {
return 0xffffffff;
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return 0xffffffff;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var2 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 1))) * 4)) + 4));
ret = 0;
var5 = (long)arg0;
do {
ret = (unsigned long)((unsigned int)((ret + *(int *)((var5)))));
var5 = (var5 + 4);
} while ((var5 != var2));
return ret;
} cpp_template_nontype pass 41 lines
// glaurung: cpp_template_nontype @ 0x12d0
int32_t cpp_template_nontype(const int32_t * arg0, int32_t arg1, int32_t arg2) {
int index;
int total;
long ret;
int var1;
long var13;
long var14;
long var3;
long var6;
if ((arg0 == 0)) {
return 0xffffffff;
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return 0xffffffff;
}
var1 = ((unsigned long)((unsigned int)(arg2)) & 1);
ret = (unsigned long)((unsigned int)(var1));
if (((unsigned long)((unsigned int)(var1)) != 0)) {
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var3 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 1))) * 4)) + 4));
ret = 0;
var6 = (long)arg0;
do {
ret = (unsigned long)((unsigned int)((ret + *(int *)((var6)))));
var6 = (var6 + 4);
} while ((var6 != var3));
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) != 0)) {
var13 = (long)((((long)arg0 + ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg1 - 1))) >> 1))) * 8)) + 8));
var14 = (long)arg0;
do {
ret = (unsigned long)((unsigned int)((ret + *(int *)((var14)))));
var14 = (var14 + 8);
} while ((var14 != var13));
}
return ret;
} cpp_template_predicate pass 27 lines
// glaurung: cpp_template_predicate @ 0x1280
int32_t cpp_template_predicate(const int32_t * arg0, int32_t arg1, int32_t arg2) {
int hits;
int index;
long ret;
long t11;
long var2;
long var7;
if ((arg0 == 0)) {
return 0xffffffff;
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return 0xffffffff;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var2 = (long)((((long)arg0 + ((unsigned long)((unsigned int)((arg1 - 1))) * 4)) + 4));
ret = 0;
var7 = (long)arg0;
do {
t11 = *(int *)((var7));
var7 = (var7 + 4);
ret = (unsigned long)((unsigned int)((ret + ((long)(arg2) < (long)((int)(t11))))));
} while ((var7 != var2));
return ret;
} cpp_template_uint8 fail 51 lines
// glaurung: cpp_template_uint8 @ 0x11f0
int32_t cpp_template_uint8(const int32_t * arg0, int32_t arg1) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int index;
unsigned char total;
long local_10;
unsigned char local_28[16];
long ret;
long rsp;
long var12;
long var15;
long var7;
long var8;
long zf_9;
rsp = (rsp - 40);
local_10 = (long)(0x28);
index = 0;
if ((arg0 == 0)) {
L_126c: ;
ret = 0xffffffff;
} else {
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
goto L_126c;
} else {
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
ret = 0;
} else {
var7 = (unsigned long)((unsigned int)((arg1 - 1)));
var8 = (long)(&local_28[0]);
do {
*(signed char *)((var8 + index)) = *(int *)(((long)arg0 + index * 4));
zf_9 = (index == var7);
index = (index + 1);
} while ((zf_9 == 0));
var12 = ((rsp + var7) + 1);
var15 = 0;
do {
total = (((var15 & 255) + *(char *)((var8))) & 255);
var8 = (var8 + 1);
var15 = (unsigned long)(total);
} while ((var12 != var8));
ret = (unsigned int)((unsigned char)((total & 255)));
}
}
}
if ((local_10 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: tear down frame
return ret;
} clang -O0
5/5cpp_template_int16 pass 30 lines
// glaurung: cpp_template_int16 @ 0x11b0
__attribute__((no_stack_protector)) int32_t cpp_template_int16(const int32_t * arg0, int32_t arg1) {
extern short _ZN12_GLOBAL__N_116accumulate_rangeIsEET_PKS1_iS1_(short *, int, short);
int index;
int local_4;
unsigned char local_40[32];
short var13;
// x86-64 prologue: save rbp, frame 80 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);
}
for (index = 0; (index < arg1); index++) {
*(short *)((&local_40[0] + ((long)(index) * 2))) = arg0[(long)(index)];
}
var13 = _ZN12_GLOBAL__N_116accumulate_rangeIsEET_PKS1_iS1_((short *)(&local_40[0]), (unsigned long)((unsigned int)(arg1)), 0);
// x86-64 epilogue: restore rbp
return (unsigned int)((short)(var13));
} cpp_template_int32 pass 26 lines
// glaurung: cpp_template_int32 @ 0x1100
int32_t cpp_template_int32(const int32_t * arg0, int32_t arg1) {
extern int _ZN12_GLOBAL__N_116accumulate_rangeIiEET_PKS1_iS1_(int *, int, int);
int local_4;
int var1;
// x86-64 prologue: save rbp, frame 32 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);
}
var1 = _ZN12_GLOBAL__N_116accumulate_rangeIiEET_PKS1_iS1_((int *)(arg0), (unsigned long)((unsigned int)(arg1)), 0);
local_4 = var1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} cpp_template_nontype pass 35 lines
// glaurung: cpp_template_nontype @ 0x1450
int32_t cpp_template_nontype(const int32_t * arg0, int32_t arg1, int32_t arg2) {
extern int _ZN12_GLOBAL__N_111strided_sumILi1EEEiPKii(int *, int);
extern int _ZN12_GLOBAL__N_111strided_sumILi2EEEiPKii(int *, int);
int local_1c;
int local_4;
int var3;
int var5;
// x86-64 prologue: save rbp, frame 32 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);
}
if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) & 1))) == 0)) {
var3 = _ZN12_GLOBAL__N_111strided_sumILi2EEEiPKii((int *)(arg0), (unsigned long)((unsigned int)(arg1)));
local_1c = var3;
} else {
var5 = _ZN12_GLOBAL__N_111strided_sumILi1EEEiPKii((int *)(arg0), (unsigned long)((unsigned int)(arg1)));
local_1c = var5;
}
local_4 = local_1c;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} cpp_template_predicate pass 26 lines
// glaurung: cpp_template_predicate @ 0x1390
int32_t cpp_template_predicate(const int32_t * arg0, int32_t arg1, int32_t arg2) {
extern int _ZN12_GLOBAL__N_111count_aboveIiEEiPKT_iS1_(int *, int, int);
int local_4;
int var0;
// x86-64 prologue: save rbp, frame 32 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);
}
var0 = _ZN12_GLOBAL__N_111count_aboveIiEEiPKT_iS1_((int *)(arg0), (unsigned long)((unsigned int)(arg1)), (unsigned long)((unsigned int)(arg2)));
local_4 = var0;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} cpp_template_uint8 pass 30 lines
// glaurung: cpp_template_uint8 @ 0x12a0
__attribute__((no_stack_protector)) int32_t cpp_template_uint8(const int32_t * arg0, int32_t arg1) {
extern unsigned char _ZN12_GLOBAL__N_116accumulate_rangeIhEET_PKS1_iS1_(char *, int, unsigned char);
int index;
unsigned char local_30[16];
int local_4;
unsigned char var13;
// 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);
}
for (index = 0; (index < arg1); index++) {
*(signed char *)((&local_30[0] + (long)(index))) = arg0[(long)(index)];
}
var13 = _ZN12_GLOBAL__N_116accumulate_rangeIhEET_PKS1_iS1_((char *)(&local_30[0]), (unsigned long)((unsigned int)(arg1)), 0);
// x86-64 epilogue: restore rbp
return (unsigned int)((unsigned char)((var13 & 255)));
} gcc -O0
5/5cpp_template_int16 pass 26 lines
// glaurung: cpp_template_int16 @ 0x115f
int32_t cpp_template_int16(const int32_t * arg0, int32_t arg1) {
extern short _ZN12_GLOBAL__N_116accumulate_rangeIsEET_PKS1_iS1_(short *, int, short);
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int index;
unsigned char local_30[32];
long local_8;
long ret;
short var15;
// x86-64 prologue: save rbp, frame 80 bytes
local_8 = (long)(0x28);
if ((((arg0 == 0) || ((long)(arg1) < 0)) || (((unsigned long)((unsigned int)(arg1)) != 16) && (16 <= (long)(arg1))))) {
ret = 0xffffffff;
} else {
for (index = 0; (index < arg1); index++) {
*(short *)((&local_30[0] + ((long)(index) * 2))) = arg0[(long)(index)];
}
var15 = _ZN12_GLOBAL__N_116accumulate_rangeIsEET_PKS1_iS1_((short *)(&local_30[0]), (unsigned long)((unsigned int)(arg1)), 0);
ret = (int)((short)(var15));
}
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} cpp_template_int32 pass 21 lines
// glaurung: cpp_template_int32 @ 0x1119
int32_t cpp_template_int32(const int32_t * arg0, int32_t arg1) {
extern int _ZN12_GLOBAL__N_116accumulate_rangeIiEET_PKS1_iS1_(int *, int, int);
int ret;
// x86-64 prologue: save rbp, frame 16 bytes
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((long)(arg1) < 0)) {
// 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;
}
ret = _ZN12_GLOBAL__N_116accumulate_rangeIiEET_PKS1_iS1_((int *)(arg0), (unsigned long)((unsigned int)(arg1)), 0);
// x86-64 epilogue: restore rbp
return ret;
} cpp_template_nontype pass 27 lines
// glaurung: cpp_template_nontype @ 0x12e7
int32_t cpp_template_nontype(const int32_t * arg0, int32_t arg1, int32_t arg2) {
extern int _ZN12_GLOBAL__N_111strided_sumILi1EEEiPKii(int *, int);
extern int _ZN12_GLOBAL__N_111strided_sumILi2EEEiPKii(int *, int);
int var5;
int var8;
// x86-64 prologue: save rbp, frame 16 bytes
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((long)(arg1) < 0)) {
// 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;
}
if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) & 1))) == 0)) {
var5 = _ZN12_GLOBAL__N_111strided_sumILi2EEEiPKii((int *)(arg0), (unsigned long)((unsigned int)(arg1)));
return var5;
} else {
var8 = _ZN12_GLOBAL__N_111strided_sumILi1EEEiPKii((int *)(arg0), (unsigned long)((unsigned int)(arg1)));
return var8;
}
} cpp_template_predicate pass 21 lines
// glaurung: cpp_template_predicate @ 0x12a0
int32_t cpp_template_predicate(const int32_t * arg0, int32_t arg1, int32_t arg2) {
extern int _ZN12_GLOBAL__N_111count_aboveIiEEiPKT_iS1_(int *, int, int);
int ret;
// x86-64 prologue: save rbp, frame 16 bytes
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((long)(arg1) < 0)) {
// 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;
}
ret = _ZN12_GLOBAL__N_111count_aboveIiEEiPKT_iS1_((int *)(arg0), (unsigned long)((unsigned int)(arg1)), (unsigned long)((unsigned int)(arg2)));
// x86-64 epilogue: restore rbp
return ret;
} cpp_template_uint8 pass 26 lines
// glaurung: cpp_template_uint8 @ 0x11ff
int32_t cpp_template_uint8(const int32_t * arg0, int32_t arg1) {
extern unsigned char _ZN12_GLOBAL__N_116accumulate_rangeIhEET_PKS1_iS1_(char *, int, unsigned char);
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int index;
unsigned char local_20[16];
long local_8;
long ret;
unsigned char var15;
// x86-64 prologue: save rbp, frame 64 bytes
local_8 = (long)(0x28);
if ((((arg0 == 0) || ((long)(arg1) < 0)) || (((unsigned long)((unsigned int)(arg1)) != 16) && (16 <= (long)(arg1))))) {
ret = 0xffffffff;
} else {
for (index = 0; (index < arg1); index++) {
*(signed char *)((&local_20[0] + (long)(index))) = arg0[(long)(index)];
}
var15 = _ZN12_GLOBAL__N_116accumulate_rangeIhEET_PKS1_iS1_((char *)(&local_20[0]), (unsigned long)((unsigned int)(arg1)), 0);
ret = (unsigned int)((unsigned char)((var15 & 255)));
}
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
}