[LLVMdev] Wrong encoding of movd on x64

Eli Friedman eli.friedman at gmail.com
Thu Jul 9 10:12:30 PDT 2009


On Thu, Jul 9, 2009 at 8:44 AM, Nicolas Capens<nicolas at capens.net> wrote:
> I believe I’ve found a bug in the encoding of the movd instruction on x64.
> Here’s some IR code to reproduce it:
[snip
> Note the last movq. What was probably intended to be generated was “movd
> ecx, mm0”. LLVM mistakenly sets the ‘wide’ bit of the REX prefix to 1,
> turning movd into movq. Also, reg and r/m encoding has been swapped. I have
> not found a fix for this yet, but the MMX_MOVD64* definitions and patterns
> looks suspicious.

Thanks for the testcase; fixed in r75142.

> Note that on x86-32 it produces correct code (though not optimal either; it
> doesn’t use movd). Also, notice that the last two instructions above should
> ideally just be a single movd to memory, instead of first writing to a GP
> register.

The suboptimal code on x86-32 is because there aren't patterns for i32
extract from <2 x i32> yet (so it gets expanded through memory).  The
suboptimal code on x86-64 is due to a missing dagcombine; it doesn't
know that extracting an i64 and truncating it to an i32 is equivalent
to extracting an i32.

> In the same breath, I believe the encoding of MMX_MOVDQ2Qrr is incorrect.
> I’ve been able to fix the first two definitions by using MRMSrcReg (and set
> hasNoSideEffects). I’m not sure about the third definition though, is this
> for 3DNow! And should it use MRMSrcReg as well?

Also fixed in r75142.  Note that MMX_MOVQ2FR64rr is actually exactly
the same instruction as MMX_MOVQ2DQrr; they're separated because it's
a bit more straightforward to write that way (FR64 and VR128 are both
XMM registers, but TableGen isn't aware of the precise relationship).

-Eli




More information about the llvm-dev mailing list