LLVMFuzzerTestOneInput:
    9|     56|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   10|     56|  if (size < sizeof(uint64_t) * 4) {
  ------------------
  |  Branch (10:7): [True: 8, False: 48]
  ------------------
   11|      8|    return 0;
   12|      8|  }
   13|       |
   14|       |  // Generate the key.
   15|     48|  const uint64_t *u64s = reinterpret_cast<const uint64_t*>(data);
   16|     48|  HH_ALIGNAS(32) const HHKey key = {u64s[0], u64s[1], u64s[2], u64s[3]};
  ------------------
  |  |   50|     48|#define HH_ALIGNAS(multiple) __attribute__((aligned(multiple)))
  ------------------
   17|     48|  data += sizeof(uint64_t) * 4;
   18|     48|  size -= sizeof(uint64_t) * 4;
   19|       |
   20|       |  // Compute the hash.
   21|     48|  HHResult64 result;
   22|     48|  InstructionSets::Run<HighwayHash>(key, reinterpret_cast<const char *>(data),
   23|     48|                                    size, &result);
   24|     48|  return 0;
   25|     56|}

_ZN11highwayhash5CpuidEjjPj:
   81|      4|           uint32_t* HH_RESTRICT abcd) {
   82|       |#if HH_MSC_VERSION
   83|       |  int regs[4];
   84|       |  __cpuidex(regs, level, count);
   85|       |  for (int i = 0; i < 4; ++i) {
   86|       |    abcd[i] = regs[i];
   87|       |  }
   88|       |#else
   89|      4|  uint32_t a, b, c, d;
   90|      4|  __cpuid_count(level, count, a, b, c, d);
   91|      4|  abcd[0] = a;
   92|      4|  abcd[1] = b;
   93|      4|  abcd[2] = c;
   94|      4|  abcd[3] = d;
   95|      4|#endif
   96|      4|}

hh_avx2.cc:_ZN11highwayhashL14host_from_le32Ej:
   81|     16|static inline uint32_t host_from_le32(uint32_t x) { return x; }

_ZN11highwayhash4AVX211HHStateAVX2C2EPKm:
   42|     48|  explicit HH_INLINE HHStateAVX2(const HHKey key_lanes) { Reset(key_lanes); }
_ZN11highwayhash4AVX211HHStateAVX25ResetEPKm:
   44|     48|  HH_INLINE void Reset(const HHKey key_lanes) {
   45|       |    // "Nothing up my sleeve" numbers, concatenated hex digits of Pi from
   46|       |    // http://www.numberworld.org/digits/Pi/, retrieved Feb 22, 2016.
   47|       |    //
   48|       |    // We use this python code to generate the fourth number to have
   49|       |    // more even mixture of bits:
   50|       |    /*
   51|       |def x(a,b,c):
   52|       |  retval = 0
   53|       |  for i in range(64):
   54|       |    count = ((a >> i) & 1) + ((b >> i) & 1) + ((c >> i) & 1)
   55|       |    if (count <= 1):
   56|       |      retval |= 1 << i
   57|       |  return retval
   58|       |    */
   59|     48|    const V4x64U init0(0x243f6a8885a308d3ull, 0x13198a2e03707344ull,
   60|     48|                       0xa4093822299f31d0ull, 0xdbe6d5d5fe4cce2full);
   61|     48|    const V4x64U init1(0x452821e638d01377ull, 0xbe5466cf34e90c6cull,
   62|     48|                       0xc0acf169b5f18a8cull, 0x3bd39e10cb0ef593ull);
   63|     48|    const V4x64U key = LoadUnaligned<V4x64U>(key_lanes);
   64|     48|    v0 = key ^ init0;
   65|     48|    v1 = Rotate64By32(key) ^ init1;
   66|     48|    mul0 = init0;
   67|     48|    mul1 = init1;
   68|     48|  }
_ZN11highwayhash4AVX211HHStateAVX212Rotate64By32ERKNS0_4V256ImEE:
  264|     48|  static HH_INLINE V4x64U Rotate64By32(const V4x64U& v) {
  265|     48|    return V4x64U(_mm256_shuffle_epi32(v, _MM_SHUFFLE(2, 3, 0, 1)));
  266|     48|  }
_ZN11highwayhash4AVX211HHStateAVX26UpdateERA32_Kc:
   70|   229k|  HH_INLINE void Update(const HHPacket& packet_bytes) {
   71|   229k|    const uint64_t* HH_RESTRICT packet =
   72|   229k|        reinterpret_cast<const uint64_t * HH_RESTRICT>(packet_bytes);
   73|   229k|    Update(LoadUnaligned<V4x64U>(packet));
   74|   229k|  }
