https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115161

--- Comment #22 from Sergei Trofimovich <slyfox at gcc dot gnu.org> ---
(In reply to Sergei Trofimovich from comment #21)

gcc generates the following code for this C code:

> int main() {
>   const __m128i su = _mm_set1_epi32(0x4f800000);
>   const __m128  sf = _mm_castsi128_ps(su);
> 
>   const __m128  overflow_mask_f32 = _mm_cmpge_ps(sf,
> _mm_set1_ps(2147483648.0f));
>   const __m128i overflow_mask = _mm_castps_si128(overflow_mask_f32);
> 
>   const __m128i conv = _mm_cvttps_epi32(sf); // overflows
>   const __m128i yes = _mm_set1_epi32(INT32_MAX);
> 
>   const __m128i a = _mm_and_si128(overflow_mask, yes);
>   const __m128i na = _mm_andnot_si128(overflow_mask, conv);
> 
>   const __m128i conv_masked = _mm_or_si128(a, na);

Dump of assembler code for function main:
   0x0000000000401020 <+0>:     sub    $0x8,%rsp
   0x0000000000401024 <+4>:     movss  0xfdc(%rip),%xmm2        # 0x402008
   0x000000000040102c <+12>:    movss  0xfd0(%rip),%xmm0        # 0x402004
   0x0000000000401034 <+20>:    movss  0xfd0(%rip),%xmm3        # 0x40200c
   0x000000000040103c <+28>:    shufps $0x0,%xmm2,%xmm2
   0x0000000000401040 <+32>:    shufps $0x0,%xmm0,%xmm0
   0x0000000000401044 <+36>:    cmpleps %xmm2,%xmm0
   0x0000000000401048 <+40>:    cvttps2dq %xmm2,%xmm2
   0x000000000040104c <+44>:    shufps $0x0,%xmm3,%xmm3
   0x0000000000401050 <+48>:    movdqa %xmm0,%xmm1
   0x0000000000401054 <+52>:    andps  %xmm3,%xmm0
   0x0000000000401057 <+55>:    pandn  %xmm2,%xmm1
   0x000000000040105b <+59>:    por    %xmm0,%xmm1

All of this all looks fine.

>   const __m128i actual = _mm_cmpeq_epi32(conv_masked,
> _mm_set1_epi32(INT32_MAX));
>   const __m128i expected = _mm_set1_epi32(-1);

   0x000000000040105f <+63>:    pcmpeqd %xmm0,%xmm0
   0x0000000000401063 <+67>:    pcmpeqd %xmm2,%xmm1
   0x0000000000401067 <+71>:    call   0x401160 <_ZL9assert_eqDv2_xS_>

Here `pcmpeqd %xmm2,%xmm1` is a problematic instruction. Why does `gcc` use
`%xmm2` (result of `cvttps2dq`) instead of, say `%xmm0` which contains
`0xFFFFffff` pattern?

>   assert_eq(expected, actual);
> }
> ```

Reply via email to