Tweak the expansion code for BIT_CONVERT to generate better code
authorEli Friedman <eli.friedman@gmail.com>
Sun, 7 Jun 2009 09:41:57 +0000 (09:41 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Sun, 7 Jun 2009 09:41:57 +0000 (09:41 +0000)
converting from an MMX vector to an i64.

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

lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
test/CodeGen/X86/2009-06-07-ExpandMMXBitcast.ll [new file with mode: 0644]

index e8ff3fc9efb49e62051159187c5bf4b4dc8b3617..b7d7818d6e0262359516b6bd67de63136bf8c7f9 100644 (file)
@@ -92,6 +92,26 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
     }
   }
 
+  if (InVT.isVector() && OutVT.isInteger()) {
+    // Handle cases like i64 = BIT_CONVERT v1i64 on x86, where the operand
+    // is legal but the result is not.
+    MVT NVT = MVT::getVectorVT(TLI.getTypeToTransformTo(OutVT), 2);
+
+    if (isTypeLegal(NVT)) {
+      SDValue CastInOp = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, InOp);
+      MVT EltNVT = NVT.getVectorElementType();
+      Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltNVT, CastInOp,
+                       DAG.getIntPtrConstant(0));
+      Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltNVT, CastInOp,
+                       DAG.getIntPtrConstant(1));
+
+      if (TLI.isBigEndian())
+        std::swap(Lo, Hi);
+      
+      return;
+    }
+  }
+
   // Lower the bit-convert to a store/load from the stack.
   assert(NOutVT.isByteSized() && "Expanded type not byte sized!");
 
diff --git a/test/CodeGen/X86/2009-06-07-ExpandMMXBitcast.ll b/test/CodeGen/X86/2009-06-07-ExpandMMXBitcast.ll
new file mode 100644 (file)
index 0000000..56015c6
--- /dev/null
@@ -0,0 +1,10 @@
+; RUN: llvm-as < %s | llc | grep movl | count 2
+
+define i64 @a(i32 %a, i32 %b) nounwind readnone {
+entry:
+       %0 = insertelement <2 x i32> undef, i32 %a, i32 0               ; <<2 x i32>> [#uses=1]
+       %1 = insertelement <2 x i32> %0, i32 %b, i32 1          ; <<2 x i32>> [#uses=1]
+       %conv = bitcast <2 x i32> %1 to i64             ; <i64> [#uses=1]
+       ret i64 %conv
+}
+