_ZN11highwayhash4AVX211HHStateAVX26UpdateERKNS0_4V256ImEE:
  307|   229k|  HH_INLINE void Update(const V4x64U& packet) {
  308|   229k|    v1 += packet;
  309|   229k|    v1 += mul0;
  310|   229k|    mul0 ^= MulLow32(v1, v0 >> 32);
  311|   229k|    HH_COMPILER_FENCE;
  ------------------
  |  |   85|   229k|#define HH_COMPILER_FENCE asm volatile("" : : : "memory")
  ------------------
  312|   229k|    v0 += mul1;
  313|   229k|    mul1 ^= MulLow32(v0, v1 >> 32);
  314|   229k|    HH_COMPILER_FENCE;
  ------------------
  |  |   85|   229k|#define HH_COMPILER_FENCE asm volatile("" : : : "memory")
  ------------------
  315|   229k|    v0 += ZipperMerge(v1);
  316|   229k|    v1 += ZipperMerge(v0);
  317|   229k|  }
_ZN11highwayhash4AVX211HHStateAVX28MulLow32ERKNS0_4V256ImEES5_:
  286|   459k|  static HH_INLINE V4x64U MulLow32(const V4x64U& a, const V4x64U& b) {
  287|   459k|    return V4x64U(_mm256_mul_epu32(a, b));
  288|   459k|  }
_ZN11highwayhash4AVX211HHStateAVX211ZipperMergeERKNS0_4V256ImEE:
  290|   459k|  static HH_INLINE V4x64U ZipperMerge(const V4x64U& v) {
  291|       |    // Multiplication mixes/scrambles bytes 0-7 of the 64-bit result to
  292|       |    // varying degrees. In descending order of goodness, bytes
  293|       |    // 3 4 2 5 1 6 0 7 have quality 228 224 164 160 100 96 36 32.
  294|       |    // As expected, the upper and lower bytes are much worse.
  295|       |    // For each 64-bit lane, our objectives are:
  296|       |    // 1) maximizing and equalizing total goodness across the four lanes.
  297|       |    // 2) mixing with bytes from the neighboring lane (AVX-2 makes it difficult
  298|       |    //    to cross the 128-bit wall, but PermuteAndUpdate takes care of that);
  299|       |    // 3) placing the worst bytes in the upper 32 bits because those will not
  300|       |    //    be used in the next 32x32 multiplication.
  301|   459k|    const uint64_t hi = 0x070806090D0A040Bull;
  302|   459k|    const uint64_t lo = 0x000F010E05020C03ull;
  303|   459k|    return V4x64U(_mm256_shuffle_epi8(v, V4x64U(hi, lo, hi, lo)));
  304|   459k|  }
_ZN11highwayhash4AVX211HHStateAVX215UpdateRemainderEPKcm:
   76|     21|  HH_INLINE void UpdateRemainder(const char* bytes, const size_t size_mod32) {
   77|       |    // 'Length padding' differentiates zero-valued inputs that have the same
   78|       |    // size/32. mod32 is sufficient because each Update behaves as if a
   79|       |    // counter were injected, because the state is large and mixed thoroughly.
   80|     21|    const V8x32U size256(
   81|     21|        _mm256_broadcastd_epi32(_mm_cvtsi64_si128(size_mod32)));
   82|       |    // Equivalent to storing size_mod32 in packet.
   83|     21|    v0 += V4x64U(size256);
   84|       |    // Boosts the avalanche effect of mod32.
   85|     21|    v1 = Rotate32By(v1, size256);
   86|       |
   87|     21|    const char* remainder = bytes + (size_mod32 & ~3);
   88|     21|    const size_t size_mod4 = size_mod32 & 3;
   89|       |
   90|     21|    const V4x32U size(_mm256_castsi256_si128(size256));
   91|       |
   92|       |    // (Branching is faster than a single _mm256_maskload_epi32.)
   93|     21|    if (HH_UNLIKELY(size_mod32 & 16)) {  // 16..31 bytes left
  ------------------
  |  |   77|     21|#define HH_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
  |  |  ------------------
  |  |  |  Branch (77:27): [True: 16, False: 5]
  |  |  ------------------
  ------------------
   94|     16|      const V4x32U packetL =
   95|     16|          LoadUnaligned<V4x32U>(reinterpret_cast<const uint32_t*>(bytes));
   96|       |
   97|     16|      const V4x32U int_mask = IntMask<16>()(size);
   98|     16|      const V4x32U int_lanes = MaskedLoadInt(bytes + 16, int_mask);
   99|     16|      const uint32_t last4 =
  100|     16|          Load3()(Load3::AllowReadBeforeAndReturn(), remainder, size_mod4);
  101|       |
  102|       |      // The upper four bytes of packetH are zero, so insert there.
  103|     16|      const V4x32U packetH(_mm_insert_epi32(int_lanes, last4, 3));
  104|     16|      Update(packetH, packetL);
  105|     16|    } else {  // size_mod32 < 16
  106|      5|      const V4x32U int_mask = IntMask<0>()(size);
  107|      5|      const V4x32U packetL = MaskedLoadInt(bytes, int_mask);
  108|      5|      const uint64_t last3 =
  109|      5|          Load3()(Load3::AllowUnordered(), remainder, size_mod4);
  110|       |
  111|       |      // Rather than insert into packetL[3], it is faster to initialize
  112|       |      // the otherwise empty packetH.
  113|      5|      const V4x32U packetH(_mm_cvtsi64_si128(last3));
  114|      5|      Update(packetH, packetL);
  115|      5|    }
  116|     21|  }
