#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef size_t const uint8_t;
typedef int uint16_t;

/* Variables and functions */
uint16_t crc16(uint8_t const msg[], size_t const msg_size) {
  static uint16_t const crc16_table[256] = {
      0x0,    0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108,
      0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x210,
      0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B,
      0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x420,  0x1401,
      0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE,
      0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x630,  0x76D7, 0x66F6,
      0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D,
      0xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x840,  0x1861, 0x2802, 0x3823,
      0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5,
      0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0xA50,  0x3A33, 0x2A12, 0xDBFD, 0xCBDC,
      0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4,
      0x5CC5, 0x2C22, 0x3C03, 0xC60,  0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD,
      0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13,
      0x2E32, 0x1E51, 0xE70,  0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A,
      0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E,
      0xE16F, 0x1080, 0xA1,   0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
      0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x2B1,
      0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB,
      0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0,
      0x481,  0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8,
      0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x691,  0x16B0, 0x6657,
      0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9,
      0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x8E1,  0x3882,
      0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
      0x4A75, 0x5A54, 0x6A37, 0x7A16, 0xAF1,  0x1AD0, 0x2AB3, 0x3A92, 0xFD2E,
      0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07,
      0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0xCC1,  0xEF1F, 0xFF3E, 0xCF5D,
      0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74,
      0x2E93, 0x3EB2, 0xED1,  0x1EF0};
  uint16_t crc = 0xFFFF;
  {
    uint8_t const *it = msg;
    for (; it != msg + msg_size; ++it) {
      size_t const idx = (uint8_t)(crc >> 8) ^ *it;
      crc = (uint16_t)(crc << 8) ^ crc16_table[idx];
    }
  }
  return crc;
}


