mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-06 20:32:19 +00: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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132985 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c7cb7ed013
commit
c2492c28ef
@ -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);
|
||||
|
@ -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.
|
||||
return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
|
||||
BitConvertToInteger(GetScalarizedVector(InOp)));
|
||||
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.
|
||||
|
1467
test/CodeGen/X86/mem-promote-integers.ll
Normal file
1467
test/CodeGen/X86/mem-promote-integers.ll
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user