_ZN11highwayhash4AVX211HHStateAVX210Rotate32ByERKNS0_4V256ImEERKNS2_IjEE:
  269|     21|  static HH_INLINE V4x64U Rotate32By(const V4x64U& v, const V8x32U& count) {
  270|       |    // Use variable shifts because sll_epi32 has 4 cycle latency (presumably
  271|       |    // to broadcast the shift count).
  272|     21|    const V4x64U shifted_left(_mm256_sllv_epi32(v, count));
  273|     21|    const V4x64U shifted_right(_mm256_srlv_epi32(v, V8x32U(32) - count));
  274|     21|    return shifted_left | shifted_right;
  275|     21|  }
_ZN11highwayhash4AVX211HHStateAVX213MaskedLoadIntEPKcRKNS0_4V128IjEE:
  245|     21|                                        const V4x32U& int_mask) {
  246|       |    // No faults will be raised when reading n=0..3 ints from "from" provided
  247|       |    // int_mask[n] = 0.
  248|     21|    const int* HH_RESTRICT int_from = reinterpret_cast<const int*>(from);
  249|     21|    return V4x32U(_mm_maskload_epi32(int_from, int_mask));
  250|     21|  }
_ZN11highwayhash4AVX211HHStateAVX26UpdateERKNS0_4V128IjEES5_:
  319|     21|  HH_INLINE void Update(const V4x32U& packetH, const V4x32U& packetL) {
  320|     21|    const __m256i packetL256 = _mm256_castsi128_si256(packetL);
  321|     21|    Update(V4x64U(_mm256_inserti128_si256(packetL256, packetH, 1)));
  322|     21|  }
_ZN11highwayhash4AVX211HHStateAVX28FinalizeEPm:
  118|     48|  HH_INLINE void Finalize(HHResult64* HH_RESTRICT result) {
  119|       |    // Mix together all lanes. It is slightly better to permute v0 than v1;
  120|       |    // it will be added to v1.
  121|     48|    Update(Permute(v0));
  122|     48|    Update(Permute(v0));
  123|     48|    Update(Permute(v0));
  124|     48|    Update(Permute(v0));
  125|       |
  126|     48|    const V2x64U sum0(_mm256_castsi256_si128(v0 + mul0));
  127|     48|    const V2x64U sum1(_mm256_castsi256_si128(v1 + mul1));
  128|     48|    const V2x64U hash = sum0 + sum1;
  129|       |    // Each lane is sufficiently mixed, so just truncate to 64 bits.
  130|     48|    _mm_storel_epi64(reinterpret_cast<__m128i*>(result), hash);
  131|     48|  }
_ZN11highwayhash4AVX211HHStateAVX27PermuteERKNS0_4V256ImEE:
  277|    192|  static HH_INLINE V4x64U Permute(const V4x64U& v) {
  278|       |    // For complete mixing, we need to swap the upper and lower 128-bit halves;
  279|       |    // we also swap all 32-bit halves. This is faster than extracti128 plus
  280|       |    // inserti128 followed by Rotate64By32.
  281|    192|    const V4x64U indices(0x0000000200000003ull, 0x0000000000000001ull,
  282|    192|                         0x0000000600000007ull, 0x0000000400000005ull);
  283|    192|    return V4x64U(_mm256_permutevar8x32_epi32(v, indices));
  284|    192|  }

