title: How to implement an efficient _mm256_madd_epi8?
body: <p>Intel provides a C style function named _mm256_madd_epi16, which basically</p>
  
  <blockquote>
    <p>__m256i _mm256_madd_epi16 (__m256i a, __m256i b)</p>
    
    <p>Multiply packed signed 16-bit integers in a and b, producing intermediate signed 32-bit integers. Horizontally add adjacent pairs of intermediate 32-bit integers, and pack the results in dst.</p>
  </blockquote>
  
  <p>Now I have two __m256i variables, each of them has 32 8-bit int in it.</p>
  
  <p>I want to implement the same functionality as <code>_mm256_madd_epi16</code> does, but each int32_t element in the result __m256i is the <strong>sum of four products of signed char instead of two pairs of signed <code>int16_t</code>.</strong></p>
  
  <p>I can do that in a scalar loop:</p>
  
  <pre><code>  alignas(32) uint32_t res[8];
    for (int i = 0; i &lt; 32; ++i)
        res[i / 4] += _mm256_extract_epi8(a, i) * _mm256_extract_epi8(b, i);
    return _mm256_load_si256((__m256i*)res);
  </code></pre>
  
  <p>Note that the multiply result is <em>sign</em>-extended to <code>int</code> before adding, and that the <code>_mm256_extract_epi8</code> helper function<sup>1</sup>  <a href="https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=4090,2293&amp;text=_mm256_extract_" rel="nofollow noreferrer">returns signed <code>__int8</code></a>.  Nevermind that the total is <code>uint32_t</code> instead of <code>int32_t</code>; it can't overflow anyway with only four 8x8 => 16-bit numbers to add.</p>
  
  <p>It looks very ugly, and doesn't runs efficiently unless the compiler does some magic to do it with SIMD instead of compiling as written to scalar extraction.</p>
  
  <hr>
  
  <p>Footnote 1:  <code>_mm256_extract_epi8</code> is not an intrinsic.  <code>vpextrb</code> only works for the low lane of a 256-bit vector, and this helper function may allow an index that isn't a compile-time constant.</p>