<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">

<head>
<meta http-equiv=Content-Type content="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<style>
<!--
 /* Font Definitions */
 @font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page Section1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.Section1
        {page:Section1;}
-->
</style>
<!--[if gte mso 9]><xml>
 <o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
 <o:shapelayout v:ext="edit">
  <o:idmap v:ext="edit" data="1" />
 </o:shapelayout></xml><![endif]-->
</head>

<body lang=EN-US link=blue vlink=purple>

<div class=Section1>

<p class=MsoNormal>Hi all,<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>I believe I’ve found a bug in the encoding of the movd
instruction on x64. Here’s some IR code to reproduce it:<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>external global i8*, align 1        ;
<i8**>:0 [#uses=1]<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>external global i8*, align 16       ;
<i8**>:1 [#uses=1]<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'><o:p> </o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>declare void @abort()<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'><o:p> </o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>define internal void @2() {<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>      %1 = load i8** @0,
align 1          ; <i8*>
[#uses=1]<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>      %2 = load i8** @1,
align 16         ; <i8*>
[#uses=1]<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>      %3 = bitcast i8* %2
to <8 x i8>*          ;
<<8 x i8>*> [#uses=1]<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>      %4 = load <8 x
i8>* %3, align 1           ;
<<8 x i8>> [#uses=1]<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>      %5 = bitcast <8 x
i8> %4 to i64           ;
<i64> [#uses=1]<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>      %6 = trunc i64 %5 to
i32            ;
<i32> [#uses=1]<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>      %7 = bitcast i8* %1
to i32*         ; <i32*>
[#uses=1]<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>      store i32 %6, i32*
%7, align 1<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>      ret void<o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:10.0pt;
font-family:"Courier New"'>}<o:p></o:p></span></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>It generates the following code:<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>mov        
rax,1E417A8h <o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>mov        
rax,qword ptr [rax] <o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>mov        
rcx,1E417B0h <o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>mov        
rcx,qword ptr [rcx] <o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>movq       
mm0,mmword ptr [rcx] <o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>movq       
rax,mm1 <o:p></o:p></span></p>

<p class=MsoNormal style='text-autospace:none'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>mov        
dword ptr [rax],ecx <o:p></o:p></span></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>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 <span
style='font-size:10.0pt;font-family:"Courier New"'>MMX_MOVD64*</span> definitions
and patterns looks suspicious.<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>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.<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>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?<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>Thanks,<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>Nicolas<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

</div>

</body>

</html>