unsigned short clHCA_CheckSum(const void *data, int size, unsigned short sum) {
  const unsigned char *s, *e;
  static const unsigned short v[] = {
      0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011, 0x8033,
      0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022, 0x8063, 0x0066,
      0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072, 0x0050, 0x8055, 0x805F,
      0x005A, 0x804B, 0x004E, 0x0044, 0x8041, 0x80C3, 0x00C6, 0x00CC, 0x80C9,
      0x00D8, 0x80DD, 0x80D7, 0x00D2, 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB,
      0x00EE, 0x00E4, 0x80E1, 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE,
      0x00B4, 0x80B1, 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087,
      0x0082, 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
      0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1, 0x01E0,
      0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1, 0x81D3, 0x01D6,
      0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2, 0x0140, 0x8145, 0x814F,
      0x014A, 0x815B, 0x015E, 0x0154, 0x8151, 0x8173, 0x0176, 0x017C, 0x8179,
      0x0168, 0x816D, 0x8167, 0x0162, 0x8123, 0x0126, 0x012C, 0x8129, 0x0138,
      0x813D, 0x8137, 0x0132, 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E,
      0x0104, 0x8101, 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317,
      0x0312, 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
      0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371, 0x8353,
      0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342, 0x03C0, 0x83C5,
      0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1, 0x83F3, 0x03F6, 0x03FC,
      0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2, 0x83A3, 0x03A6, 0x03AC, 0x83A9,
      0x03B8, 0x83BD, 0x83B7, 0x03B2, 0x0390, 0x8395, 0x839F, 0x039A, 0x838B,
      0x038E, 0x0384, 0x8381, 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E,
      0x0294, 0x8291, 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7,
      0x02A2, 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
      0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1, 0x8243,
      0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252, 0x0270, 0x8275,
      0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261, 0x0220, 0x8225, 0x822F,
      0x022A, 0x823B, 0x023E, 0x0234, 0x8231, 0x8213, 0x0216, 0x021C, 0x8219,
      0x0208, 0x820D, 0x8207, 0x0202,
  };
  for (s = (const unsigned char *)data, e = s + size; s < e; s++)
    sum = (sum << 8) ^ v[(sum >> 8) ^ *s];
  return sum;
}