_ZNK11highwayhash4AVX27IntMaskILj16EEclERKNS0_4V128IjEE:
   64|     16|  HH_INLINE V4x32U operator()(const V4x32U& size) const {
   65|       |#if HH_TARGET == HH_TARGET_NEON
   66|       |    return V4x32U(vcgtq_u32(size, V4x32U(31, 27, 23, 19)));
   67|       |#else
   68|     16|    return V4x32U(_mm_cmpgt_epi32(size, V4x32U(31, 27, 23, 19)));
   69|     16|#endif
   70|     16|  }
_ZNK11highwayhash4AVX27IntMaskILj0EEclERKNS0_4V128IjEE:
   49|      5|  HH_INLINE V4x32U operator()(const V4x32U& size) const {
   50|       |    // Lane n is valid if size >= (n + 1) * 4; subtract one because we only have
   51|       |    // greater-than comparisons and don't want a negated mask.
   52|       |#if HH_TARGET == HH_TARGET_NEON
   53|       |    return V4x32U(vcgtq_u32(size, V4x32U(15, 11, 7, 3)));
   54|       |#else
   55|      5|    return V4x32U(_mm_cmpgt_epi32(size, V4x32U(15, 11, 7, 3)));
   56|      5|#endif
   57|      5|  }

_ZN11highwayhash12HighwayHashTINS_4AVX211HHStateAVX2EmEEvPT_PKcmPT0_:
  101|     48|                            Result* HH_RESTRICT hash) {
  102|       |  // BeginIACA();
  103|     48|  const size_t remainder = size & (sizeof(HHPacket) - 1);
  104|     48|  const size_t truncated = size & ~(sizeof(HHPacket) - 1);
  105|   229k|  for (size_t offset = 0; offset < truncated; offset += sizeof(HHPacket)) {
  ------------------
  |  Branch (105:27): [True: 229k, False: 48]
  ------------------
  106|   229k|    state->Update(*reinterpret_cast<const HHPacket*>(bytes + offset));
  107|   229k|  }
  108|       |
  109|     48|  if (remainder != 0) {
  ------------------
  |  Branch (109:7): [True: 21, False: 27]
  ------------------
  110|     21|    state->UpdateRemainder(bytes + truncated, remainder);
  111|     21|  }
  112|       |
  113|     48|  state->Finalize(hash);
  114|       |  // EndIACA();
  115|     48|}

_ZNK11highwayhash11HighwayHashILj4EEclERA4_KmPKcmPm:
   40|     48|                                     HHResult64* HH_RESTRICT hash) const {
   41|     48|  HHStateT<Target> state(key);
   42|     48|  HighwayHashT(&state, bytes, size, hash);
   43|     48|}