x86 assembly (clang, -O0):
<crc16>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0xffff,-0x14(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
mov    -0x8(%rbp),%rcx
mov    -0x10(%rbp),%rdx
shl    $0x3,%rdx
add    %rdx,%rcx
cmp    %rcx,%rax
je     1172 <crc16+0x72>
mov    -0x14(%rbp),%eax
sar    $0x8,%eax
cltq
mov    -0x20(%rbp),%rcx
xor    (%rcx),%rax
mov    %rax,-0x28(%rbp)
mov    -0x14(%rbp),%eax
shl    $0x8,%eax
mov    -0x28(%rbp),%rdx
lea    0xea5(%rip),%rcx
xor    (%rcx,%rdx,4),%eax
mov    %eax,-0x14(%rbp)
mov    -0x20(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x20(%rbp)
jmp    111b <crc16+0x1b>
mov    -0x14(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<crc16>:
test   %rsi,%rsi
je     113d <crc16+0x3d>
shl    $0x3,%rsi
mov    $0xffff,%eax
xor    %ecx,%ecx
lea    0xee9(%rip),%r8
nopw   0x0(%rax,%rax,1)
mov    %eax,%edx
sar    $0x8,%edx
movslq %edx,%rdx
xor    (%rdi,%rcx,1),%rdx
shl    $0x8,%eax
xor    (%r8,%rdx,4),%eax
add    $0x8,%rcx
cmp    %rcx,%rsi
jne    1120 <crc16+0x20>
ret
mov    $0xffff,%eax
ret

LLVM IR (-O0):
@crc16.crc16_table = internal constant [256 x i32] [i32 0, i32 4129, i32 8258, i32 12387, i32 16516, i32 20645, i32 24774, i32 28903, i32 33032, i32 37161, i32 41290, i32 45419, i32 49548, i32 53677, i32 57806, i32 61935, i32 4657, i32 528, i32 12915, i32 8786, i32 21173, i32 17044, i32 29431, i32 25302, i32 37689, i32 33560, i32 45947, i32 41818, i32 54205, i32 50076, i32 62463, i32 58334, i32 9314, i32 13379, i32 1056, i32 5121, i32 25830, i32 29895, i32 17572, i32 21637, i32 42346, i32 46411, i32 34088, i32 38153, i32 58862, i32 62927, i32 50604, i32 54669, i32 13907, i32 9842, i32 5649, i32 1584, i32 30423, i32 26358, i32 22165, i32 18100, i32 46939, i32 42874, i32 38681, i32 34616, i32 63455, i32 59390, i32 55197, i32 51132, i32 18628, i32 22757, i32 26758, i32 30887, i32 2112, i32 6241, i32 10242, i32 14371, i32 51660, i32 55789, i32 59790, i32 63919, i32 35144, i32 39273, i32 43274, i32 47403, i32 23285, i32 19156, i32 31415, i32 27286, i32 6769, i32 2640, i32 14899, i32 10770, i32 56317, i32 52188, i32 64447, i32 60318, i32 39801, i32 35672, i32 47931, i32 43802, i32 27814, i32 31879, i32 19684, i32 23749, i32 11298, i32 15363, i32 3168, i32 7233, i32 60846, i32 64911, i32 52716, i32 56781, i32 44330, i32 48395, i32 36200, i32 40265, i32 32407, i32 28342, i32 24277, i32 20212, i32 15891, i32 11826, i32 7761, i32 3696, i32 65439, i32 61374, i32 57309, i32 53244, i32 48923, i32 44858, i32 40793, i32 36728, i32 37256, i32 33193, i32 45514, i32 41451, i32 53516, i32 49453, i32 61774, i32 57711, i32 4224, i32 161, i32 12482, i32 8419, i32 20484, i32 16421, i32 28742, i32 24679, i32 33721, i32 37784, i32 41979, i32 46042, i32 49981, i32 54044, i32 58239, i32 62302, i32 689, i32 4752, i32 8947, i32 13010, i32 16949, i32 21012, i32 25207, i32 29270, i32 46570, i32 42443, i32 38312, i32 34185, i32 62830, i32 58703, i32 54572, i32 50445, i32 13538, i32 9411, i32 5280, i32 1153, i32 29798, i32 25671, i32 21540, i32 17413, i32 42971, i32 47098, i32 34713, i32 38840, i32 59231, i32 63358, i32 50973, i32 55100, i32 9939, i32 14066, i32 1681, i32 5808, i32 26199, i32 30326, i32 17941, i32 22068, i32 55628, i32 51565, i32 63758, i32 59695, i32 39368, i32 35305, i32 47498, i32 43435, i32 22596, i32 18533, i32 30726, i32 26663, i32 6336, i32 2273, i32 14466, i32 10403, i32 52093, i32 56156, i32 60223, i32 64286, i32 35833, i32 39896, i32 43963, i32 48026, i32 19061, i32 23124, i32 27191, i32 31254, i32 2801, i32 6864, i32 10931, i32 14994, i32 64814, i32 60687, i32 56684, i32 52557, i32 48554, i32 44427, i32 40424, i32 36297, i32 31782, i32 27655, i32 23652, i32 19525, i32 15522, i32 11395, i32 7392, i32 3265, i32 61215, i32 65342, i32 53085, i32 57212, i32 44955, i32 49082, i32 36825, i32 40952, i32 28183, i32 32310, i32 20053, i32 24180, i32 11923, i32 16050, i32 3793, i32 7920]
define i32 @crc16(i64* %0, i64 %1) {
%3 = alloca i64*
%4 = alloca i64
%5 = alloca i32
%6 = alloca i64*
%7 = alloca i64
store i64* %0, i64** %3
store i64 %1, i64* %4
store i32 65535, i32* %5
%8 = load i64*, i64** %3
store i64* %8, i64** %6
br label %9
9: ; preds = %28, %2
%10 = load i64*, i64** %6
%11 = load i64*, i64** %3
%12 = load i64, i64* %4
%13 = getelementptr inbounds i64, i64* %11, i64 %12
%14 = icmp ne i64* %10, %13
br i1 %14, label %15, label %31
15: ; preds = %9
%16 = load i32, i32* %5
%17 = ashr i32 %16, 8
%18 = sext i32 %17 to i64
%19 = load i64*, i64** %6
%20 = load i64, i64* %19
%21 = xor i64 %18, %20
store i64 %21, i64* %7
%22 = load i32, i32* %5
%23 = shl i32 %22, 8
%24 = load i64, i64* %7
%25 = getelementptr inbounds [256 x i32], [256 x i32]* @crc16.crc16_table, i64 0, i64 %24
%26 = load i32, i32* %25
%27 = xor i32 %23, %26
store i32 %27, i32* %5
br label %28
28: ; preds = %15
%29 = load i64*, i64** %6
%30 = getelementptr inbounds i64, i64* %29, i32 1
store i64* %30, i64** %6
br label %9
31: ; preds = %9
%32 = load i32, i32* %5
ret i32 %32
}

LLVM IR (-O2):
@crc16.crc16_table = internal unnamed_addr constant [256 x i32] [i32 0, i32 4129, i32 8258, i32 12387, i32 16516, i32 20645, i32 24774, i32 28903, i32 33032, i32 37161, i32 41290, i32 45419, i32 49548, i32 53677, i32 57806, i32 61935, i32 4657, i32 528, i32 12915, i32 8786, i32 21173, i32 17044, i32 29431, i32 25302, i32 37689, i32 33560, i32 45947, i32 41818, i32 54205, i32 50076, i32 62463, i32 58334, i32 9314, i32 13379, i32 1056, i32 5121, i32 25830, i32 29895, i32 17572, i32 21637, i32 42346, i32 46411, i32 34088, i32 38153, i32 58862, i32 62927, i32 50604, i32 54669, i32 13907, i32 9842, i32 5649, i32 1584, i32 30423, i32 26358, i32 22165, i32 18100, i32 46939, i32 42874, i32 38681, i32 34616, i32 63455, i32 59390, i32 55197, i32 51132, i32 18628, i32 22757, i32 26758, i32 30887, i32 2112, i32 6241, i32 10242, i32 14371, i32 51660, i32 55789, i32 59790, i32 63919, i32 35144, i32 39273, i32 43274, i32 47403, i32 23285, i32 19156, i32 31415, i32 27286, i32 6769, i32 2640, i32 14899, i32 10770, i32 56317, i32 52188, i32 64447, i32 60318, i32 39801, i32 35672, i32 47931, i32 43802, i32 27814, i32 31879, i32 19684, i32 23749, i32 11298, i32 15363, i32 3168, i32 7233, i32 60846, i32 64911, i32 52716, i32 56781, i32 44330, i32 48395, i32 36200, i32 40265, i32 32407, i32 28342, i32 24277, i32 20212, i32 15891, i32 11826, i32 7761, i32 3696, i32 65439, i32 61374, i32 57309, i32 53244, i32 48923, i32 44858, i32 40793, i32 36728, i32 37256, i32 33193, i32 45514, i32 41451, i32 53516, i32 49453, i32 61774, i32 57711, i32 4224, i32 161, i32 12482, i32 8419, i32 20484, i32 16421, i32 28742, i32 24679, i32 33721, i32 37784, i32 41979, i32 46042, i32 49981, i32 54044, i32 58239, i32 62302, i32 689, i32 4752, i32 8947, i32 13010, i32 16949, i32 21012, i32 25207, i32 29270, i32 46570, i32 42443, i32 38312, i32 34185, i32 62830, i32 58703, i32 54572, i32 50445, i32 13538, i32 9411, i32 5280, i32 1153, i32 29798, i32 25671, i32 21540, i32 17413, i32 42971, i32 47098, i32 34713, i32 38840, i32 59231, i32 63358, i32 50973, i32 55100, i32 9939, i32 14066, i32 1681, i32 5808, i32 26199, i32 30326, i32 17941, i32 22068, i32 55628, i32 51565, i32 63758, i32 59695, i32 39368, i32 35305, i32 47498, i32 43435, i32 22596, i32 18533, i32 30726, i32 26663, i32 6336, i32 2273, i32 14466, i32 10403, i32 52093, i32 56156, i32 60223, i32 64286, i32 35833, i32 39896, i32 43963, i32 48026, i32 19061, i32 23124, i32 27191, i32 31254, i32 2801, i32 6864, i32 10931, i32 14994, i32 64814, i32 60687, i32 56684, i32 52557, i32 48554, i32 44427, i32 40424, i32 36297, i32 31782, i32 27655, i32 23652, i32 19525, i32 15522, i32 11395, i32 7392, i32 3265, i32 61215, i32 65342, i32 53085, i32 57212, i32 44955, i32 49082, i32 36825, i32 40952, i32 28183, i32 32310, i32 20053, i32 24180, i32 11923, i32 16050, i32 3793, i32 7920]
define i32 @crc16(i64* %0, i64 %1) {
%3 = getelementptr inbounds i64, i64* %0, i64 %1
%4 = icmp eq i64 %1, 0
br i1 %4, label %18, label %5
5: ; preds = %2, %5
%6 = phi i32 [ %15, %5 ], [ 65535, %2 ]
%7 = phi i64* [ %16, %5 ], [ %0, %2 ]
%8 = ashr i32 %6, 8
%9 = sext i32 %8 to i64
%10 = load i64, i64* %7
%11 = xor i64 %10, %9
%12 = shl i32 %6, 8
%13 = getelementptr inbounds [256 x i32], [256 x i32]* @crc16.crc16_table, i64 0, i64 %11
%14 = load i32, i32* %13
%15 = xor i32 %14, %12
%16 = getelementptr inbounds i64, i64* %7, i64 1
%17 = icmp eq i64* %16, %3
br i1 %17, label %18, label %5
18: ; preds = %5, %2
%19 = phi i32 [ 65535, %2 ], [ %15, %5 ]
ret i32 %19
}