Commit f2f5e962 by Nicolas Capens Committed by Nicolas Capens

Don't eliminate wide store followed by a narrow one.

If the previous store operation is wider than the next one, we can't eliminate it because there could be a subsequent wide load reading its non-overwritten data. Bug swiftshader:48 Change-Id: Iccb9cabad8ab8503140061ec4ce711a2959de33d Reviewed-on: https://swiftshader-review.googlesource.com/10948Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 709f69b2
...@@ -45,6 +45,7 @@ namespace ...@@ -45,6 +45,7 @@ namespace
static Ice::Operand *storeAddress(const Ice::Inst *instruction); static Ice::Operand *storeAddress(const Ice::Inst *instruction);
static Ice::Operand *loadAddress(const Ice::Inst *instruction); static Ice::Operand *loadAddress(const Ice::Inst *instruction);
static Ice::Operand *storeData(const Ice::Inst *instruction); static Ice::Operand *storeData(const Ice::Inst *instruction);
static std::size_t storeSize(const Ice::Inst *instruction);
Ice::Cfg *function; Ice::Cfg *function;
Ice::GlobalContext *context; Ice::GlobalContext *context;
...@@ -312,10 +313,15 @@ namespace ...@@ -312,10 +313,15 @@ namespace
continue; continue;
} }
// New store found. If we had a previous one, eliminate it. // New store found. If we had a previous one, try to eliminate it.
if(store) if(store)
{ {
deleteInstruction(store); // If the previous store is wider than the new one, we can't eliminate it
// because there could be a wide load reading its non-overwritten data.
if(storeSize(&inst) >= storeSize(store))
{
deleteInstruction(store);
}
} }
store = &inst; store = &inst;
...@@ -563,6 +569,23 @@ namespace ...@@ -563,6 +569,23 @@ namespace
return nullptr; return nullptr;
} }
std::size_t Optimizer::storeSize(const Ice::Inst *store)
{
assert(isStore(*store));
if(auto *instStore = llvm::dyn_cast<Ice::InstStore>(store))
{
return Ice::typeWidthInBytes(instStore->getData()->getType());
}
if(auto *storeSubVector = asStoreSubVector(store))
{
return llvm::cast<Ice::ConstantInteger32>(storeSubVector->getSrc(3))->getValue();
}
return 0;
}
bool Optimizer::Uses::areOnlyLoadStore() const bool Optimizer::Uses::areOnlyLoadStore() const
{ {
return size() == (loads.size() + stores.size()); return size() == (loads.size() + stores.size());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment