1) Improve comments.
authorChris Lattner <sabre@nondot.org>
Sat, 8 Mar 2008 22:59:52 +0000 (22:59 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 8 Mar 2008 22:59:52 +0000 (22:59 +0000)
2) Don't try to insert an i64 value into the low part of a
   vector with movq on an x86-32 target.  This allows us to
   compile:

__m128i doload64(short x) {return _mm_set_epi16(0,0,0,0,0,0,0,1);}

into:

_doload64:
movaps LCPI1_0, %xmm0
ret

instead of:

_doload64:
subl $28, %esp
movl $0, 4(%esp)
movl $1, (%esp)
movq (%esp), %xmm0
addl $28, %esp
ret

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48057 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp

index 6219f929210e016ab23f1752018cf6d03be230e9..71e0d68c00fc060d3f07d6847affd567221c9ce6 100644 (file)
@@ -3055,7 +3055,15 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
   if (NumNonZero == 1 && NumElems <= 4) {
     unsigned Idx = CountTrailingZeros_32(NonZeros);
     SDOperand Item = Op.getOperand(Idx);
-    if (Idx == 0) {
+    
+    // If we have a constant or non-constant insertion into the low element of
+    // a vector, we can do this with SCALAR_TO_VECTOR + shuffle of zero into
+    // the rest of the elements.  This will be matched as movd/movq/movss/movsd
+    // depending on what the source datatype is.  Because we can only get here
+    // when NumElems <= 4, this only needs to handle i32/f32/i64/f64.
+    if (Idx == 0 &&
+        // Don't do this for i64 values on x86-32.
+        (EVT != MVT::i64 || Subtarget->is64Bit())) {
       Item = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Item);
       // Turn it into a MOVL (i.e. movss, movsd, or movd) to a zero vector.
       return getShuffleVectorZeroOrUndef(Item, VT, NumElems, Idx,
@@ -3065,6 +3073,11 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
     if (IsAllConstants) // Otherwise, it's better to do a constpool load.
       return SDOperand();
 
+    // Otherwise, if this is a vector with i32 or f32 elements, and the element
+    // is a non-constant being inserted into an element other than the low one,
+    // we can't use a constant pool load.  Instead, use SCALAR_TO_VECTOR (aka
+    // movd/movss) to move this into the low element, then shuffle it into
+    // place.
     if (EVTBits == 32) {
       Item = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Item);