_ZN11highwayhash15InstructionSets9SupportedEv:
   72|     48|TargetBits InstructionSets::Supported() {
   73|     48|  TargetBits supported = supported_.load(std::memory_order_acquire);
   74|       |  // Already initialized, return that.
   75|     48|  if (HH_LIKELY(supported)) {
  ------------------
  |  |   76|     48|#define HH_LIKELY(expr) __builtin_expect(!!(expr), 1)
  |  |  ------------------
  |  |  |  Branch (76:25): [True: 47, False: 1]
  |  |  ------------------
  ------------------
   76|     47|    return supported;
   77|     47|  }
   78|       |
   79|      1|  uint32_t flags = 0;
   80|      1|  uint32_t abcd[4];
   81|       |
   82|      1|  Cpuid(0, 0, abcd);
   83|      1|  const uint32_t max_level = abcd[0];
   84|       |
   85|       |  // Standard feature flags
   86|      1|  Cpuid(1, 0, abcd);
   87|      1|  flags |= IsBitSet(abcd[3], 25) ? kBitSSE : 0;
  ------------------
  |  Branch (87:12): [True: 1, False: 0]
  ------------------
   88|      1|  flags |= IsBitSet(abcd[3], 26) ? kBitSSE2 : 0;
  ------------------
  |  Branch (88:12): [True: 1, False: 0]
  ------------------
   89|      1|  flags |= IsBitSet(abcd[2], 0) ? kBitSSE3 : 0;
  ------------------
  |  Branch (89:12): [True: 1, False: 0]
  ------------------
   90|      1|  flags |= IsBitSet(abcd[2], 9) ? kBitSSSE3 : 0;
  ------------------
  |  Branch (90:12): [True: 1, False: 0]
  ------------------
   91|      1|  flags |= IsBitSet(abcd[2], 19) ? kBitSSE41 : 0;
  ------------------
  |  Branch (91:12): [True: 1, False: 0]
  ------------------
   92|      1|  flags |= IsBitSet(abcd[2], 20) ? kBitSSE42 : 0;
  ------------------
  |  Branch (92:12): [True: 1, False: 0]
  ------------------
   93|      1|  flags |= IsBitSet(abcd[2], 12) ? kBitFMA : 0;
  ------------------
  |  Branch (93:12): [True: 1, False: 0]
  ------------------
   94|      1|  flags |= IsBitSet(abcd[2], 28) ? kBitAVX : 0;
  ------------------
  |  Branch (94:12): [True: 1, False: 0]
  ------------------
   95|      1|  const bool has_osxsave = IsBitSet(abcd[2], 27);
   96|       |
   97|       |  // Extended feature flags
   98|      1|  Cpuid(0x80000001U, 0, abcd);
   99|      1|  flags |= IsBitSet(abcd[2], 5) ? kBitLZCNT : 0;
  ------------------
  |  Branch (99:12): [True: 1, False: 0]
  ------------------
  100|       |
  101|       |  // Extended features
  102|      1|  if (max_level >= 7) {
  ------------------
  |  Branch (102:7): [True: 1, False: 0]
  ------------------
  103|      1|    Cpuid(7, 0, abcd);
  104|      1|    flags |= IsBitSet(abcd[1], 3) ? kBitBMI : 0;
  ------------------
  |  Branch (104:14): [True: 1, False: 0]
  ------------------
  105|      1|    flags |= IsBitSet(abcd[1], 5) ? kBitAVX2 : 0;
  ------------------
  |  Branch (105:14): [True: 1, False: 0]
  ------------------
  106|      1|    flags |= IsBitSet(abcd[1], 8) ? kBitBMI2 : 0;
  ------------------
  |  Branch (106:14): [True: 1, False: 0]
  ------------------
  107|      1|  }
  108|       |
  109|       |  // Verify OS support for XSAVE, without which XMM/YMM registers are not
  110|       |  // preserved across context switches and are not safe to use.
  111|      1|  if (has_osxsave) {
  ------------------
  |  Branch (111:7): [True: 1, False: 0]
  ------------------
  112|      1|    const uint32_t xcr0 = ReadXCR0();
  113|       |    // XMM
  114|      1|    if ((xcr0 & 2) == 0) {
  ------------------
  |  Branch (114:9): [True: 0, False: 1]
  ------------------
  115|      0|      flags &= ~(kBitSSE | kBitSSE2 | kBitSSE3 | kBitSSSE3 | kBitSSE41 |
  116|      0|                 kBitSSE42 | kBitAVX | kBitAVX2 | kBitFMA);
  117|      0|    }
  118|       |    // YMM
  119|      1|    if ((xcr0 & 4) == 0) {
  ------------------
  |  Branch (119:9): [True: 0, False: 1]
  ------------------
  120|      0|      flags &= ~(kBitAVX | kBitAVX2);
  121|      0|    }
  122|      1|  }
  123|       |
  124|       |  // Also indicates "supported" has been initialized.
  125|      1|  supported = HH_TARGET_Portable;
  ------------------
  |  |  128|      1|#define HH_TARGET_Portable 1
  ------------------
  126|       |
  127|       |  // Set target bit(s) if all their group's flags are all set.
  128|      1|  if ((flags & kGroupAVX2) == kGroupAVX2) {
  ------------------
  |  Branch (128:7): [True: 1, False: 0]
  ------------------
  129|      1|    supported |= HH_TARGET_AVX2;
  ------------------
  |  |  130|      1|#define HH_TARGET_AVX2 4
  ------------------
  130|      1|  }
  131|      1|  if ((flags & kGroupSSE41) == kGroupSSE41) {
  ------------------
  |  Branch (131:7): [True: 1, False: 0]
  ------------------
  132|      1|    supported |= HH_TARGET_SSE41;
  ------------------
  |  |  129|      1|#define HH_TARGET_SSE41 2
  ------------------
  133|      1|  }
  134|       |
  135|      1|  supported_.store(supported, std::memory_order_release);
  136|      1|  return supported;
  137|     48|}
instruction_sets.cc:_ZN11highwayhash12_GLOBAL__N_18IsBitSetEji:
   28|     13|bool IsBitSet(const uint32_t reg, const int index) {
   29|     13|  return (reg & (1U << index)) != 0;
   30|     13|}
