Fixture 121
dense expression
C · 3 functions · 4 lanes · 12 of 12 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
An IOCCC-flavoured expression: comma operators, nested conditionals, compound assignment, and subscript arithmetic packed into a few statements. It is deliberately dense but fully defined -- every side effect is separated by a sequence point.
#include <stdint.h>
/* An IOCCC-flavoured expression: comma operators, nested conditionals, compound
* assignment, and subscript arithmetic packed into a few statements. It is
* deliberately dense but fully defined -- every side effect is separated by a
* sequence point. */
__attribute__((noinline)) int32_t
dense_fold(int32_t *state, int32_t count, int32_t seed) {
int32_t i = 0;
int32_t a = seed;
int32_t b = 0;
if (state == 0 || count < 0 || count > 16) {
return -1;
}
for (; i < count; a ^= (b = (a << 1) ^ i), state[i] = a, ++i) {
a = (a & 1) ? ((a >> 1) ^ 0x5A5A) : (a >> 1);
}
return (i ? (state[i - 1] ^ b) : a) + (b ? 1 : 0);
}
__attribute__((noinline)) int32_t
chained_assignment(int32_t seed, int32_t *trace) {
int32_t a;
int32_t b;
int32_t c;
if (trace == 0) {
return -1;
}
a = b = c = seed; /* right-associative */
a += b -= c *= 2; /* c doubles, b drops, a rises */
trace[0] = a;
trace[1] = b;
trace[2] = c;
return a + b + c;
}
__attribute__((noinline)) int32_t
conditional_lvalue_select(int32_t which, int32_t *left, int32_t *right) {
if (left == 0 || right == 0) {
return -1;
}
/* The conditional selects a pointer, then the store happens through it. */
*(which ? left : right) += 10;
return *left * 100 + *right;
} 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
3/3chained_assignment pass 25 lines
// glaurung: chained_assignment @ 0x1210
int32_t chained_assignment(int32_t arg0, int32_t * arg1) {
int c;
int b;
int a;
long var3;
long var6;
// x86-64 prologue: save rbp
if ((arg1 != 0)) {
c = arg0;
b = arg0;
a = arg0;
var3 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(c)) << 1)));
c = var3;
var6 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(b)) - var3)));
b = var6;
a = (var6 + a);
*(int *)((long)arg1) = a;
*(int *)(((long)arg1 + 0x4)) = b;
*(int *)(((long)arg1 + 0x8)) = c;
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(a)) + b))) + c));
} else {
return (unsigned int)(-1);
}
} conditional_lvalue_select pass 21 lines
// glaurung: conditional_lvalue_select @ 0x1290
int32_t conditional_lvalue_select(int32_t arg0, int32_t * arg1, int32_t * arg2) {
int * local_20;
int local_4;
// x86-64 prologue: save rbp
if ((arg1 == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if ((arg2 == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
local_20 = (((unsigned long)((unsigned int)(arg0)) == 0) ? (int *)arg2 : (int *)arg1);
*(int *)((local_20)) = ((unsigned long)((unsigned int)(*(int *)(local_20))) + 10);
local_4 = ((*(int *)((long)arg1) * 100) + *(int *)((long)arg2));
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} dense_fold pass 42 lines
// glaurung: dense_fold @ 0x1100
int32_t dense_fold(int32_t * arg0, int32_t arg1, int32_t arg2) {
int i;
int a;
int b;
int local_28;
int local_2c;
int local_4;
long var22;
// x86-64 prologue: save rbp
i = 0;
a = arg2;
b = 0;
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);
}
while ((i < arg1)) {
local_28 = (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(a)) & 1))) == 0) ? ((int)(a) >> 1) : ((unsigned long)((unsigned int)(((int)(a) >> 1))) ^ 0x5a5a));
a = local_28;
var22 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(a)) << 1))) ^ i)));
b = var22;
a = (var22 ^ a);
arg0[(long)(i)] = a;
i = ((unsigned int)(i) + 1);
}
local_2c = (((unsigned long)((unsigned int)(i)) == 0) ? (unsigned long)((unsigned int)(a)) : ((unsigned long)((unsigned int)(arg0[(long)((int)(((unsigned long)((unsigned int)(i)) - 1)))])) ^ (unsigned long)((unsigned int)(b))));
local_4 = ((unsigned int)(local_2c) + (((unsigned long)((unsigned int)(b)) != 0) ? 1 : 0));
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
3/3chained_assignment pass 12 lines
// glaurung: chained_assignment @ 0x11c0
int32_t chained_assignment(int32_t arg0, int32_t * arg1) {
int b;
int c;
if ((arg1 == 0)) {
return 0xffffffff;
}
*(int *)(((long)arg1)) = 0;
*(int *)(((long)arg1 + 0x4)) = (-(unsigned long)((unsigned int)(arg0)));
*(int *)(((long)arg1 + 0x8)) = ((unsigned long)((unsigned int)(arg0)) + (unsigned long)((unsigned int)(arg0)));
return (unsigned int)(arg0);
} conditional_lvalue_select pass 14 lines
// glaurung: conditional_lvalue_select @ 0x11f0
int32_t conditional_lvalue_select(int32_t arg0, int32_t * arg1, int32_t * arg2) {
long ret;
int * var1;
ret = 0xffffffff;
if ((arg1 != 0)) {
if ((arg2 != 0)) {
var1 = (((unsigned long)((unsigned int)(arg0)) == 0) ? (int *)arg2 : (int *)arg1);
*(int *)((var1)) = (*(int *)((var1)) + 10);
ret = (unsigned long)((unsigned int)(((*(int *)(((long)arg1)) * 100) + *(int *)(((long)arg2)))));
}
}
return ret;
} dense_fold pass 66 lines
// glaurung: dense_fold @ 0x1100
int32_t dense_fold(int32_t * arg0, int32_t arg1, int32_t arg2) {
int i;
int a;
int b;
long ret;
long var1;
long var13;
long var17;
long var2;
long var23;
long var26;
long var3;
long var30;
long var36;
long var37;
long var40;
long var44;
long var48;
long var6;
ret = 0xffffffff;
if ((arg0 == 0)) {
return ret;
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
var1 = 0;
var2 = (unsigned long)((unsigned int)(arg2));
} else {
var3 = (unsigned long)((unsigned int)(arg1));
if (((unsigned long)((unsigned int)(arg1)) != 1)) {
var6 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var3)) & -2)));
i = 0;
a = arg2;
do {
var13 = (unsigned long)((unsigned int)(((int)(a) >> 1)));
var17 = (((unsigned long)((unsigned char)((a & 1))) == 0) ? var13 : (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var13)) ^ 0x5a5a))));
var23 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(i)) ^ var17))) ^ (unsigned long)((unsigned int)((var17 + var17))))));
*(int *)(((long)arg0 + i * 4)) = var23;
var26 = (unsigned long)((unsigned int)(((int)(var23) >> 1)));
var30 = (((unsigned long)((unsigned char)((var17 & 1))) == 0) ? var26 : (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var26)) ^ 0x5a5a))));
b = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((i + 1))) ^ (unsigned long)((unsigned int)((var30 + var30))))));
a = (unsigned long)((unsigned int)((var30 ^ b)));
*(int *)(((long)arg0 + i * 4 + 0x4)) = a;
i = (i + 2);
var36 = (unsigned long)((unsigned int)(i));
var37 = (unsigned long)((unsigned int)(a));
} while ((i != var6));
} else {
var36 = 0;
b = var40;
var37 = (unsigned long)((unsigned int)(arg2));
}
if (((unsigned long)((unsigned char)((var3 & 1))) != 0)) {
var44 = (unsigned long)((unsigned int)(((int)(var37) >> 1)));
var48 = (((unsigned long)((unsigned char)((var37 & 1))) == 0) ? var44 : (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var44)) ^ 0x5a5a))));
b = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var36)) ^ (unsigned long)((unsigned int)((var48 + var48))))));
*(int *)(((long)arg0 + var36 * 4)) = (var48 ^ b);
}
var1 = ((unsigned long)((unsigned int)(b)) != 0);
var2 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)((((long)arg0 + ((long)(arg1) * 4)) - 4)))) ^ b)));
}
return (unsigned int)((var1 + var2));
} gcc -O0
3/3chained_assignment pass 21 lines
// glaurung: chained_assignment @ 0x11c2
int32_t chained_assignment(int32_t arg0, int32_t * arg1) {
int c;
int b;
int a;
// x86-64 prologue: save rbp
if ((arg1 != 0)) {
c = arg0;
b = c;
a = b;
c = (c << 1);
b = (b - (unsigned int)(c));
a = (a + (unsigned int)(b));
*(int *)((long)arg1) = a;
*(int *)((arg1 + 1)) = b;
*(int *)((arg1 + 2)) = c;
return (unsigned int)(((unsigned long)((unsigned int)(c)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(a)) + (unsigned long)((unsigned int)(b)))))));
} else {
return 0xffffffff;
}
} conditional_lvalue_select pass 15 lines
// glaurung: conditional_lvalue_select @ 0x1232
int32_t conditional_lvalue_select(int32_t arg0, int32_t * arg1, int32_t * arg2) {
// x86-64 prologue: save rbp
if ((arg1 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if ((arg2 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
*(int *)((((unsigned long)((unsigned int)(arg0)) == 0) ? (long)arg2 : (long)arg1)) = ((unsigned long)((unsigned int)(*(int *)((((unsigned long)((unsigned int)(arg0)) == 0) ? (long)arg2 : (long)arg1)))) + 10);
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)((unsigned int)(*(int *)((long)arg2))) + ((unsigned long)((unsigned int)(*(int *)((long)arg1))) * 100)));
} dense_fold pass 31 lines
// glaurung: dense_fold @ 0x10f9
int32_t dense_fold(int32_t * arg0, int32_t arg1, int32_t arg2) {
int i;
int a;
int b;
// x86-64 prologue: save rbp
i = 0;
a = arg2;
b = 0;
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;
}
while ((i < arg1)) {
a = (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(a)) & 1))) == 0) ? (unsigned long)((unsigned int)(((int)(a) >> 1))) : (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((int)(a) >> 1))) ^ 0x5a5a))));
b = ((unsigned int)(((unsigned long)((unsigned int)(a)) + (unsigned long)((unsigned int)(a)))) ^ i);
a = (a ^ (unsigned int)(b));
arg0[(long)(i)] = a;
i = (i + 1);
}
// x86-64 epilogue: restore rbp
return (unsigned int)(((((unsigned long)((unsigned int)(i)) == 0) ? (unsigned long)((unsigned int)(a)) : (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)(((long)arg0 + (((long)(i) << 2) - 4))))) ^ b)))) + ((unsigned long)((unsigned int)(b)) != 0)));
} gcc -O2
3/3chained_assignment pass 15 lines
// glaurung: chained_assignment @ 0x1180
int32_t chained_assignment(int32_t arg0, int32_t * arg1) {
int c;
long t138;
long var0;
if ((arg1 == 0)) {
return 0xffffffff;
}
var0 = (unsigned long)((unsigned int)((arg0 + arg0)));
t138 = (-(unsigned long)((unsigned int)(arg0)));
*(int *)(((long)arg1)) = 0;
*(int *)(((long)arg1 + 0x8)) = var0;
*(int *)(((long)arg1 + 0x4)) = t138;
return (unsigned int)((var0 + t138));
} conditional_lvalue_select pass 12 lines
// glaurung: conditional_lvalue_select @ 0x11b0
int32_t conditional_lvalue_select(int32_t arg0, int32_t * arg1, int32_t * arg2) {
int * var1;
if ((arg1 != 0)) {
if ((arg2 != 0)) {
var1 = (((unsigned long)((unsigned int)(arg0)) != 0) ? (int *)arg1 : (int *)arg2);
*(int *)((var1)) = (*(int *)((var1)) + 10);
return (unsigned int)(((*(int *)(((long)arg1)) * 100) + *(int *)(((long)arg2))));
}
}
return 0xffffffff;
} dense_fold pass 41 lines
// glaurung: dense_fold @ 0x1100
int32_t dense_fold(int32_t * arg0, int32_t arg1, int32_t arg2) {
int i;
int a;
int b;
long var0;
long var1;
int var15;
long var16;
long var18;
long var21;
long var5;
long var9;
var0 = (long)arg0;
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 (unsigned int)(arg2);
}
var1 = (unsigned long)((unsigned int)((arg1 - 1)));
i = 0;
var5 = (unsigned long)((unsigned int)(arg2));
while (1) {
var9 = (unsigned long)((unsigned int)(((int)(var5) >> 1)));
var15 = (((unsigned long)((unsigned int)((var5 & 1))) != 0) ? (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var9)) ^ 0x5a5a))) : var9);
var16 = (unsigned long)((unsigned int)((var15 + var15)));
var18 = ((unsigned long)((unsigned int)(i)) + 1);
var21 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var16)) ^ i)));
var5 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var15)) ^ var21)));
*(int *)((var0 + i * 4)) = var5;
if ((i == var1)) {
break;
}
i = var18;
}
return (unsigned int)((((unsigned int)(var16) != (unsigned int)(i)) + (unsigned long)((unsigned int)((var21 ^ *(int *)(((var0 + ((long)(arg1) * 4)) - 4)))))));
}