forked from OSchip/llvm-project
Cleanup the trunc-store legalization code and add asserts.
llvm-svn: 141659
This commit is contained in:
parent
c8a78ded33
commit
b521b6037b
|
@ -1607,82 +1607,101 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
|
||||||
EVT WideScalarVT = Tmp3.getValueType().getScalarType();
|
EVT WideScalarVT = Tmp3.getValueType().getScalarType();
|
||||||
EVT NarrowScalarVT = StVT.getScalarType();
|
EVT NarrowScalarVT = StVT.getScalarType();
|
||||||
|
|
||||||
// The Store type is illegal, must scalarize the vector store.
|
if (StVT.isVector()) {
|
||||||
SmallVector<SDValue, 8> Stores;
|
|
||||||
bool ScalarLegal = TLI.isTypeLegal(WideScalarVT);
|
|
||||||
if (!TLI.isTypeLegal(StVT) && StVT.isVector() && ScalarLegal) {
|
|
||||||
unsigned NumElem = StVT.getVectorNumElements();
|
unsigned NumElem = StVT.getVectorNumElements();
|
||||||
|
// The type of the data we want to save
|
||||||
|
EVT RegVT = Tmp3.getValueType();
|
||||||
|
EVT RegSclVT = RegVT.getScalarType();
|
||||||
|
// The type of data as saved in memory.
|
||||||
|
EVT MemSclVT = StVT.getScalarType();
|
||||||
|
|
||||||
unsigned ScalarSize = StVT.getScalarType().getSizeInBits();
|
bool RegScalarLegal = TLI.isTypeLegal(RegSclVT);
|
||||||
EVT EltVT = EVT::getIntegerVT(*DAG.getContext(), ScalarSize);
|
bool MemScalarLegal = TLI.isTypeLegal(MemSclVT);
|
||||||
assert(TLI.isTypeLegal(EltVT) && "Scalar store type must be legal");
|
|
||||||
|
|
||||||
// Round odd types to the next pow of two.
|
// We need to expand this store. If both the reg-scalar and the
|
||||||
if (!isPowerOf2_32(ScalarSize))
|
// memory-scalar are of legal types, then scalarize the vector.
|
||||||
ScalarSize = NextPowerOf2(ScalarSize);
|
if (RegScalarLegal && MemScalarLegal) {
|
||||||
// Types smaller than 8 bits are promoted to 8 bits.
|
// Cast floats into integers
|
||||||
ScalarSize = std::max<unsigned>(ScalarSize, 8);
|
unsigned ScalarSize = MemSclVT.getSizeInBits();
|
||||||
// Store stride
|
EVT EltVT = EVT::getIntegerVT(*DAG.getContext(), ScalarSize);
|
||||||
unsigned Stride = ScalarSize/8;
|
assert(TLI.isTypeLegal(EltVT) && "Saved scalars must be legal");
|
||||||
assert(isPowerOf2_32(Stride) && "Stride must be a power of two");
|
|
||||||
|
|
||||||
for (unsigned Idx=0; Idx<NumElem; Idx++) {
|
// Round odd types to the next pow of two.
|
||||||
SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
|
if (!isPowerOf2_32(ScalarSize))
|
||||||
WideScalarVT, Tmp3, DAG.getIntPtrConstant(Idx));
|
ScalarSize = NextPowerOf2(ScalarSize);
|
||||||
|
|
||||||
Ex = DAG.getNode(ISD::TRUNCATE, dl, EltVT, Ex);
|
// Store Stride in bytes
|
||||||
Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
|
unsigned Stride = ScalarSize/8;
|
||||||
DAG.getIntPtrConstant(Stride));
|
// Extract each of the elements from the original vector
|
||||||
SDValue Store = DAG.getStore(Tmp1, dl, Ex, Tmp2,
|
// and save them into memory individually.
|
||||||
ST->getPointerInfo().getWithOffset(Idx*Stride),
|
SmallVector<SDValue, 8> Stores;
|
||||||
isVolatile, isNonTemporal, Alignment);
|
for (unsigned Idx = 0; Idx < NumElem; Idx++) {
|
||||||
Stores.push_back(Store);
|
SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
|
||||||
}
|
RegSclVT, Tmp3, DAG.getIntPtrConstant(Idx));
|
||||||
Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
|
|
||||||
&Stores[0], Stores.size());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Store type is illegal, must scalarize the vector store.
|
Ex = DAG.getNode(ISD::TRUNCATE, dl, EltVT, Ex);
|
||||||
// However, the scalar type is illegal. Must bitcast the result
|
Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
|
||||||
// and store it in smaller parts.
|
DAG.getIntPtrConstant(Stride));
|
||||||
if (!TLI.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,
|
SDValue Store = DAG.getStore(Tmp1, dl, Ex, Tmp2,
|
||||||
ST->getPointerInfo().getWithOffset(Idx*Stride),
|
ST->getPointerInfo().getWithOffset(Idx*Stride),
|
||||||
isVolatile, isNonTemporal, Alignment);
|
isVolatile, isNonTemporal, Alignment);
|
||||||
Stores.push_back(Store);
|
Stores.push_back(Store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
|
||||||
|
&Stores[0], Stores.size());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
|
|
||||||
&Stores[0], Stores.size());
|
|
||||||
break;
|
// The scalar register type is illegal.
|
||||||
}
|
// For example saving <2 x i64> -> <2 x i32> on a x86.
|
||||||
|
// In here we bitcast the value into a vector of smaller parts and
|
||||||
|
// save it using smaller scalars.
|
||||||
|
if (!RegScalarLegal && MemScalarLegal) {
|
||||||
|
// Store Stride in bytes
|
||||||
|
unsigned Stride = MemSclVT.getSizeInBits()/8;
|
||||||
|
|
||||||
|
unsigned SizeRatio =
|
||||||
|
(RegSclVT.getSizeInBits() / MemSclVT.getSizeInBits());
|
||||||
|
|
||||||
|
EVT CastValueVT = EVT::getVectorVT(*DAG.getContext(),
|
||||||
|
MemSclVT,
|
||||||
|
SizeRatio * NumElem);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
SmallVector<SDValue, 8> Stores;
|
||||||
|
for (unsigned Idx=0; Idx < NumElem * SizeRatio; Idx++) {
|
||||||
|
// Extract the Ith element.
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
assert(false && "Unable to legalize the vector trunc store!");
|
||||||
|
}// is vector
|
||||||
|
|
||||||
|
|
||||||
// TRUNCSTORE:i16 i32 -> STORE i16
|
// TRUNCSTORE:i16 i32 -> STORE i16
|
||||||
|
|
Loading…
Reference in New Issue