instruction_sets.cc:_ZN11highwayhash12_GLOBAL__N_18ReadXCR0Ev:
   34|      1|uint32_t ReadXCR0() {
   35|       |#if HH_MSC_VERSION
   36|       |  return static_cast<uint32_t>(_xgetbv(0));
   37|       |#else
   38|      1|  uint32_t xcr0, xcr0_high;
   39|      1|  const uint32_t index = 0;
   40|      1|  asm volatile(".byte 0x0F, 0x01, 0xD0"
   41|      1|               : "=a"(xcr0), "=d"(xcr0_high)
   42|      1|               : "c"(index));
   43|      1|  return xcr0;
   44|      1|#endif
   45|      1|}

_ZN11highwayhash15InstructionSets3RunINS_11HighwayHashEJRA4_KmPKcRmPmEEEjDpOT0_:
   56|     48|  static HH_INLINE TargetBits Run(Args&&... args) {
   57|     48|#if HH_ARCH_X64
   58|     48|    const TargetBits supported = Supported();
   59|     48|    if (supported & HH_TARGET_AVX2) {
  ------------------
  |  |  130|     48|#define HH_TARGET_AVX2 4
  ------------------
  |  Branch (59:9): [True: 48, False: 0]
  ------------------
   60|     48|      Func<HH_TARGET_AVX2>()(std::forward<Args>(args)...);
   61|     48|      return HH_TARGET_AVX2;
  ------------------
  |  |  130|     48|#define HH_TARGET_AVX2 4
  ------------------
   62|     48|    }
   63|      0|    if (supported & HH_TARGET_SSE41) {
  ------------------
  |  |  129|      0|#define HH_TARGET_SSE41 2
  ------------------
  |  Branch (63:9): [True: 0, False: 0]
  ------------------
   64|      0|      Func<HH_TARGET_SSE41>()(std::forward<Args>(args)...);
   65|      0|      return HH_TARGET_SSE41;
  ------------------
  |  |  129|      0|#define HH_TARGET_SSE41 2
  ------------------
   66|      0|    }
   67|       |#elif HH_ARCH_PPC
   68|       |    const TargetBits supported = Supported();
   69|       |    if (supported & HH_TARGET_VSX) {
   70|       |      Func<HH_TARGET_VSX>()(std::forward<Args>(args)...);
   71|       |      return HH_TARGET_VSX;
   72|       |    }
   73|       |#elif HH_ARCH_NEON
   74|       |    const TargetBits supported = Supported();
   75|       |    if (supported & HH_TARGET_NEON) {
   76|       |      Func<HH_TARGET_NEON>()(std::forward<Args>(args)...);
   77|       |      return HH_TARGET_NEON;
   78|       |    }
   79|       |#endif
   80|       |
   81|       |    // No matching HH_ARCH or no supported HH_TARGET:
   82|      0|    Func<HH_TARGET_Portable>()(std::forward<Args>(args)...);
   83|      0|    return HH_TARGET_Portable;
  ------------------
  |  |  128|      0|#define HH_TARGET_Portable 1
  ------------------
   84|      0|  }

_ZN11highwayhash4AVX25Load3clENS1_24AllowReadBeforeAndReturnEPKcm:
   53|     16|                                const size_t size_mod4) {
   54|       |    // It's safe to read before "from", so we can load 32 bits, which is faster
   55|       |    // than individual byte loads. We assume little-endian byte order, so
   56|       |    // big-endian platforms will need to swap. Type punning can generate
   57|       |    // incorrect code if compiled with strict aliasing; the only safe
   58|       |    // alternatives are memcpy and reading through char*. We must avoid memcpy
   59|       |    // because string.h must not be included per the warning above. On GCC and
   60|       |    // Clang, we can use a builtin instead.
   61|     16|    uint32_t last4;
   62|     16|    Copy(from + size_mod4 - 4, 4, reinterpret_cast<char*>(&last4));
   63|     16|    return host_from_le32(last4);
   64|     16|  }
_ZN11highwayhash4AVX25Load34CopyEPKcmPc:
  130|     16|                             char* HH_RESTRICT to) {
  131|       |#if HH_MSC_VERSION
  132|       |    for (size_t i = 0; i < size; ++i) {
  133|       |      to[i] = from[i];
  134|       |    }
  135|       |#else
  136|     16|    __builtin_memcpy(to, from, size);
  137|     16|#endif
  138|     16|  }