x86 assembly (clang, -O0):
<clHCA_CheckSum>:
push   %rbp
mov    %rsp,%rbp
mov    %dx,%ax
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %ax,-0xe(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
movslq -0xc(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x18(%rbp),%rax
cmp    -0x20(%rbp),%rax
jae    1173 <clHCA_CheckSum+0x73>
movzwl -0xe(%rbp),%eax
shl    $0x8,%eax
movzwl -0xe(%rbp),%ecx
sar    $0x8,%ecx
mov    -0x18(%rbp),%rdx
movzbl (%rdx),%edx
xor    %edx,%ecx
movslq %ecx,%rdx
lea    0xea8(%rip),%rcx
movzwl (%rcx,%rdx,2),%ecx
xor    %ecx,%eax
mov    %ax,-0xe(%rbp)
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    1129 <clHCA_CheckSum+0x29>
movzwl -0xe(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<clHCA_CheckSum>:
mov    %edx,%eax
test   %esi,%esi
jle    1140 <clHCA_CheckSum+0x40>
movslq %esi,%rcx
add    %rdi,%rcx
lea    0xeed(%rip),%r8
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movzwl %ax,%esi
mov    %esi,%eax
shl    $0x8,%eax
shr    $0x8,%rsi
movzbl (%rdi),%edx
xor    %rsi,%rdx
xor    (%r8,%rdx,2),%ax
add    $0x1,%rdi
cmp    %rcx,%rdi
jb     1120 <clHCA_CheckSum+0x20>
ret

LLVM IR (-O0):
@clHCA_CheckSum.v = internal constant [256 x i16] [i16 0, i16 -32763, i16 -32753, i16 10, i16 -32741, i16 30, i16 20, i16 -32751, i16 -32717, i16 54, i16 60, i16 -32711, i16 40, i16 -32723, i16 -32729, i16 34, i16 -32669, i16 102, i16 108, i16 -32663, i16 120, i16 -32643, i16 -32649, i16 114, i16 80, i16 -32683, i16 -32673, i16 90, i16 -32693, i16 78, i16 68, i16 -32703, i16 -32573, i16 198, i16 204, i16 -32567, i16 216, i16 -32547, i16 -32553, i16 210, i16 240, i16 -32523, i16 -32513, i16 250, i16 -32533, i16 238, i16 228, i16 -32543, i16 160, i16 -32603, i16 -32593, i16 170, i16 -32581, i16 190, i16 180, i16 -32591, i16 -32621, i16 150, i16 156, i16 -32615, i16 136, i16 -32627, i16 -32633, i16 130, i16 -32381, i16 390, i16 396, i16 -32375, i16 408, i16 -32355, i16 -32361, i16 402, i16 432, i16 -32331, i16 -32321, i16 442, i16 -32341, i16 430, i16 420, i16 -32351, i16 480, i16 -32283, i16 -32273, i16 490, i16 -32261, i16 510, i16 500, i16 -32271, i16 -32301, i16 470, i16 476, i16 -32295, i16 456, i16 -32307, i16 -32313, i16 450, i16 320, i16 -32443, i16 -32433, i16 330, i16 -32421, i16 350, i16 340, i16 -32431, i16 -32397, i16 374, i16 380, i16 -32391, i16 360, i16 -32403, i16 -32409, i16 354, i16 -32477, i16 294, i16 300, i16 -32471, i16 312, i16 -32451, i16 -32457, i16 306, i16 272, i16 -32491, i16 -32481, i16 282, i16 -32501, i16 270, i16 260, i16 -32511, i16 -31997, i16 774, i16 780, i16 -31991, i16 792, i16 -31971, i16 -31977, i16 786, i16 816, i16 -31947, i16 -31937, i16 826, i16 -31957, i16 814, i16 804, i16 -31967, i16 864, i16 -31899, i16 -31889, i16 874, i16 -31877, i16 894, i16 884, i16 -31887, i16 -31917, i16 854, i16 860, i16 -31911, i16 840, i16 -31923, i16 -31929, i16 834, i16 960, i16 -31803, i16 -31793, i16 970, i16 -31781, i16 990, i16 980, i16 -31791, i16 -31757, i16 1014, i16 1020, i16 -31751, i16 1000, i16 -31763, i16 -31769, i16 994, i16 -31837, i16 934, i16 940, i16 -31831, i16 952, i16 -31811, i16 -31817, i16 946, i16 912, i16 -31851, i16 -31841, i16 922, i16 -31861, i16 910, i16 900, i16 -31871, i16 640, i16 -32123, i16 -32113, i16 650, i16 -32101, i16 670, i16 660, i16 -32111, i16 -32077, i16 694, i16 700, i16 -32071, i16 680, i16 -32083, i16 -32089, i16 674, i16 -32029, i16 742, i16 748, i16 -32023, i16 760, i16 -32003, i16 -32009, i16 754, i16 720, i16 -32043, i16 -32033, i16 730, i16 -32053, i16 718, i16 708, i16 -32063, i16 -32189, i16 582, i16 588, i16 -32183, i16 600, i16 -32163, i16 -32169, i16 594, i16 624, i16 -32139, i16 -32129, i16 634, i16 -32149, i16 622, i16 612, i16 -32159, i16 544, i16 -32219, i16 -32209, i16 554, i16 -32197, i16 574, i16 564, i16 -32207, i16 -32237, i16 534, i16 540, i16 -32231, i16 520, i16 -32243, i16 -32249, i16 514]
define zeroext i16 @clHCA_CheckSum(i8* %0, i32 %1, i16 zeroext %2) {
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i16
%7 = alloca i8*
%8 = alloca i8*
store i8* %0, i8** %4
store i32 %1, i32* %5
store i16 %2, i16* %6
%9 = load i8*, i8** %4
store i8* %9, i8** %7
%10 = load i8*, i8** %7
%11 = load i32, i32* %5
%12 = sext i32 %11 to i64
%13 = getelementptr inbounds i8, i8* %10, i64 %12
store i8* %13, i8** %8
br label %14
14: ; preds = %35, %3
%15 = load i8*, i8** %7
%16 = load i8*, i8** %8
%17 = icmp ult i8* %15, %16
br i1 %17, label %18, label %38
18: ; preds = %14
%19 = load i16, i16* %6
%20 = zext i16 %19 to i32
%21 = shl i32 %20, 8
%22 = load i16, i16* %6
%23 = zext i16 %22 to i32
%24 = ashr i32 %23, 8
%25 = load i8*, i8** %7
%26 = load i8, i8* %25
%27 = zext i8 %26 to i32
%28 = xor i32 %24, %27
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds [256 x i16], [256 x i16]* @clHCA_CheckSum.v, i64 0, i64 %29
%31 = load i16, i16* %30
%32 = zext i16 %31 to i32
%33 = xor i32 %21, %32
%34 = trunc i32 %33 to i16
store i16 %34, i16* %6
br label %35
35: ; preds = %18
%36 = load i8*, i8** %7
%37 = getelementptr inbounds i8, i8* %36, i32 1
store i8* %37, i8** %7
br label %14
38: ; preds = %14
%39 = load i16, i16* %6
ret i16 %39
}

LLVM IR (-O2):
@clHCA_CheckSum.v = internal unnamed_addr constant [256 x i16] [i16 0, i16 -32763, i16 -32753, i16 10, i16 -32741, i16 30, i16 20, i16 -32751, i16 -32717, i16 54, i16 60, i16 -32711, i16 40, i16 -32723, i16 -32729, i16 34, i16 -32669, i16 102, i16 108, i16 -32663, i16 120, i16 -32643, i16 -32649, i16 114, i16 80, i16 -32683, i16 -32673, i16 90, i16 -32693, i16 78, i16 68, i16 -32703, i16 -32573, i16 198, i16 204, i16 -32567, i16 216, i16 -32547, i16 -32553, i16 210, i16 240, i16 -32523, i16 -32513, i16 250, i16 -32533, i16 238, i16 228, i16 -32543, i16 160, i16 -32603, i16 -32593, i16 170, i16 -32581, i16 190, i16 180, i16 -32591, i16 -32621, i16 150, i16 156, i16 -32615, i16 136, i16 -32627, i16 -32633, i16 130, i16 -32381, i16 390, i16 396, i16 -32375, i16 408, i16 -32355, i16 -32361, i16 402, i16 432, i16 -32331, i16 -32321, i16 442, i16 -32341, i16 430, i16 420, i16 -32351, i16 480, i16 -32283, i16 -32273, i16 490, i16 -32261, i16 510, i16 500, i16 -32271, i16 -32301, i16 470, i16 476, i16 -32295, i16 456, i16 -32307, i16 -32313, i16 450, i16 320, i16 -32443, i16 -32433, i16 330, i16 -32421, i16 350, i16 340, i16 -32431, i16 -32397, i16 374, i16 380, i16 -32391, i16 360, i16 -32403, i16 -32409, i16 354, i16 -32477, i16 294, i16 300, i16 -32471, i16 312, i16 -32451, i16 -32457, i16 306, i16 272, i16 -32491, i16 -32481, i16 282, i16 -32501, i16 270, i16 260, i16 -32511, i16 -31997, i16 774, i16 780, i16 -31991, i16 792, i16 -31971, i16 -31977, i16 786, i16 816, i16 -31947, i16 -31937, i16 826, i16 -31957, i16 814, i16 804, i16 -31967, i16 864, i16 -31899, i16 -31889, i16 874, i16 -31877, i16 894, i16 884, i16 -31887, i16 -31917, i16 854, i16 860, i16 -31911, i16 840, i16 -31923, i16 -31929, i16 834, i16 960, i16 -31803, i16 -31793, i16 970, i16 -31781, i16 990, i16 980, i16 -31791, i16 -31757, i16 1014, i16 1020, i16 -31751, i16 1000, i16 -31763, i16 -31769, i16 994, i16 -31837, i16 934, i16 940, i16 -31831, i16 952, i16 -31811, i16 -31817, i16 946, i16 912, i16 -31851, i16 -31841, i16 922, i16 -31861, i16 910, i16 900, i16 -31871, i16 640, i16 -32123, i16 -32113, i16 650, i16 -32101, i16 670, i16 660, i16 -32111, i16 -32077, i16 694, i16 700, i16 -32071, i16 680, i16 -32083, i16 -32089, i16 674, i16 -32029, i16 742, i16 748, i16 -32023, i16 760, i16 -32003, i16 -32009, i16 754, i16 720, i16 -32043, i16 -32033, i16 730, i16 -32053, i16 718, i16 708, i16 -32063, i16 -32189, i16 582, i16 588, i16 -32183, i16 600, i16 -32163, i16 -32169, i16 594, i16 624, i16 -32139, i16 -32129, i16 634, i16 -32149, i16 622, i16 612, i16 -32159, i16 544, i16 -32219, i16 -32209, i16 554, i16 -32197, i16 574, i16 564, i16 -32207, i16 -32237, i16 534, i16 540, i16 -32231, i16 520, i16 -32243, i16 -32249, i16 514]
define zeroext i16 @clHCA_CheckSum(i8* %0, i32 %1, i16 zeroext %2) {
%4 = sext i32 %1 to i64
%5 = getelementptr inbounds i8, i8* %0, i64 %4
%6 = icmp sgt i32 %1, 0
br i1 %6, label %7, label %21
7: ; preds = %3, %7
%8 = phi i16 [ %18, %7 ], [ %2, %3 ]
%9 = phi i8* [ %19, %7 ], [ %0, %3 ]
%10 = shl i16 %8, 8
%11 = lshr i16 %8, 8
%12 = zext i16 %11 to i64
%13 = load i8, i8* %9
%14 = zext i8 %13 to i64
%15 = xor i64 %14, %12
%16 = getelementptr inbounds [256 x i16], [256 x i16]* @clHCA_CheckSum.v, i64 0, i64 %15
%17 = load i16, i16* %16
%18 = xor i16 %17, %10
%19 = getelementptr inbounds i8, i8* %9, i64 1
%20 = icmp ult i8* %19, %5
br i1 %20, label %7, label %21
21: ; preds = %7, %3
%22 = phi i16 [ %2, %3 ], [ %18, %7 ]
ret i16 %22
}