Repository: numpy/numpy
File: numpy/_core/src/common/simd/avx2/arithmetic.h (C/C++)

Code before:
    __m256i mulhi      = npyv__mullhi_u64(a, divisor.val[0]);
    // floor(a/d)      = (mulhi + ((a-mulhi) >> sh1)) >> sh2
    __m256i q          = _mm256_sub_epi64(a, mulhi);
            q          = _mm256_srl_epi64(q, shf1);
            q          = _mm256_add_epi64(mulhi, q);
            q          = _mm256_srl_epi64(q, shf2);
    return  q;
}
// divide each unsigned 64-bit element by a divisor (round towards zero)
NPY_FINLINE npyv_s64 npyv_divc_s64(npyv_s64 a, const npyv_s64x3 divisor)
{
    const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
    // high part of unsigned multiplication
    __m256i mulhi      = npyv__mullhi_u64(a, divisor.val[0]);
    // convert unsigned to signed high multiplication
    // mulhi - ((a < 0) ? m : 0) - ((m < 0) ? a : 0);
    __m256i asign      = _mm256_cmpgt_epi64(_mm256_setzero_si256(), a);
    __m256i msign      = _mm256_cmpgt_epi64(_mm256_setzero_si256(), divisor.val[0]);
    __m256i m_asign    = _mm256_and_si256(divisor.val[0], asign);
    __m256i a_msign    = _mm256_and_si256(a, msign);
            mulhi      = _mm256_sub_epi64(mulhi, m_asign);
            mulhi      = _mm256_sub_epi64(mulhi, a_msign);
    // q               = (a + mulhi) >> sh
    __m256i q          = _mm256_add_epi64(a, mulhi);
    // emulate arithmetic right shift
    const __m256i sigb = npyv_setall_s64(1LL << 63);
            q          = _mm256_srl_epi64(_mm256_add_epi64(q, sigb), shf1);
            q          = _mm256_sub_epi64(q, _mm256_srl_epi64(sigb, shf1));
    // q               = q - XSIGN(a)
    // trunc(a/d)      = (q ^ dsign) - dsign
            q          = _mm256_sub_epi64(q, asign);
            q          = _mm256_sub_epi64(_mm256_xor_si256(q, divisor.val[2]), divisor.val[2]);
    return  q;
}
/***************************
 * Division
 ***************************/
// TODO: emulate integer division
#define npyv_div_f32 _mm256_div_ps
#define npyv_div_f64 _mm256_div_pd

/***************************
 * FUSED
 ***************************/
#ifdef NPY_HAVE_FMA3
    // multiply and add, a*b + c
    #define npyv_muladd_f32 _mm256_fmadd_ps
    #define npyv_muladd_f64 _mm256_fmadd_pd
    // multiply and subtract, a*b - c
    #define npyv_mulsub_f32 _mm256_fmsub_ps
    #define npyv_mulsub_f64 _mm256_fmsub_pd

Review comment (suggestion):
I suppose it is relatively clear from the `sbit` context, but I wonder if we can at least keep a
```suggestion
    const __m256i sbit = npyv_setall_s64(0x8000000000000000 /* 1 << 63 */);
```
(since I don't have a better idea, I assume `1ULL << 63` doesn't warn, but then we would also need to cast back to long long probably, so dunno that is better)

Code after:
    __m256i mulhi      = npyv__mullhi_u64(a, divisor.val[0]);
    // floor(a/d)      = (mulhi + ((a-mulhi) >> sh1)) >> sh2
    __m256i q          = _mm256_sub_epi64(a, mulhi);
            q          = _mm256_srl_epi64(q, shf1);
            q          = _mm256_add_epi64(mulhi, q);
            q          = _mm256_srl_epi64(q, shf2);
    return  q;
}
// divide each unsigned 64-bit element by a divisor (round towards zero)
NPY_FINLINE npyv_s64 npyv_divc_s64(npyv_s64 a, const npyv_s64x3 divisor)
{
    const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
    // high part of unsigned multiplication
    __m256i mulhi      = npyv__mullhi_u64(a, divisor.val[0]);
    // convert unsigned to signed high multiplication
    // mulhi - ((a < 0) ? m : 0) - ((m < 0) ? a : 0);
    __m256i asign      = _mm256_cmpgt_epi64(_mm256_setzero_si256(), a);
    __m256i msign      = _mm256_cmpgt_epi64(_mm256_setzero_si256(), divisor.val[0]);
    __m256i m_asign    = _mm256_and_si256(divisor.val[0], asign);
    __m256i a_msign    = _mm256_and_si256(a, msign);
            mulhi      = _mm256_sub_epi64(mulhi, m_asign);
            mulhi      = _mm256_sub_epi64(mulhi, a_msign);
    // q               = (a + mulhi) >> sh
    __m256i q          = _mm256_add_epi64(a, mulhi);
    // emulate arithmetic right shift
    const __m256i sbit = npyv_setall_s64(0x8000000000000000);
            q          = _mm256_srl_epi64(_mm256_add_epi64(q, sbit), shf1);
            q          = _mm256_sub_epi64(q, _mm256_srl_epi64(sbit, shf1));
    // q               = q - XSIGN(a)
    // trunc(a/d)      = (q ^ dsign) - dsign
            q          = _mm256_sub_epi64(q, asign);
            q          = _mm256_sub_epi64(_mm256_xor_si256(q, divisor.val[2]), divisor.val[2]);
    return  q;
}
/***************************
 * Division
 ***************************/
// TODO: emulate integer division
#define npyv_div_f32 _mm256_div_ps
#define npyv_div_f64 _mm256_div_pd

/***************************
 * FUSED
 ***************************/
#ifdef NPY_HAVE_FMA3
    // multiply and add, a*b + c
    #define npyv_muladd_f32 _mm256_fmadd_ps
    #define npyv_muladd_f64 _mm256_fmadd_pd
    // multiply and subtract, a*b - c
    #define npyv_mulsub_f32 _mm256_fmsub_ps
    #define npyv_mulsub_f64 _mm256_fmsub_pd