_ZN11highwayhash4AVX25Load3clENS1_14AllowUnorderedEPKcm:
   81|      5|                                const size_t size_mod4) {
   82|      5|    uint64_t last3 = 0;
   83|       |    // Not allowed to read any bytes; early-out is faster than reading from a
   84|       |    // constant array of zeros.
   85|      5|    if (size_mod4 == 0) {
  ------------------
  |  Branch (85:9): [True: 1, False: 4]
  ------------------
   86|      1|      return last3;
   87|      1|    }
   88|       |
   89|       |    // These indices are chosen as an easy-to-compute sequence containing the
   90|       |    // same elements as [0, size), but repeated and/or reordered. This enables
   91|       |    // unconditional loads, which outperform conditional 8 or 16+8 bit loads.
   92|      4|    const uint64_t idx0 = 0;
   93|      4|    const uint64_t idx1 = size_mod4 >> 1;
   94|      4|    const uint64_t idx2 = size_mod4 - 1;
   95|       |    // Store into least significant bytes (avoids one shift).
   96|      4|    last3 = U64FromChar(from[idx0]);
   97|      4|    last3 += U64FromChar(from[idx1]) << 8;
   98|      4|    last3 += U64FromChar(from[idx2]) << 16;
   99|      4|    return last3;
  100|      5|  }
_ZN11highwayhash4AVX25Load311U64FromCharEc:
  125|     12|  static HH_INLINE uint64_t U64FromChar(const char c) {
  126|     12|    return static_cast<uint64_t>(static_cast<unsigned char>(c));
  127|     12|  }

_ZN11highwayhash4AVX24V128IjEC2ERKDv2_x:
  235|    216|  HH_INLINE V128(const Intrinsic& v) : v_(v) {}
_ZN11highwayhash4AVX213LoadUnalignedINS0_4V128IjEEEET_PKNS4_1TE:
  660|     16|LoadUnaligned<V4x32U>(const V4x32U::T* const HH_RESTRICT from) {
  661|     16|  const __m128i* const HH_RESTRICT p = reinterpret_cast<const __m128i*>(from);
  662|     16|  return V4x32U(_mm_loadu_si128(p));
  663|     16|}
_ZNK11highwayhash4AVX24V128IjEcvDv2_xEv:
  240|    237|  HH_INLINE operator Intrinsic() const { return v_; }
_ZN11highwayhash4AVX24V128IjEC2Ejjjj:
  220|     21|      : v_(_mm_set_epi32(p_3, p_2, p_1, p_0)) {}
_ZN11highwayhash4AVX24V128ImEC2ERKDv2_x:
  317|    192|  HH_INLINE V128(const Intrinsic& v) : v_(v) {}
_ZN11highwayhash4AVX2plImEENS0_4V128IT_EERKS4_S6_:
  543|     48|HH_INLINE V128<T> operator+(const V128<T>& left, const V128<T>& right) {
  544|     48|  V128<T> t(left);
  545|     48|  return t += right;
  546|     48|}
_ZN11highwayhash4AVX24V128ImEC2ERKS2_:
  308|     48|  HH_INLINE explicit V128(const V128& other) : v_(other.v_) {}
_ZN11highwayhash4AVX24V128ImEpLERKS2_:
  329|     48|  HH_INLINE V128& operator+=(const V128& other) {
  330|     48|    v_ = _mm_add_epi64(v_, other.v_);
  331|     48|    return *this;
  332|     48|  }
_ZNK11highwayhash4AVX24V128ImEcvDv2_xEv:
  322|    144|  HH_INLINE operator Intrinsic() const { return v_; }

_ZN11highwayhash4AVX24V256ImEC2Ev:
  282|    192|  HH_INLINE V256() {}
_ZN11highwayhash4AVX24V256ImEC2Emmmm:
  286|   459k|      : v_(_mm256_set_epi64x(p_3, p_2, p_1, p_0)) {}
_ZN11highwayhash4AVX213LoadUnalignedINS0_4V256ImEEEET_PKNS4_1TE:
  630|   229k|HH_INLINE V4x64U LoadUnaligned(const V4x64U::T* const HH_RESTRICT from) {
  631|   229k|  const __m256i* const HH_RESTRICT p = reinterpret_cast<const __m256i*>(from);
  632|   229k|  return V4x64U(_mm256_loadu_si256(p));
  633|   229k|}
_ZNK11highwayhash4AVX24V256ImEcvDv4_xEv:
  307|  3.44M|  HH_INLINE operator Intrinsic() const { return v_; }
