1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 11:33:24 +02:00

Add a testcase for checking the integer-promotion of many different vector

types (with power of two types such as 8,16,32 .. 512).

Fix a bug in the integer promotion of bitcast nodes. Enable integer expanding
only if the target of the conversion is an integer (when the type action is
scalarize).

Add handling to the legalization of vector load/store in cases where the saved
vector is integer-promoted.

llvm-svn: 132985
This commit is contained in:
Nadav Rotem 2011-06-14 08:11:52 +00:00
parent db789f2d76
commit 1b92c3d96c
3 changed files with 1638 additions and 2 deletions

View File

@ -1374,6 +1374,91 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Tmp2 = LegalizeOp(Load.getValue(1));
break;
}
// If this is a promoted vector load, and the vector element types are
// legal, then scalarize it.
if (ExtType == ISD::EXTLOAD && SrcVT.isVector() &&
isTypeLegal(Node->getValueType(0).getScalarType())) {
SmallVector<SDValue, 8> LoadVals;
SmallVector<SDValue, 8> LoadChains;
unsigned NumElem = SrcVT.getVectorNumElements();
unsigned Stride = SrcVT.getScalarType().getSizeInBits()/8;
for (unsigned Idx=0; Idx<NumElem; Idx++) {
Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
DAG.getIntPtrConstant(Stride));
SDValue ScalarLoad = DAG.getExtLoad(ISD::EXTLOAD, dl,
Node->getValueType(0).getScalarType(),
Tmp1, Tmp2, LD->getPointerInfo().getWithOffset(Idx * Stride),
SrcVT.getScalarType(),
LD->isVolatile(), LD->isNonTemporal(),
LD->getAlignment());
LoadVals.push_back(ScalarLoad.getValue(0));
LoadChains.push_back(ScalarLoad.getValue(1));
}
Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
&LoadChains[0], LoadChains.size());
SDValue ValRes = DAG.getNode(ISD::BUILD_VECTOR, dl,
Node->getValueType(0), &LoadVals[0], LoadVals.size());
Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes.
Tmp2 = LegalizeOp(Result.getValue(0)); // Relegalize new nodes.
break;
}
// If this is a promoted vector load, and the vector element types are
// illegal, create the promoted vector from bitcasted segments.
if (ExtType == ISD::EXTLOAD && SrcVT.isVector()) {
EVT MemElemTy = Node->getValueType(0).getScalarType();
EVT SrcSclrTy = SrcVT.getScalarType();
unsigned SizeRatio =
(MemElemTy.getSizeInBits() / SrcSclrTy.getSizeInBits());
SmallVector<SDValue, 8> LoadVals;
SmallVector<SDValue, 8> LoadChains;
unsigned NumElem = SrcVT.getVectorNumElements();
unsigned Stride = SrcVT.getScalarType().getSizeInBits()/8;
for (unsigned Idx=0; Idx<NumElem; Idx++) {
Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
DAG.getIntPtrConstant(Stride));
SDValue ScalarLoad = DAG.getExtLoad(ISD::EXTLOAD, dl,
SrcVT.getScalarType(),
Tmp1, Tmp2, LD->getPointerInfo().getWithOffset(Idx * Stride),
SrcVT.getScalarType(),
LD->isVolatile(), LD->isNonTemporal(),
LD->getAlignment());
if (TLI.isBigEndian()) {
// MSB (which is garbage, comes first)
LoadVals.push_back(ScalarLoad.getValue(0));
for (unsigned i = 0; i<SizeRatio-1; ++i)
LoadVals.push_back(DAG.getUNDEF(SrcVT.getScalarType()));
} else {
// LSB (which is data, comes first)
for (unsigned i = 0; i<SizeRatio-1; ++i)
LoadVals.push_back(DAG.getUNDEF(SrcVT.getScalarType()));
LoadVals.push_back(ScalarLoad.getValue(0));
}
LoadChains.push_back(ScalarLoad.getValue(1));
}
Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
&LoadChains[0], LoadChains.size());
EVT TempWideVector = EVT::getVectorVT(*DAG.getContext(),
SrcVT.getScalarType(), NumElem*SizeRatio);
SDValue ValRes = DAG.getNode(ISD::BUILD_VECTOR, dl,
TempWideVector, &LoadVals[0], LoadVals.size());
// Cast to the correct type
ValRes = DAG.getNode(ISD::BITCAST, dl, Node->getValueType(0), ValRes);
Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes.
Tmp2 = LegalizeOp(Result.getValue(0)); // Relegalize new nodes.
break;
}
// FIXME: This does not work for vectors on most targets. Sign- and
// zero-extend operations are currently folded into extending loads,
// whether they are legal or not, and then we end up here without any
@ -1549,6 +1634,88 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Result = TLI.LowerOperation(Result, DAG);
break;
case Expand:
EVT WideScalarVT = Tmp3.getValueType().getScalarType();
EVT NarrowScalarVT = StVT.getScalarType();
// The Store type is illegal, must scalarize the vector store.
SmallVector<SDValue, 8> Stores;
bool ScalarLegal = isTypeLegal(WideScalarVT);
if (!isTypeLegal(StVT) && StVT.isVector() && ScalarLegal) {
unsigned NumElem = StVT.getVectorNumElements();
unsigned ScalarSize = StVT.getScalarType().getSizeInBits();
// Round odd types to the next pow of two.
if (!isPowerOf2_32(ScalarSize))
ScalarSize = NextPowerOf2(ScalarSize);
// Types smaller than 8 bits are promoted to 8 bits.
ScalarSize = std::max<unsigned>(ScalarSize, 8);
// Store stride
unsigned Stride = ScalarSize/8;
assert(isPowerOf2_32(Stride) && "Stride must be a power of two");
for (unsigned Idx=0; Idx<NumElem; Idx++) {
SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
WideScalarVT, Tmp3, DAG.getIntPtrConstant(Idx));
EVT NVT = EVT::getIntegerVT(*DAG.getContext(), ScalarSize);
Ex = DAG.getNode(ISD::TRUNCATE, dl, NVT, Ex);
Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
DAG.getIntPtrConstant(Stride));
SDValue Store = DAG.getStore(Tmp1, dl, Ex, Tmp2,
ST->getPointerInfo().getWithOffset(Idx*Stride),
isVolatile, isNonTemporal, Alignment);
Stores.push_back(Store);
}
Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
&Stores[0], Stores.size());
break;
}
// The Store type is illegal, must scalarize the vector store.
// However, the scalar type is illegal. Must bitcast the result
// and store it in smaller parts.
if (!isTypeLegal(StVT) && StVT.isVector()) {
unsigned WideNumElem = StVT.getVectorNumElements();
unsigned Stride = NarrowScalarVT.getSizeInBits()/8;
unsigned SizeRatio =
(WideScalarVT.getSizeInBits() / NarrowScalarVT.getSizeInBits());
EVT CastValueVT = EVT::getVectorVT(*DAG.getContext(), NarrowScalarVT,
SizeRatio*WideNumElem);
// Cast the wide elem vector to wider vec with smaller elem type.
// Example <2 x i64> -> <4 x i32>
Tmp3 = DAG.getNode(ISD::BITCAST, dl, CastValueVT, Tmp3);
for (unsigned Idx=0; Idx<WideNumElem*SizeRatio; Idx++) {
// Extract elment i
SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
NarrowScalarVT, Tmp3, DAG.getIntPtrConstant(Idx));
// bump pointer.
Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
DAG.getIntPtrConstant(Stride));
// Store if, this element is:
// - First element on big endian, or
// - Last element on little endian
if (( TLI.isBigEndian() && (Idx%SizeRatio == 0)) ||
((!TLI.isBigEndian() && (Idx%SizeRatio == SizeRatio-1)))) {
SDValue Store = DAG.getStore(Tmp1, dl, Ex, Tmp2,
ST->getPointerInfo().getWithOffset(Idx*Stride),
isVolatile, isNonTemporal, Alignment);
Stores.push_back(Store);
}
}
Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
&Stores[0], Stores.size());
break;
}
// TRUNCSTORE:i16 i32 -> STORE i16
assert(isTypeLegal(StVT) && "Do not know how to expand this store!");
Tmp3 = DAG.getNode(ISD::TRUNCATE, dl, StVT, Tmp3);

View File

@ -204,8 +204,10 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BITCAST(SDNode *N) {
break;
case TargetLowering::TypeScalarizeVector:
// Convert the element to an integer and promote it by hand.
if (!NOutVT.isVector())
return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
BitConvertToInteger(GetScalarizedVector(InOp)));
break;
case TargetLowering::TypeSplitVector: {
// For example, i32 = BITCAST v2i16 on alpha. Convert the split
// pieces of the input into integers and reassemble in the final type.

File diff suppressed because it is too large Load Diff