Added missing support to widen an operand from a bit convert.
authorMon P Wang <wangmp@apple.com>
Thu, 15 Jan 2009 22:43:38 +0000 (22:43 +0000)
committerMon P Wang <wangmp@apple.com>
Thu, 15 Jan 2009 22:43:38 +0000 (22:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62285 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/LegalizeTypes.h
lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
test/CodeGen/X86/widen_cast-6.ll [new file with mode: 0644]

index c6fbf70a3420e0ecc09da2aa98554d86c2904092..949ee349ce2d51beb3609906390a713770110f35 100644 (file)
@@ -606,6 +606,7 @@ private:
 
   // Widen Vector Operand.
   bool WidenVectorOperand(SDNode *N, unsigned ResNo);
+  SDValue WidenVecOp_BIT_CONVERT(SDNode *N);
   SDValue WidenVecOp_CONCAT_VECTORS(SDNode *N);
   SDValue WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N);
   SDValue WidenVecOp_STORE(SDNode* N);
index 0c2639a467ed4a04851633d5b7487a20a5be426b..3823f65263a12f6473532aec008d3793bb997f70 100644 (file)
@@ -1735,6 +1735,7 @@ bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned ResNo) {
     assert(0 && "Do not know how to widen this operator's operand!");
     abort();
 
+  case ISD::BIT_CONVERT:        Res = WidenVecOp_BIT_CONVERT(N); break;
   case ISD::CONCAT_VECTORS:     Res = WidenVecOp_CONCAT_VECTORS(N); break;
   case ISD::EXTRACT_VECTOR_ELT: Res = WidenVecOp_EXTRACT_VECTOR_ELT(N); break;
   case ISD::STORE:              Res = WidenVecOp_STORE(N); break;
@@ -1786,6 +1787,36 @@ SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) {
   return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElts);
 }
 
+SDValue DAGTypeLegalizer::WidenVecOp_BIT_CONVERT(SDNode *N) {
+  MVT VT = N->getValueType(0);
+  SDValue InOp = GetWidenedVector(N->getOperand(0));
+  MVT InWidenVT = InOp.getValueType();
+
+  // Check if we can convert between two legal vector types and extract.
+  unsigned InWidenSize = InWidenVT.getSizeInBits();
+  unsigned Size = VT.getSizeInBits();
+  if (InWidenSize % Size == 0 && !VT.isVector()) {
+    unsigned NewNumElts = InWidenSize / Size;
+    MVT NewVT = MVT::getVectorVT(VT, NewNumElts);
+    if (TLI.isTypeLegal(NewVT)) {
+      SDValue BitOp = DAG.getNode(ISD::BIT_CONVERT, NewVT, InOp);
+      return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, VT, BitOp,
+                         DAG.getIntPtrConstant(0));
+    }
+  }
+
+  // Lower the bit-convert to a store/load from the stack. Create the stack
+  // frame object.  Make sure it is aligned for both the source and destination
+  // types.
+  SDValue FIPtr = DAG.CreateStackTemporary(InWidenVT, VT);
+
+  // Emit a store to the stack slot.
+  SDValue Store = DAG.getStore(DAG.getEntryNode(), InOp, FIPtr, NULL, 0);
+
+  // Result is a load from the stack slot.
+  return DAG.getLoad(VT, Store, FIPtr, NULL, 0);
+}
+
 SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) {
   // If the input vector is not legal, it is likely that we will not find a
   // legal vector of the same size. Replace the concatenate vector with a
diff --git a/test/CodeGen/X86/widen_cast-6.ll b/test/CodeGen/X86/widen_cast-6.ll
new file mode 100644 (file)
index 0000000..0fa1b7a
--- /dev/null
@@ -0,0 +1,10 @@
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse41 -disable-mmx -o %t -f
+; RUN: grep movd  %t | count 1
+
+; Test bit convert that requires widening in the operand.
+
+define i32 @return_v2hi() nounwind {
+entry:
+       %retval12 = bitcast <2 x i16> zeroinitializer to i32            ; <i32> [#uses=1]
+       ret i32 %retval12
+}