[llvm-commits] [llvm] r47670 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.h LegalizeTypesSplit.cpp

Duncan Sands baldrick at free.fr
Wed Feb 27 05:03:46 PST 2008


Author: baldrick
Date: Wed Feb 27 07:03:44 2008
New Revision: 47670

URL: http://llvm.org/viewvc/llvm-project?rev=47670&view=rev
Log:
LegalizeTypes support for legalizing the mask
operand of a VECTOR_SHUFFLE.  The mask is a
vector of constant integers.  The code in
LegalizeDAG doesn't bother to legalize the
mask, since it's basically just storage for
a bunch of constants, however LegalizeTypes
is more picky.  The problem is that there may
not exist any legal vector-of-integers type
with a legal element type, so it is impossible
to create a legal mask!  Unless of course you
cheat by creating a BUILD_VECTOR where the
operands have a different type to the element
type of the vector being built...  This is
pretty ugly but works - all relevant tests in
the testsuite pass, and produce the same
assembler with and without LegalizeTypes.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=47670&r1=47669&r2=47670&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Wed Feb 27 07:03:44 2008
@@ -316,6 +316,7 @@
   SDOperand SplitOp_EXTRACT_SUBVECTOR(SDNode *N);
   SDOperand SplitOp_RET(SDNode *N, unsigned OpNo);
   SDOperand SplitOp_STORE(StoreSDNode *N, unsigned OpNo);
+  SDOperand SplitOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo);
 };
 
 } // end namespace llvm.

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp?rev=47670&r1=47669&r2=47670&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Wed Feb 27 07:03:44 2008
@@ -341,6 +341,7 @@
     case ISD::RET:   Res = SplitOp_RET(N, OpNo); break;
 
     case ISD::EXTRACT_SUBVECTOR: Res = SplitOp_EXTRACT_SUBVECTOR(N); break;
+    case ISD::VECTOR_SHUFFLE:    Res = SplitOp_VECTOR_SHUFFLE(N, OpNo); break;
     }
   }
   
@@ -421,3 +422,57 @@
                        DAG.getConstant(IdxVal - LoElts, Idx.getValueType()));
   }
 }
+
+SDOperand DAGTypeLegalizer::SplitOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) {
+  assert(OpNo == 2 && "Shuffle source type differs from result type?");
+  SDOperand Mask = N->getOperand(2);
+  unsigned MaskLength = MVT::getVectorNumElements(Mask.getValueType());
+  unsigned LargestMaskEntryPlusOne = 2 * MaskLength;
+  unsigned MinimumBitWidth = Log2_32_Ceil(LargestMaskEntryPlusOne);
+
+  // Look for a legal vector type to place the mask values in.
+  // Note that there may not be *any* legal vector-of-integer
+  // type for which the element type is legal!
+  for (MVT::SimpleValueType EltVT = MVT::FIRST_INTEGER_VALUETYPE;
+       EltVT <= MVT::LAST_INTEGER_VALUETYPE;
+       // Integer values types are consecutively numbered.  Exploit this.
+       EltVT = MVT::SimpleValueType(EltVT + 1)) {
+
+    // Is the element type big enough to hold the values?
+    if (MVT::getSizeInBits(EltVT) < MinimumBitWidth)
+      // Nope.
+      continue;
+
+    // Is the vector type legal?
+    MVT::ValueType VecVT = MVT::getVectorType(EltVT, MaskLength);
+    if (!isTypeLegal(VecVT))
+      // Nope.
+      continue;
+
+    // If the element type is not legal, find a larger legal type to use for
+    // the BUILD_VECTOR operands.  This is an ugly hack, but seems to work!
+    for (MVT::SimpleValueType OpVT = EltVT; OpVT <= MVT::LAST_INTEGER_VALUETYPE;
+         // Integer values types are consecutively numbered.  Exploit this.
+         OpVT = MVT::SimpleValueType(OpVT + 1)) {
+      if (!isTypeLegal(OpVT))
+        continue;
+
+      // Success!  Rebuild the vector using the legal types.
+      SmallVector<SDOperand, 16> Ops(MaskLength);
+      for (unsigned i = 0; i < MaskLength; ++i) {
+        uint64_t Idx =
+          cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
+        Ops[i] = DAG.getConstant(Idx, OpVT);
+      }
+      return DAG.UpdateNodeOperands(SDOperand(N,0),
+                                    N->getOperand(0), N->getOperand(1),
+                                    DAG.getNode(ISD::BUILD_VECTOR,
+                                                VecVT, &Ops[0], Ops.size()));
+    }
+
+    // Continuing is pointless - failure is certain.
+    break;
+  }
+  assert(false && "Failed to find an appropriate mask type!");
+  return SDOperand(N, 0);
+}





More information about the llvm-commits mailing list