[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