mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-03 00:47:07 +00:00
LegalizeDAG: Don't replace vector store with integer if not legal
For the same reason as the corresponding load change. Note that ExpandStore is completely broken for non-byte sized element vector stores, but preserve the current broken behavior which has tests for it. The behavior should be the same, but now introduces a new typed store that is incorrectly split later rather than doing it directly. llvm-svn: 264928
This commit is contained in:
parent
2731b782d7
commit
7d16d35792
@ -2857,6 +2857,11 @@ public:
|
||||
/// \returns MERGE_VALUEs of the scalar loads with their chains.
|
||||
SDValue scalarizeVectorLoad(LoadSDNode *LD, SelectionDAG &DAG) const;
|
||||
|
||||
// Turn a store of a vector type into stores of the individual elements.
|
||||
/// \param ST Store with a vector value type
|
||||
/// \returns MERGE_VALUs of the individual store chains.
|
||||
SDValue scalarizeVectorStore(StoreSDNode *ST, SelectionDAG &DAG) const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Instruction Emitting Hooks
|
||||
//
|
||||
|
@ -327,6 +327,12 @@ static void ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
|
||||
ST->getMemoryVT().isVector()) {
|
||||
EVT intVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());
|
||||
if (TLI.isTypeLegal(intVT)) {
|
||||
if (!TLI.isOperationLegalOrCustom(ISD::STORE, intVT)) {
|
||||
// Scalarize the store and let the individual components be handled.
|
||||
SDValue Result = TLI.scalarizeVectorStore(ST, DAG);
|
||||
DAGLegalize->ReplaceNode(SDValue(ST, 0), Result);
|
||||
return;
|
||||
}
|
||||
// Expand to a bitconvert of the value to the integer type of the
|
||||
// same size, then a (misaligned) int store.
|
||||
// FIXME: Does not handle truncating floating point stores!
|
||||
|
@ -636,54 +636,40 @@ SDValue VectorLegalizer::ExpandLoad(SDValue Op) {
|
||||
}
|
||||
|
||||
SDValue VectorLegalizer::ExpandStore(SDValue Op) {
|
||||
SDLoc dl(Op);
|
||||
StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
|
||||
SDValue Chain = ST->getChain();
|
||||
SDValue BasePTR = ST->getBasePtr();
|
||||
SDValue Value = ST->getValue();
|
||||
|
||||
EVT StVT = ST->getMemoryVT();
|
||||
|
||||
unsigned Alignment = ST->getAlignment();
|
||||
bool isVolatile = ST->isVolatile();
|
||||
bool isNonTemporal = ST->isNonTemporal();
|
||||
AAMDNodes AAInfo = ST->getAAInfo();
|
||||
|
||||
unsigned NumElem = StVT.getVectorNumElements();
|
||||
// The type of the data we want to save
|
||||
EVT RegVT = Value.getValueType();
|
||||
EVT RegSclVT = RegVT.getScalarType();
|
||||
// The type of data as saved in memory.
|
||||
EVT MemSclVT = StVT.getScalarType();
|
||||
|
||||
// Cast floats into integers
|
||||
unsigned ScalarSize = MemSclVT.getSizeInBits();
|
||||
|
||||
// Round odd types to the next pow of two.
|
||||
if (!isPowerOf2_32(ScalarSize))
|
||||
ScalarSize = NextPowerOf2(ScalarSize);
|
||||
if (!isPowerOf2_32(ScalarSize)) {
|
||||
// FIXME: This is completely broken and inconsistent with ExpandLoad
|
||||
// handling.
|
||||
|
||||
// Store Stride in bytes
|
||||
unsigned Stride = ScalarSize/8;
|
||||
// Extract each of the elements from the original vector
|
||||
// and save them into memory individually.
|
||||
SmallVector<SDValue, 8> Stores;
|
||||
for (unsigned Idx = 0; Idx < NumElem; Idx++) {
|
||||
SDValue Ex = DAG.getNode(
|
||||
ISD::EXTRACT_VECTOR_ELT, dl, RegSclVT, Value,
|
||||
DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
|
||||
// For sub-byte element sizes, this ends up with 0 stride between elements,
|
||||
// so the same element just gets re-written to the same location. There seem
|
||||
// to be tests explicitly testing for this broken behavior though. tests
|
||||
// for this broken behavior.
|
||||
|
||||
// This scalar TruncStore may be illegal, but we legalize it later.
|
||||
SDValue Store = DAG.getTruncStore(Chain, dl, Ex, BasePTR,
|
||||
ST->getPointerInfo().getWithOffset(Idx*Stride), MemSclVT,
|
||||
isVolatile, isNonTemporal, MinAlign(Alignment, Idx*Stride),
|
||||
AAInfo);
|
||||
LLVMContext &Ctx = *DAG.getContext();
|
||||
|
||||
BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR,
|
||||
DAG.getConstant(Stride, dl, BasePTR.getValueType()));
|
||||
EVT NewMemVT
|
||||
= EVT::getVectorVT(Ctx,
|
||||
MemSclVT.getIntegerVT(Ctx, NextPowerOf2(ScalarSize)),
|
||||
StVT.getVectorNumElements());
|
||||
|
||||
Stores.push_back(Store);
|
||||
SDValue NewVectorStore
|
||||
= DAG.getTruncStore(ST->getChain(), SDLoc(Op), ST->getValue(),
|
||||
ST->getBasePtr(),
|
||||
ST->getPointerInfo(), NewMemVT,
|
||||
ST->isVolatile(), ST->isNonTemporal(),
|
||||
ST->getAlignment(),
|
||||
ST->getAAInfo());
|
||||
ST = cast<StoreSDNode>(NewVectorStore.getNode());
|
||||
}
|
||||
SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Stores);
|
||||
|
||||
SDValue TF = TLI.scalarizeVectorStore(ST, DAG);
|
||||
AddLegalizedOperand(Op, TF);
|
||||
return TF;
|
||||
}
|
||||
|
@ -3150,6 +3150,60 @@ SDValue TargetLowering::scalarizeVectorLoad(LoadSDNode *LD,
|
||||
return DAG.getMergeValues({ Value, NewChain }, SL);
|
||||
}
|
||||
|
||||
// FIXME: This relies on each element having a byte size, otherwise the stride
|
||||
// is 0 and just overwrites the same location. ExpandStore currently expects
|
||||
// this broken behavior.
|
||||
SDValue TargetLowering::scalarizeVectorStore(StoreSDNode *ST,
|
||||
SelectionDAG &DAG) const {
|
||||
SDLoc SL(ST);
|
||||
|
||||
SDValue Chain = ST->getChain();
|
||||
SDValue BasePtr = ST->getBasePtr();
|
||||
SDValue Value = ST->getValue();
|
||||
EVT StVT = ST->getMemoryVT();
|
||||
|
||||
unsigned Alignment = ST->getAlignment();
|
||||
bool isVolatile = ST->isVolatile();
|
||||
bool isNonTemporal = ST->isNonTemporal();
|
||||
AAMDNodes AAInfo = ST->getAAInfo();
|
||||
|
||||
// The type of the data we want to save
|
||||
EVT RegVT = Value.getValueType();
|
||||
EVT RegSclVT = RegVT.getScalarType();
|
||||
|
||||
// The type of data as saved in memory.
|
||||
EVT MemSclVT = StVT.getScalarType();
|
||||
|
||||
EVT PtrVT = BasePtr.getValueType();
|
||||
|
||||
// Store Stride in bytes
|
||||
unsigned Stride = MemSclVT.getSizeInBits() / 8;
|
||||
EVT IdxVT = getVectorIdxTy(DAG.getDataLayout());
|
||||
unsigned NumElem = StVT.getVectorNumElements();
|
||||
|
||||
// Extract each of the elements from the original vector and save them into
|
||||
// memory individually.
|
||||
SmallVector<SDValue, 8> Stores;
|
||||
for (unsigned Idx = 0; Idx < NumElem; ++Idx) {
|
||||
SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, RegSclVT, Value,
|
||||
DAG.getConstant(Idx, SL, IdxVT));
|
||||
|
||||
SDValue Ptr = DAG.getNode(ISD::ADD, SL, PtrVT, BasePtr,
|
||||
DAG.getConstant(Idx * Stride, SL, PtrVT));
|
||||
|
||||
// This scalar TruncStore may be illegal, but we legalize it later.
|
||||
SDValue Store = DAG.getTruncStore(
|
||||
Chain, SL, Elt, Ptr,
|
||||
ST->getPointerInfo().getWithOffset(Idx * Stride), MemSclVT,
|
||||
isVolatile, isNonTemporal, MinAlign(Alignment, Idx * Stride),
|
||||
AAInfo);
|
||||
|
||||
Stores.push_back(Store);
|
||||
}
|
||||
|
||||
return DAG.getNode(ISD::TokenFactor, SL, MVT::Other, Stores);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Implementation of Emulated TLS Model
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user