Fixture 69
molar mass
C · 1 functions · 4 lanes · 4 of 4 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
A chemical-formula parser: element symbols with optional multi-digit counts, looked up in a small table, accumulated as centi-atomic-mass units. Parsing plus table lookup plus accumulation in one pass.
#include <stdint.h>
/* A chemical-formula parser: element symbols with optional multi-digit counts,
* looked up in a small table, accumulated as centi-atomic-mass units. Parsing
* plus table lookup plus accumulation in one pass. */
#define FORMULA_MAX 16
static int32_t element_mass_centi(uint8_t first, uint8_t second) {
if (first == (uint8_t)'H' && second == 0) {
return 101;
}
if (first == (uint8_t)'C' && second == 0) {
return 1201;
}
if (first == (uint8_t)'N' && second == 0) {
return 1401;
}
if (first == (uint8_t)'O' && second == 0) {
return 1600;
}
if (first == (uint8_t)'S' && second == 0) {
return 3207;
}
if (first == (uint8_t)'N' && second == (uint8_t)'a') {
return 2299;
}
if (first == (uint8_t)'C' && second == (uint8_t)'l') {
return 3545;
}
if (first == (uint8_t)'F' && second == (uint8_t)'e') {
return 5585;
}
return -1;
}
__attribute__((noinline)) int32_t
molar_mass_centi(const uint8_t *formula, int32_t length) {
int32_t total = 0;
int32_t index = 0;
if (formula == 0 || length < 0 || length > FORMULA_MAX) {
return -1;
}
while (index < length) {
uint8_t first = formula[index];
uint8_t second = 0;
int32_t count = 0;
int32_t mass;
if (first < (uint8_t)'A' || first > (uint8_t)'Z') {
return -2;
}
index += 1;
if (index < length && formula[index] >= (uint8_t)'a' &&
formula[index] <= (uint8_t)'z') {
second = formula[index];
index += 1;
}
mass = element_mass_centi(first, second);
if (mass < 0) {
return -3;
}
while (index < length && formula[index] >= (uint8_t)'0' &&
formula[index] <= (uint8_t)'9') {
count = count * 10 + (int32_t)(formula[index] - (uint8_t)'0');
if (count > 99) {
return -4;
}
index += 1;
}
if (count == 0) {
count = 1;
}
total += mass * count;
}
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
1/1molar_mass_centi pass 93 lines
// glaurung: molar_mass_centi @ 0x1100
int32_t molar_mass_centi(const uint8_t * arg0, int32_t arg1) {
extern int element_mass_centi(unsigned char, unsigned char);
int total;
int index;
unsigned char first;
unsigned char second;
int count;
int mass;
signed char local_29;
int local_4;
int var16;
int var25;
int var33;
int var38;
total = 0;
index = 0;
if ((arg0 != 0)) {
if ((0 <= (long)(arg1))) {
if ((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16))) {
goto L_1148;
}
}
}
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_1148: ;
goto L_114d;
L_114d: ;
if ((arg1 <= index)) {
goto L_12ca;
}
first = arg0[index];
second = 0;
count = 0;
if ((65 <= (long)(first))) {
if ((((unsigned long)((unsigned long)(first)) == 90) | ((long)(first) < 90))) {
goto L_1198;
}
}
local_4 = -2;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_1198: ;
index = ((unsigned int)(index) + 1);
if ((index < arg1)) {
if ((97 <= (long)((int)((unsigned char)(arg0[index]))))) {
var16 = (unsigned int)((unsigned char)(arg0[index]));
if (((((unsigned long)((unsigned int)(var16)) == 122) | ((long)((int)(var16)) < 122)) != 0)) {
second = arg0[index];
index = ((unsigned int)(index) + 1);
}
}
}
var25 = element_mass_centi((unsigned int)((unsigned char)((first & 255))), second);
mass = var25;
if (((long)(mass) < 0)) {
local_4 = -3;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
goto L_121b;
L_121b: ;
local_29 = 0;
if ((index < arg1)) {
var33 = (unsigned int)((unsigned char)(arg0[index]));
local_29 = 0;
if ((48 <= (long)((int)(var33)))) {
var38 = (unsigned int)((unsigned char)(arg0[index]));
local_29 = (((unsigned long)((unsigned int)(var38)) == 57) | ((long)((int)(var38)) < 57));
}
}
if (((unsigned long)((unsigned char)((local_29 & 1))) != 0)) {
count = ((count * 10) + (unsigned int)(((unsigned int)((unsigned char)(arg0[index])) - 48)));
if (((((unsigned long)((unsigned int)(count)) == 99) | ((long)(count) < 99)) == 0)) {
local_4 = -4;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
index = ((unsigned int)(index) + 1);
goto L_121b;
}
if (((unsigned long)((unsigned int)(count)) == 0)) {
count = 1;
}
total = ((unsigned int)(((unsigned long)((unsigned int)(mass)) * count)) + total);
goto L_114d;
L_12ca: ;
local_4 = total;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
1/1molar_mass_centi pass 201 lines
// glaurung: molar_mass_centi @ 0x1100
int32_t molar_mass_centi(const uint8_t * arg0, int32_t arg1) {
unsigned char first;
int mass;
int index;
int count;
int total;
unsigned char second;
long ret;
long t167;
long var0;
long var10;
long var11;
long var12;
long var13;
long var16;
int var17;
long var2;
long var21;
long var22;
long var23;
long var24;
long var25;
long var37;
long var38;
long var42;
int var44;
long var46;
int var49;
long var52;
long var53;
long var7;
ret = 0xffffffff;
if ((arg0 == 0)) {
goto L_1264;
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
goto L_1264;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
goto L_1262;
}
var0 = (unsigned long)((unsigned int)(arg1));
var2 = 0;
var7 = 0;
var10 = 0;
var11 = var12;
L_112d: ;
var13 = (long)((int)(var10));
first = ((var11 & -256) | (arg0[(long)((int)(var10))] & 255));
ret = (unsigned long)((unsigned int)(((unsigned int)(first) - 91)));
if (((unsigned long)((unsigned long)((unsigned char)((ret & 255)))) < (unsigned long)(230))) {
goto L_1268;
}
var16 = (var13 + 1);
if (((long)((int)(var16)) < (long)(arg1))) {
var17 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + var16))));
ret = (unsigned long)((unsigned int)((var17 - 97)));
t167 = (ret & 255);
var21 = (((unsigned long)(26) <= (unsigned long)((unsigned long)((unsigned char)(t167)))) ? var2 : var17);
var16 = (unsigned long)((unsigned int)((((unsigned long)(26) <= (unsigned long)((unsigned long)((unsigned char)(t167)))) ? var16 : (unsigned long)((unsigned int)((var10 + 2))))));
var22 = var21;
if (((unsigned long)((unsigned char)((first & 255))) == 72)) {
goto L_1178;
}
var23 = var21;
var24 = ret;
var25 = var16;
goto L_1183;
}
var22 = 0;
var23 = 0;
var24 = ret;
var25 = var16;
if (((unsigned long)((unsigned char)((first & 255))) != 72)) {
goto L_1183;
}
L_1178: ;
var23 = var22;
var24 = ret;
var25 = var16;
mass = 101;
if (((unsigned long)((unsigned char)((var22 & 255))) == 0)) {
goto L_1200;
}
L_1183: ;
if (((unsigned long)((unsigned char)((first & 255))) == 67)) {
mass = 1201;
ret = var24;
var16 = var25;
if (((unsigned long)((unsigned char)((var23 & 255))) == 0)) {
goto L_1200;
}
}
if (((unsigned long)((unsigned char)((first & 255))) == 78)) {
mass = 1401;
ret = var24;
var16 = var25;
if (((unsigned long)((unsigned char)((var23 & 255))) == 0)) {
goto L_1200;
}
}
if (((unsigned long)((unsigned char)((first & 255))) == 79)) {
mass = 1600;
ret = var24;
var16 = var25;
if (((unsigned long)((unsigned char)((var23 & 255))) == 0)) {
goto L_1200;
}
}
if (((unsigned long)((unsigned char)((first & 255))) == 83)) {
mass = 3207;
ret = var24;
var16 = var25;
if (((unsigned long)((unsigned char)((var23 & 255))) == 0)) {
goto L_1200;
}
}
if (((unsigned long)((unsigned char)((first & 255))) == 78)) {
mass = 2299;
ret = var24;
var16 = var25;
if (((unsigned long)((unsigned char)((var23 & 255))) == 97)) {
goto L_1200;
}
}
if (((unsigned long)((unsigned char)((first & 255))) == 67)) {
mass = 3545;
ret = var24;
var16 = var25;
if (((unsigned long)((unsigned char)((var23 & 255))) == 108)) {
goto L_1200;
}
}
ret = 0xfffffffd;
if (((unsigned long)((unsigned char)((first & 255))) != 70)) {
goto L_1264;
}
mass = 0x15d1;
if (((unsigned long)((unsigned char)((var23 & 255))) != 101)) {
goto L_1264;
}
var16 = var25;
L_1200: ;
var37 = var16;
var38 = (unsigned long)(first);
if (((long)(arg1) <= (long)((int)(var16)))) {
goto L_1240;
}
var42 = 0;
index = (long)((int)(var16));
L_1210: ;
var44 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + index))));
var46 = (unsigned long)((unsigned int)(index));
if (((unsigned long)((unsigned long)((unsigned char)(((unsigned long)((unsigned int)((var44 - 48))) & 255)))) <= (unsigned long)(9))) {
var49 = ((unsigned int)((var44 + ((unsigned long)((unsigned int)((var42 + (var42 * 4)))) * 2))) - 48);
count = (unsigned long)((unsigned int)(var49));
if (((((unsigned long)((unsigned int)(var49)) == 99) | ((long)((int)(var49)) < 99)) == 0)) {
goto L_125b;
}
index = (index + 1);
var42 = (unsigned long)((unsigned int)(count));
if ((var0 != index)) {
goto L_1210;
}
var42 = (unsigned long)((unsigned int)(count));
var46 = (unsigned long)((unsigned int)(var0));
}
var52 = var42;
var53 = (unsigned long)((unsigned int)(var44));
if (((unsigned long)((unsigned int)(var42)) != 0)) {
goto L_1245;
}
var37 = var46;
var38 = (unsigned long)((unsigned int)(var44));
L_1240: ;
var52 = 1;
var46 = var37;
var53 = var38;
L_1245: ;
total = (var7 + (unsigned int)((var52 * mass)));
ret = (unsigned long)((unsigned int)(total));
var7 = (unsigned long)((unsigned int)(total));
var10 = (unsigned long)((unsigned int)(var46));
var11 = var53;
if (((long)((int)(var46)) < (long)(arg1))) {
goto L_112d;
}
goto L_1264;
L_125b: ;
ret = 0xfffffffc;
goto L_1264;
L_1262: ;
ret = 0;
L_1264: ;
// x86-64 epilogue: tear down frame
return ret;
L_1268: ;
ret = 0xfffffffe;
goto L_1264;
} gcc -O0
1/1molar_mass_centi pass 77 lines
// glaurung: molar_mass_centi @ 0x11ad
int32_t molar_mass_centi(const uint8_t * arg0, int32_t arg1) {
extern int element_mass_centi(unsigned char, unsigned char);
int total;
int index;
unsigned char first;
unsigned char second;
int count;
int mass;
int var25;
int var32;
total = 0;
index = 0;
if ((arg0 != 0)) {
if ((0 <= (long)(arg1))) {
if ((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16))) {
goto L_1313;
}
}
}
// x86-64 epilogue: restore rbp
return 0xffffffff;
L_11ef: ;
first = arg0[index];
second = 0;
count = 0;
if (((unsigned long)(64) < (unsigned long)(first))) {
if (((unsigned long)(first) <= (unsigned long)(90))) {
goto L_1223;
}
}
// x86-64 epilogue: restore rbp
return 0xfffffffe;
L_1223: ;
index = (index + 1);
if ((index < arg1)) {
if (((unsigned long)(96) < (unsigned long)((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255)))))) {
if (((unsigned long)((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255)))) <= (unsigned long)(122))) {
second = arg0[index];
index = (index + 1);
}
}
}
var25 = element_mass_centi((unsigned long)((unsigned long)(first)), (unsigned long)((unsigned long)(second)));
mass = var25;
if ((0 <= (long)(mass))) {
goto L_12cc;
}
// x86-64 epilogue: restore rbp
return 0xfffffffd;
L_1292: ;
var32 = ((unsigned int)(((unsigned long)((unsigned int)(count)) << 2)) + (unsigned int)(count));
count = ((unsigned int)(((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255))) - 48)) + (unsigned int)(((unsigned long)((unsigned int)(var32)) + (unsigned long)((unsigned int)(var32)))));
if (((((unsigned long)((unsigned int)(count)) == 99) | ((long)(count) < 99)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xfffffffc;
}
index = (index + 1);
L_12cc: ;
if ((index < arg1)) {
if (((unsigned long)(47) < (unsigned long)((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255)))))) {
if (((unsigned long)((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(arg0[index])) & 255)))) <= (unsigned long)(57))) {
goto L_1292;
}
}
}
if (((unsigned long)((unsigned int)(count)) == 0)) {
count = 1;
}
total = (total + (unsigned int)(((unsigned long)((unsigned int)(mass)) * count)));
L_1313: ;
if ((index < arg1)) {
goto L_11ef;
}
// x86-64 epilogue: restore rbp
return (unsigned int)(total);
} gcc -O2
1/1molar_mass_centi pass 205 lines
// glaurung: molar_mass_centi @ 0x1100
int32_t molar_mass_centi(const uint8_t * arg0, int32_t arg1) {
unsigned char first;
int index;
unsigned char second;
int count;
int total;
long t183;
long t184;
long var0;
long var1;
long var12;
long var13;
long var18;
int var19;
long var21;
long var23;
long var26;
long var28;
long var29;
long var34;
long var37;
int var40;
int var41;
long var43;
long var44;
long var45;
long var46;
int var47;
long var49;
var0 = (long)arg0;
var1 = (unsigned long)((unsigned int)(arg1));
if (((arg0 == 0) || ((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1)))))) {
goto L_12ef;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
goto L_12e7;
}
var12 = 0;
var13 = 0;
L_112b: ;
first = (unsigned int)((unsigned char)(*(char *)((var0 + (long)((int)(var13))))));
if (((unsigned long)(25) < (unsigned long)((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(((unsigned int)(first) - 65))) & 255)))))) {
goto L_12d1;
}
index = (unsigned long)((unsigned int)((var13 + 1)));
if ((((unsigned int)(var1) == (unsigned int)(index)) | ((long)((int)(var1)) < (long)(index)))) {
goto L_1230;
}
var18 = (long)(index);
var19 = (unsigned int)((unsigned char)(*(char *)((var0 + (long)(index)))));
if (((unsigned long)((unsigned long)((unsigned char)(((unsigned long)((unsigned int)((var19 - 97))) & 255)))) <= (unsigned long)(25))) {
goto L_1290;
}
var21 = 101;
var23 = (unsigned long)((unsigned int)(index));
if (((unsigned long)((unsigned char)((first & 255))) == 72)) {
goto L_11df;
}
L_116b: ;
t183 = ((unsigned long)(first) & 255);
var26 = ((unsigned long)((unsigned char)(t183)) == 67);
if (((unsigned long)((unsigned char)(t183)) == 67)) {
goto L_1268;
}
t184 = ((unsigned long)(first) & 255);
var28 = ((unsigned long)((unsigned char)(t184)) == 78);
if (((unsigned long)((unsigned char)(t184)) == 78)) {
goto L_1280;
}
var29 = 1;
var23 = (unsigned long)((unsigned int)(index));
second = 0;
L_118a: ;
if (((unsigned long)((unsigned char)((first & 255))) == 79)) {
if (((unsigned long)((unsigned char)((var29 & 255))) != 0)) {
goto L_12b0;
}
}
if (((unsigned long)((unsigned char)((first & 255))) == 83)) {
if (((unsigned long)((unsigned char)((var29 & 255))) != 0)) {
goto L_1273;
}
}
if (((unsigned long)((unsigned char)((second & 255))) == 97)) {
if (((unsigned long)((unsigned char)((var28 & 255))) != 0)) {
goto L_12bb;
}
}
if (((unsigned long)((unsigned char)((second & 255))) == 108)) {
if (((unsigned long)((unsigned char)((var26 & 255))) != 0)) {
goto L_12c6;
}
}
if (((unsigned long)((unsigned char)((first & 255))) != 70)) {
goto L_12dc;
}
if (((unsigned long)((unsigned char)((second & 255))) != 101)) {
goto L_12dc;
}
var21 = 0x15d1;
L_11d7: ;
if (((long)((int)(var1)) <= (long)((int)(var23)))) {
goto L_123e;
}
var18 = (long)((int)(var23));
L_11df: ;
var34 = (var18 + var0);
var37 = var23;
count = 0;
goto L_1208;
L_11f0: ;
count = (unsigned long)((unsigned int)(((var40 + ((unsigned long)((unsigned int)((count + (count * 4)))) * 2)) - 48)));
if (((((unsigned long)((unsigned int)(count)) == 99) | ((long)(count) < 99)) == 0)) {
goto L_1258;
}
var41 = (var37 + 1);
var37 = (unsigned long)((unsigned int)(var41));
var34 = (var34 + 1);
if (((unsigned int)(var1) == (unsigned int)(var41))) {
goto L_1248;
}
L_1208: ;
var40 = (unsigned int)((unsigned char)(*(char *)((var34))));
if (((unsigned long)((unsigned long)((unsigned char)(((unsigned long)((unsigned int)((var40 - 48))) & 255)))) <= (unsigned long)(9))) {
goto L_11f0;
}
var43 = (unsigned long)((unsigned int)(var37));
var44 = var37;
var45 = var37;
var46 = (unsigned long)((unsigned int)(count));
if (((unsigned long)((unsigned int)(count)) != 0)) {
goto L_124c;
}
L_121a: ;
var47 = (var12 + var21);
var12 = (unsigned long)((unsigned int)(var47));
var13 = var43;
var49 = (unsigned long)((unsigned int)(var47));
if (((long)((int)(var44)) < (long)((int)(var1)))) {
goto L_112b;
}
L_1226: ;
return (unsigned int)(var49);
L_1230: ;
if (((unsigned long)((unsigned char)((first & 255))) != 72)) {
goto L_116b;
}
var21 = 101;
L_123e: ;
var49 = (unsigned long)((unsigned int)((var12 + var21)));
goto L_1226;
L_1248: ;
var45 = var37;
var46 = (unsigned long)((unsigned int)(count));
if (((unsigned long)((unsigned int)(count)) == 0)) {
goto L_123e;
}
L_124c: ;
var21 = (unsigned long)((unsigned int)((var21 * var46)));
var43 = (unsigned long)((unsigned int)(var45));
var44 = var45;
goto L_121a;
L_1258: ;
return 0xfffffffc;
L_1268: ;
var21 = 1201;
var23 = (unsigned long)((unsigned int)(index));
goto L_11d7;
L_1273: ;
var21 = 3207;
goto L_11d7;
L_1280: ;
var21 = 1401;
var23 = (unsigned long)((unsigned int)(index));
goto L_11d7;
L_1290: ;
var26 = ((unsigned long)((unsigned char)((first & 255))) == 67);
var28 = ((unsigned long)((unsigned char)((first & 255))) == 78);
var29 = 0;
var23 = (unsigned long)((unsigned int)((var13 + 2)));
second = var19;
goto L_118a;
L_12b0: ;
var21 = 1600;
goto L_11d7;
L_12bb: ;
var21 = 2299;
goto L_11d7;
L_12c6: ;
var21 = 3545;
goto L_11d7;
L_12d1: ;
var49 = 0xfffffffe;
goto L_1226;
L_12dc: ;
var49 = 0xfffffffd;
goto L_1226;
L_12e7: ;
var49 = 0;
goto L_1226;
L_12ef: ;
var49 = 0xffffffff;
goto L_1226;
}