unsigned short checksum_crc_ccitt_uint16(const unsigned char data[],
                                         unsigned int size) {
  static const unsigned short crc_ccitt_table[] = {
      0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108,
      0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210,
      0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b,
      0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401,
      0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee,
      0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6,
      0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d,
      0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
      0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5,
      0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc,
      0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4,
      0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd,
      0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13,
      0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a,
      0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e,
      0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
      0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1,
      0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb,
      0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0,
      0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
      0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657,
      0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9,
      0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882,
      0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
      0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e,
      0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07,
      0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d,
      0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
      0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
  unsigned short crc = 0xffff;
  for (unsigned int i = 0; i < size; ++i)
    crc = (crc << 8) ^ crc_ccitt_table[(crc >> 8) ^ data[i]];
  return crc;
}


x86 assembly (clang, -O0):
<checksum_crc_ccitt_uint16>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
movw   $0xffff,-0xe(%rbp)
movl   $0x0,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0xc(%rbp),%eax
jae    1161 <checksum_crc_ccitt_uint16+0x61>
movzwl -0xe(%rbp),%eax
shl    $0x8,%eax
movzwl -0xe(%rbp),%ecx
sar    $0x8,%ecx
mov    -0x8(%rbp),%rdx
mov    -0x14(%rbp),%esi
movzbl (%rdx,%rsi,1),%edx
xor    %edx,%ecx
movslq %ecx,%rdx
lea    0xeb7(%rip),%rcx
movzwl (%rcx,%rdx,2),%ecx
xor    %ecx,%eax
mov    %ax,-0xe(%rbp)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1118 <checksum_crc_ccitt_uint16+0x18>
movzwl -0xe(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<checksum_crc_ccitt_uint16>:
test   %esi,%esi
je     1114 <checksum_crc_ccitt_uint16+0x14>
mov    %esi,%r8d
cmp    $0x1,%esi
jne    1119 <checksum_crc_ccitt_uint16+0x19>
mov    $0xffff,%ax
xor    %edx,%edx
jmp    116a <checksum_crc_ccitt_uint16+0x6a>
mov    $0xffff,%ax
ret
mov    %r8d,%r10d
and    $0xfffffffe,%r10d
mov    $0xffff,%ax
xor    %edx,%edx
lea    0xed3(%rip),%r9
nopl   (%rax)
movzwl %ax,%eax
mov    %eax,%ecx
shl    $0x8,%ecx
shr    $0x8,%rax
movzbl (%rdi,%rdx,1),%esi
xor    %rax,%rsi
movzwl (%r9,%rsi,2),%eax
xor    %eax,%ecx
shl    $0x8,%eax
movzwl %cx,%ecx
shr    $0x8,%rcx
movzbl 0x1(%rdi,%rdx,1),%esi
xor    %rcx,%rsi
xor    (%r9,%rsi,2),%ax
add    $0x2,%rdx
cmp    %rdx,%r10
jne    1130 <checksum_crc_ccitt_uint16+0x30>
test   $0x1,%r8b
je     118e <checksum_crc_ccitt_uint16+0x8e>
movzwl %ax,%ecx
mov    %ecx,%eax
shl    $0x8,%eax
shr    $0x8,%rcx
movzbl (%rdi,%rdx,1),%edx
xor    %rcx,%rdx
lea    0xe76(%rip),%rcx
xor    (%rcx,%rdx,2),%ax
ret

LLVM IR (-O0):
@checksum_crc_ccitt_uint16.crc_ccitt_table = internal constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
define zeroext i16 @checksum_crc_ccitt_uint16(i8* %0, i32 %1) {
%3 = alloca i8*
%4 = alloca i32
%5 = alloca i16
%6 = alloca i32
store i8* %0, i8** %3
store i32 %1, i32* %4
store i16 -1, i16* %5
store i32 0, i32* %6
br label %7
7: ; preds = %31, %2
%8 = load i32, i32* %6
%9 = load i32, i32* %4
%10 = icmp ult i32 %8, %9
br i1 %10, label %11, label %34
11: ; preds = %7
%12 = load i16, i16* %5
%13 = zext i16 %12 to i32
%14 = shl i32 %13, 8
%15 = load i16, i16* %5
%16 = zext i16 %15 to i32
%17 = ashr i32 %16, 8
%18 = load i8*, i8** %3
%19 = load i32, i32* %6
%20 = zext i32 %19 to i64
%21 = getelementptr inbounds i8, i8* %18, i64 %20
%22 = load i8, i8* %21
%23 = zext i8 %22 to i32
%24 = xor i32 %17, %23
%25 = sext i32 %24 to i64
%26 = getelementptr inbounds [256 x i16], [256 x i16]* @checksum_crc_ccitt_uint16.crc_ccitt_table, i64 0, i64 %25
%27 = load i16, i16* %26
%28 = zext i16 %27 to i32
%29 = xor i32 %14, %28
%30 = trunc i32 %29 to i16
store i16 %30, i16* %5
br label %31
31: ; preds = %11
%32 = load i32, i32* %6
%33 = add i32 %32, 1
store i32 %33, i32* %6
br label %7
34: ; preds = %7
%35 = load i16, i16* %5
ret i16 %35
}

LLVM IR (-O2):
@checksum_crc_ccitt_uint16.crc_ccitt_table = internal unnamed_addr constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
define zeroext i16 @checksum_crc_ccitt_uint16(i8* nocapture %0, i32 %1) {
%3 = icmp eq i32 %1, 0
br i1 %3, label %26, label %4
4: ; preds = %2
%5 = zext i32 %1 to i64
%6 = and i64 %5, 1
%7 = icmp eq i32 %1, 1
br i1 %7, label %10, label %8
8: ; preds = %4
%9 = and i64 %5, 4294967294
br label %28
10: ; preds = %28, %4
%11 = phi i16 [ undef, %4 ], [ %52, %28 ]
%12 = phi i64 [ 0, %4 ], [ %53, %28 ]
%13 = phi i16 [ -1, %4 ], [ %52, %28 ]
%14 = icmp eq i64 %6, 0
br i1 %14, label %26, label %15
15: ; preds = %10
%16 = shl i16 %13, 8
%17 = lshr i16 %13, 8
%18 = zext i16 %17 to i64
%19 = getelementptr inbounds i8, i8* %0, i64 %12
%20 = load i8, i8* %19
%21 = zext i8 %20 to i64
%22 = xor i64 %21, %18
%23 = getelementptr inbounds [256 x i16], [256 x i16]* @checksum_crc_ccitt_uint16.crc_ccitt_table, i64 0, i64 %22
%24 = load i16, i16* %23
%25 = xor i16 %24, %16
br label %26
26: ; preds = %15, %10, %2
%27 = phi i16 [ -1, %2 ], [ %11, %10 ], [ %25, %15 ]
ret i16 %27
28: ; preds = %28, %8
%29 = phi i64 [ 0, %8 ], [ %53, %28 ]
%30 = phi i16 [ -1, %8 ], [ %52, %28 ]
%31 = phi i64 [ 0, %8 ], [ %54, %28 ]
%32 = shl i16 %30, 8
%33 = lshr i16 %30, 8
%34 = zext i16 %33 to i64
%35 = getelementptr inbounds i8, i8* %0, i64 %29
%36 = load i8, i8* %35
%37 = zext i8 %36 to i64
%38 = xor i64 %37, %34
%39 = getelementptr inbounds [256 x i16], [256 x i16]* @checksum_crc_ccitt_uint16.crc_ccitt_table, i64 0, i64 %38
%40 = load i16, i16* %39
%41 = xor i16 %40, %32
%42 = or i64 %29, 1
%43 = shl i16 %40, 8
%44 = lshr i16 %41, 8
%45 = zext i16 %44 to i64
%46 = getelementptr inbounds i8, i8* %0, i64 %42
%47 = load i8, i8* %46
%48 = zext i8 %47 to i64
%49 = xor i64 %48, %45
%50 = getelementptr inbounds [256 x i16], [256 x i16]* @checksum_crc_ccitt_uint16.crc_ccitt_table, i64 0, i64 %49
%51 = load i16, i16* %50
%52 = xor i16 %51, %43
%53 = add nuw nsw i64 %29, 2
%54 = add i64 %31, 2
%55 = icmp eq i64 %54, %9
br i1 %55, label %10, label %28
}