MOVQ xmm,xmm source incorrectly modeled as 128-bit

Given the following minimal example:

; __m128i __fastcall repro(__int64 dummy, double x);
repro:
    movq xmm0, xmm1 ; F3 0F 7E C1
    ret

Hex-Rays correctly determines:

__m128i __fastcall repro@<xmm0>(
    __int64@<rcx>,
    double@<xmm1>
)

However, at MMAT_GENERATED, it produces:

USE: xmm1.16
DEF: xmm0.16

mov call !_mm_move_epi64<fast:__m128i xmm1.16>
    => __m128i .16, xmm0.16
    ; u=xmm1.16    d=xmm0.16

At MMAT_LVARS, the 8 byte argument has effectively become a 16 byte intrinsic input:

mov call !_mm_move_epi64<fast:__m128i x.16>
    => __m128i .16{1}, result.16{1}
    ; u=xmm1.16    d=xmm0.16

Resulting in:

// local variable allocation has failed, the output may be wrong!
__m128i __fastcall repro(__int64 dummy, double x)
{
    return _mm_move_epi64(*(__m128i *)&x);
}

For MOVQ with XMM source and destination operands, only the low 64 bits of the source are read, the low 64 bits are copied to the destination and the upper 64 bits of the destination are cleared.

I would therefore expect the use list for this instruction to cover only the low 8 bytes of the source register, such that USE: xmm1_8.8

As far as I can tell this is specific to the XMM/XMM lift, XMM/r64 uses xmm0_8.8 and r64/XMM uses an 8 byte source with a wider zero extended destination.

The same issue appears with both XMM/XMM MOVQ encodings.

Thanks for the great product.

Thanks, we can confirm the issue! We should have a fix for this in 9.5.