_ZN11highwayhash4AVX24V256ImEC2ERKDv4_x:
  302|  2.75M|  HH_INLINE V256(const Intrinsic& v) : v_(v) {}
_ZN11highwayhash4AVX2eoImEENS0_4V256IT_EERKS4_S6_:
  545|     96|HH_INLINE V256<T> operator^(const V256<T>& left, const V256<T>& right) {
  546|     96|  V256<T> t(left);
  547|     96|  return t ^= right;
  548|     96|}
_ZN11highwayhash4AVX24V256ImEC2ERKS2_:
  293|   459k|  HH_INLINE explicit V256(const V256& other) : v_(other.v_) {}
_ZN11highwayhash4AVX24V256ImEeOERKS2_:
  331|   459k|  HH_INLINE V256& operator^=(const V256& other) {
  332|   459k|    v_ = _mm256_xor_si256(v_, other.v_);
  333|   459k|    return *this;
  334|   459k|  }
_ZN11highwayhash4AVX24V256ImEaSERKS2_:
  296|    213|  HH_INLINE V256& operator=(const V256& other) {
  297|    213|    v_ = other.v_;
  298|    213|    return *this;
  299|    213|  }
_ZN11highwayhash4AVX24V256ImEpLERKS2_:
  314|  1.14M|  HH_INLINE V256& operator+=(const V256& other) {
  315|  1.14M|    v_ = _mm256_add_epi64(v_, other.v_);
  316|  1.14M|    return *this;
  317|  1.14M|  }
_ZN11highwayhash4AVX2rsImEENS0_4V256IT_EERKS4_i:
  557|   459k|HH_INLINE V256<T> operator>>(const V256<T>& v, const int count) {
  558|   459k|  V256<T> t(v);
  559|   459k|  return t >>= count;
  560|   459k|}
_ZN11highwayhash4AVX24V256ImErSEi:
  341|   459k|  HH_INLINE V256& operator>>=(const int count) {
  342|   459k|    v_ = _mm256_srli_epi64(v_, count);
  343|   459k|    return *this;
  344|   459k|  }
_ZN11highwayhash4AVX24V256IjEC2ERKDv4_x:
  226|     42|  HH_INLINE V256(const Intrinsic& v) : v_(v) {}
_ZN11highwayhash4AVX24V256ImEC2IjEERKNS1_IT_EE:
  295|     21|  HH_INLINE explicit V256(const V256<U>& other) : v_(other) {}
_ZN11highwayhash4AVX2miIjEENS0_4V256IT_EERKS4_S6_:
  527|     21|HH_INLINE V256<T> operator-(const V256<T>& left, const V256<T>& right) {
  528|     21|  V256<T> t(left);
  529|     21|  return t -= right;
  530|     21|}
_ZN11highwayhash4AVX24V256IjEC2ERKS2_:
  217|     21|  HH_INLINE explicit V256(const V256& other) : v_(other.v_) {}
_ZN11highwayhash4AVX24V256IjEmIERKS2_:
  242|     21|  HH_INLINE V256& operator-=(const V256& other) {
  243|     21|    v_ = _mm256_sub_epi32(v_, other.v_);
  244|     21|    return *this;
  245|     21|  }
_ZN11highwayhash4AVX24V256IjEC2Ej:
  214|     21|      : v_(_mm256_broadcastd_epi32(_mm_cvtsi32_si128(i))) {}
_ZN11highwayhash4AVX2orImEENS0_4V256IT_EES4_RKS4_:
  539|     21|HH_INLINE V256<T> operator|(const V256<T> left, const V256<T>& right) {
  540|     21|  V256<T> t(left);
  541|     21|  return t |= right;
  542|     21|}
_ZN11highwayhash4AVX24V256ImEoRERKS2_:
  327|     21|  HH_INLINE V256& operator|=(const V256& other) {
  328|     21|    v_ = _mm256_or_si256(v_, other.v_);
  329|     21|    return *this;
  330|     21|  }
_ZNK11highwayhash4AVX24V256IjEcvDv4_xEv:
  231|    105|  HH_INLINE operator Intrinsic() const { return v_; }
_ZN11highwayhash4AVX2plImEENS0_4V256IT_EERKS4_S6_:
  521|     96|HH_INLINE V256<T> operator+(const V256<T>& left, const V256<T>& right) {
  522|     96|  V256<T> t(left);
  523|     96|  return t += right;
  524|     96|}

