<div dir="ltr">Hi Quentin,<div><br></div><div>Could you take a look at <a href="http://llvm.org/bugs/show_bug.cgi?id=20421">http://llvm.org/bugs/show_bug.cgi?id=20421</a>? I wonder if this revision could cause that.</div></div>
<div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jul 11, 2014 at 5:08 AM, Quentin Colombet <span dir="ltr"><<a href="mailto:qcolombet@apple.com" target="_blank">qcolombet@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: qcolombet<br>
Date: Fri Jul 11 07:08:23 2014<br>
New Revision: 212808<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=212808&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=212808&view=rev</a><br>
Log:<br>
[X86] Fix the inversion of low and high bits for the lowering of MUL_LOHI.<br>
Also add a few comments.<br>
<br>
<rdar://problem/17581756><br>
<br>
Modified:<br>
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
    llvm/trunk/test/CodeGen/X86/vector-idiv.ll<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=212808&r1=212807&r2=212808&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=212808&r1=212807&r2=212808&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Jul 11 07:08:23 2014<br>
@@ -15156,10 +15156,23 @@ static SDValue LowerMUL_LOHI(SDValue Op,<br>
   assert((VT == MVT::v4i32 && Subtarget->hasSSE2()) ||<br>
          (VT == MVT::v8i32 && Subtarget->hasInt256()));<br>
<br>
-  // Get the high parts.<br>
+  // PMULxD operations multiply each even value (starting at 0) of LHS with<br>
+  // the related value of RHS and produce a widen result.<br>
+  // E.g., PMULUDQ <4 x i32> <a|b|c|d>, <4 x i32> <e|f|g|h><br>
+  // => <2 x i64> <ae|cg><br>
+  //<br>
+  // In other word, to have all the results, we need to perform two PMULxD:<br>
+  // 1. one with the even values.<br>
+  // 2. one with the odd values.<br>
+  // To achieve #2, with need to place the odd values at an even position.<br>
+  //<br>
+  // Place the odd value at an even position (basically, shift all values 1<br>
+  // step to the left):<br>
   const int Mask[] = {1, -1, 3, -1, 5, -1, 7, -1};<br>
-  SDValue Hi0 = DAG.getVectorShuffle(VT, dl, Op0, Op0, Mask);<br>
-  SDValue Hi1 = DAG.getVectorShuffle(VT, dl, Op1, Op1, Mask);<br>
+  // <a|b|c|d> => <b|undef|d|undef><br>
+  SDValue Odd0 = DAG.getVectorShuffle(VT, dl, Op0, Op0, Mask);<br>
+  // <e|f|g|h> => <f|undef|h|undef><br>
+  SDValue Odd1 = DAG.getVectorShuffle(VT, dl, Op1, Op1, Mask);<br>
<br>
   // Emit two multiplies, one for the lower 2 ints and one for the higher 2<br>
   // ints.<br>
@@ -15167,22 +15180,39 @@ static SDValue LowerMUL_LOHI(SDValue Op,<br>
   bool IsSigned = Op->getOpcode() == ISD::SMUL_LOHI;<br>
   unsigned Opcode =<br>
       (!IsSigned || !Subtarget->hasSSE41()) ? X86ISD::PMULUDQ : X86ISD::PMULDQ;<br>
+  // PMULUDQ <4 x i32> <a|b|c|d>, <4 x i32> <e|f|g|h><br>
+  // => <2 x i64> <ae|cg><br>
   SDValue Mul1 = DAG.getNode(ISD::BITCAST, dl, VT,<br>
                              DAG.getNode(Opcode, dl, MulVT, Op0, Op1));<br>
+  // PMULUDQ <4 x i32> <b|undef|d|undef>, <4 x i32> <f|undef|h|undef><br>
+  // => <2 x i64> <bf|dh><br>
   SDValue Mul2 = DAG.getNode(ISD::BITCAST, dl, VT,<br>
-                             DAG.getNode(Opcode, dl, MulVT, Hi0, Hi1));<br>
+                             DAG.getNode(Opcode, dl, MulVT, Odd0, Odd1));<br>
<br>
   // Shuffle it back into the right order.<br>
+  // The internal representation is big endian.<br>
+  // In other words, a i64 bitcasted to 2 x i32 has its high part at index 0<br>
+  // and its low part at index 1.<br>
+  // Moreover, we have: Mul1 = <ae|cg> ; Mul2 = <bf|dh><br>
+  // Vector index                0 1   ;          2 3<br>
+  // We want      <ae|bf|cg|dh><br>
+  // Vector index   0  2  1  3<br>
+  // Since each element is seen as 2 x i32, we get:<br>
+  // high_mask[i] = 2 x vector_index[i]<br>
+  // low_mask[i] = 2 x vector_index[i] + 1<br>
+  // where vector_index = {0, Size/2, 1, Size/2 + 1, ...,<br>
+  //                       Size/2 - 1, Size/2 + Size/2 - 1}<br>
+  // where Size is the number of element of the final vector.<br>
   SDValue Highs, Lows;<br>
   if (VT == MVT::v8i32) {<br>
-    const int HighMask[] = {1, 9, 3, 11, 5, 13, 7, 15};<br>
+    const int HighMask[] = {0, 8, 2, 10, 4, 12, 6, 14};<br>
     Highs = DAG.getVectorShuffle(VT, dl, Mul1, Mul2, HighMask);<br>
-    const int LowMask[] = {0, 8, 2, 10, 4, 12, 6, 14};<br>
+    const int LowMask[] = {1, 9, 3, 11, 5, 13, 7, 15};<br>
     Lows = DAG.getVectorShuffle(VT, dl, Mul1, Mul2, LowMask);<br>
   } else {<br>
-    const int HighMask[] = {1, 5, 3, 7};<br>
+    const int HighMask[] = {0, 4, 2, 6};<br>
     Highs = DAG.getVectorShuffle(VT, dl, Mul1, Mul2, HighMask);<br>
-    const int LowMask[] = {0, 4, 2, 6};<br>
+    const int LowMask[] = {1, 5, 3, 7};<br>
     Lows = DAG.getVectorShuffle(VT, dl, Mul1, Mul2, LowMask);<br>
   }<br>
<br>
@@ -15200,7 +15230,9 @@ static SDValue LowerMUL_LOHI(SDValue Op,<br>
     Highs = DAG.getNode(ISD::SUB, dl, VT, Highs, Fixup);<br>
   }<br>
<br>
-  return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getValueType(), Highs, Lows);<br>
+  // The low part of a MUL_LOHI is supposed to be the first value and the<br>
+  // high part the second value.<br>
+  return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getValueType(), Lows, Highs);<br>
 }<br>
<br>
 static SDValue LowerScalarImmediateShift(SDValue Op, SelectionDAG &DAG,<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/vector-idiv.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vector-idiv.ll?rev=212808&r1=212807&r2=212808&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vector-idiv.ll?rev=212808&r1=212807&r2=212808&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/vector-idiv.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/vector-idiv.ll Fri Jul 11 07:08:23 2014<br>
@@ -132,9 +132,6 @@ define <4 x i32> @test8(<4 x i32> %a) {<br>
 ; SSE41: padd<br>
<br>
 ; SSE-LABEL: test8:<br>
-; SSE: psrad $31<br>
-; SSE: pand<br>
-; SSE: paddd<br>
 ; SSE: pmuludq<br>
 ; SSE: pshufd  $49<br>
 ; SSE-NOT: pshufd      $49<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div dir="ltr">Alexey Samsonov<br><a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a></div>
</div>