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

--- Comment #3 from Peter Cordes <peter at cordes dot ca> ---
(In reply to Marc Glisse from comment #2)
> Does anything bad happen if you remove the #ifdef/#endif for
> _mm_cvtsi64_si128? (2 files in the testsuite would need updating for a
> proper patch)

It's just a wrapper for

_mm_cvtsi64_si128 (long long __A) {
  return _mm_set_epi64x (0, __A);
}

and _mm_set_epi64x is already available in 32-bit mode.

I tried using _mm_set_epi64x(0, i) (https://godbolt.org/g/24AYPk), and got the
expected results (same as with _mm_loadl_epi64(&i));

__m128i movq_test(uint64_t *p) {
  return _mm_set_epi64x( 0, *p );
}

        movl    4(%esp), %eax
        vmovq   (%eax), %xmm0
        ret

For the test where we shift before movq, it still uses 32-bit integer
double-precision shifts, stores to the stack, then vmovq (instead of optimizing
to  vmovq / vpsllq)


For the reverse, we get:

long long extract(__m128i v) {
    return ((__v2di)v)[0];
}

        subl    $28, %esp
        vmovq   %xmm0, 8(%esp)
        movl    8(%esp), %eax
        movl    12(%esp), %edx
        addl    $28, %esp
        ret

MOVD / PEXTRD might be better, but gcc does handle it.  It's all using syntax
that's available in 32-bit mode, not a special built-in.

I don't think it's helpful to disable the 64-bit integer intrinsics for 32-bit
mode, even though they are no longer always single instructions.  I guess it
could be worse if someone used it without thinking, assuming it would be the
same cost as MOVD, and didn't really need the full 64 bits.  In that case, a
compile-time error would prompt them to port more optimally to 32-bit.  But
it's not usually gcc's job to refuse to compile code that might be sub-optimal!

Reply via email to