Finish implementing a readme entry: when inserting an i64 variable
authorChris Lattner <sabre@nondot.org>
Sun, 9 Mar 2008 05:42:06 +0000 (05:42 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 9 Mar 2008 05:42:06 +0000 (05:42 +0000)
into a vector of zeros or undef, and when the top part is obviously
zero, we can just use movd + shuffle.  This allows us to compile
vec_set-B.ll into:

_test3:
movl $1234567, %eax
andl 4(%esp), %eax
movd %eax, %xmm0
ret

instead of:

_test3:
subl $28, %esp
movl $1234567, %eax
andl 32(%esp), %eax
movl %eax, (%esp)
movl $0, 4(%esp)
movq (%esp), %xmm0
addl $28, %esp
ret

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

lib/Target/X86/README-SSE.txt
lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/vec_set-B.ll [new file with mode: 0644]

index 7087c681737998785baa774763cbcaf0b3a20e57..4d7224514cb93456c4dd2cda277a0cf92545768a 100644 (file)
@@ -781,41 +781,3 @@ LLVM should be able to generate the same thing as gcc.  This looks like it is
 just a matter of matching (scalar_to_vector (load x)) to movd.
 
 //===---------------------------------------------------------------------===//
-
-These two functions should compile to identical code on x86-32:
-
-define <2 x i64> @test2(i64 %arg) {
-entry:
-       %A = and i64 %arg, 1234567
-       %B = insertelement <2 x i64> undef, i64 %A, i32 0
-       ret <2 x i64> %B
-}
-
-define <2 x i64> @test2(i64 %arg) {
-entry:
-        %A = and i64 %arg, 1234567
-        %B = insertelement <2 x i64> zeroinitializer, i64 %A, i32 0
-        ret <2 x i64> %B
-}
-
-The later compiles to:
-
-_test2:
-       movl    $1234567, %eax
-       andl    4(%esp), %eax
-       movd    %eax, %xmm0
-       ret
-
-the former compiles to:
-
-_test2:
-       subl    $28, %esp
-       movl    $1234567, %eax
-       andl    32(%esp), %eax
-       movl    %eax, (%esp)
-       movl    $0, 4(%esp)
-       movaps  (%esp), %xmm0
-       addl    $28, %esp
-       ret
-
-//===---------------------------------------------------------------------===//
index 133a2da1f6d820029bedb3a57e650cb655b435b5..be7f91c6ae6273bdfc043ebae6bc353ce069d55f 100644 (file)
@@ -3063,11 +3063,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
     return DAG.getNode(ISD::UNDEF, VT);
   }
 
-  // Splat is obviously ok. Let legalizer expand it to a shuffle.
-  if (Values.size() == 1)
-    return SDOperand();
-
-  // Special case for single non-zero element.
+  // Special case for single non-zero, non-undef, element.
   if (NumNonZero == 1 && NumElems <= 4) {
     unsigned Idx = CountTrailingZeros_32(NonZeros);
     SDOperand Item = Op.getOperand(Idx);
@@ -3141,6 +3137,10 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
     }
   }
 
+  // Splat is obviously ok. Let legalizer expand it to a shuffle.
+  if (Values.size() == 1)
+    return SDOperand();
+  
   // A vector full of immediates; various special cases are already
   // handled, so this is best done with a single constant-pool load.
   if (IsAllConstants)
diff --git a/test/CodeGen/X86/vec_set-B.ll b/test/CodeGen/X86/vec_set-B.ll
new file mode 100644 (file)
index 0000000..e4e5667
--- /dev/null
@@ -0,0 +1,24 @@
+; RUN: llvm-as < %s | llc -march=x86 | not grep movaps
+; RUN: llvm-as < %s | llc -march=x86 | grep esp | count 2
+
+; These should both generate something like this:
+;_test3:
+;      movl    $1234567, %eax
+;      andl    4(%esp), %eax
+;      movd    %eax, %xmm0
+;      ret
+
+define <2 x i64> @test3(i64 %arg) {
+entry:
+        %A = and i64 %arg, 1234567
+        %B = insertelement <2 x i64> zeroinitializer, i64 %A, i32 0
+        ret <2 x i64> %B
+}
+
+define <2 x i64> @test2(i64 %arg) {
+entry:
+       %A = and i64 %arg, 1234567
+       %B = insertelement <2 x i64> undef, i64 %A, i32 0
+       ret <2 x i64> %B
+}
+