Skip to content

Commit

Permalink
Fix handling of non-volatile unresolved symrefs on ppc32
Browse files Browse the repository at this point in the history
As it turns out, under certain corner cases we can generate unresolved
symrefs that are not marked as volatile. In the event that such a symref
is loaded as a long on ppc32, LoadStoreHandler would get confused and
fail to use its handling for unresolved on such symrefs. Instead, it
would generate two separate loads/stores, leaving an unused snippet that
will cause a crash later. This has been corrected and LoadStoreHandler
now checks for unresolved before checking volatility.

Signed-off-by: Ben Thomas <ben@benthomas.ca>
  • Loading branch information
aviansie-ben committed Feb 11, 2021
1 parent 5d25291 commit 6bfb49b
Showing 1 changed file with 57 additions and 57 deletions.
114 changes: 57 additions & 57 deletions compiler/p/codegen/OMRLoadStoreHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,38 +167,38 @@ void OMR::Power::LoadStoreHandlerImpl::generateLoadSequence(TR::CodeGenerator *c
void OMR::Power::LoadStoreHandlerImpl::generatePairedLoadSequence(TR::CodeGenerator *cg, TR::Register *trgReg, TR::Node *node, TR::MemoryReference *memRef)
{
#ifdef J9_PROJECT_SPECIFIC
if (node->getSymbolReference()->isUnresolved())
{
TR::SymbolReference *vrlSymRef = cg->comp()->getSymRefTab()->findOrCreateVolatileReadLongSymbolRef(cg->comp()->getMethodSymbol());

memRef->getUnresolvedSnippet()->setIs32BitLong();

TR::RegisterDependencyConditions *deps = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(4, 4, cg->trMemory());
TR::addDependency(deps, trgReg->getHighOrder(), TR::RealRegister::gr3, TR_GPR, cg);
TR::addDependency(deps, trgReg->getLowOrder(), TR::RealRegister::gr4, TR_GPR, cg);
TR::addDependency(deps, NULL, TR::RealRegister::gr11, TR_GPR, cg);

TR::addDependency(deps, memRef->getBaseRegister(), TR::RealRegister::NoReg, TR_GPR, cg);
deps->getPreConditions()->getRegisterDependency(3)->setExcludeGPR0();
deps->getPostConditions()->getRegisterDependency(3)->setExcludeGPR0();

generateTrg1MemInstruction(cg, TR::InstOpCode::addi2, node, trgReg->getHighOrder(), memRef);
generateDepImmSymInstruction(
cg,
TR::InstOpCode::bl,
node,
reinterpret_cast<uintptr_t>(vrlSymRef->getSymbol()->castToMethodSymbol()->getMethodAddress()),
deps,
vrlSymRef
);

cg->machine()->setLinkRegisterKilled(true);
}
// Since non-volatiles are implemented as two separate loads, we must use a special sequence to perform the load in
// a single instruction even when SMP is disabled.
if (node->getSymbol()->isSyncVolatile())
else if (node->getSymbol()->isSyncVolatile())
{
if (node->getSymbolReference()->isUnresolved())
{
TR::SymbolReference *vrlSymRef = cg->comp()->getSymRefTab()->findOrCreateVolatileReadLongSymbolRef(cg->comp()->getMethodSymbol());

memRef->getUnresolvedSnippet()->setIs32BitLong();

TR::RegisterDependencyConditions *deps = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(4, 4, cg->trMemory());
TR::addDependency(deps, trgReg->getHighOrder(), TR::RealRegister::gr3, TR_GPR, cg);
TR::addDependency(deps, trgReg->getLowOrder(), TR::RealRegister::gr4, TR_GPR, cg);
TR::addDependency(deps, NULL, TR::RealRegister::gr11, TR_GPR, cg);

TR::addDependency(deps, memRef->getBaseRegister(), TR::RealRegister::NoReg, TR_GPR, cg);
deps->getPreConditions()->getRegisterDependency(3)->setExcludeGPR0();
deps->getPostConditions()->getRegisterDependency(3)->setExcludeGPR0();

generateTrg1MemInstruction(cg, TR::InstOpCode::addi2, node, trgReg->getHighOrder(), memRef);
generateDepImmSymInstruction(
cg,
TR::InstOpCode::bl,
node,
reinterpret_cast<uintptr_t>(vrlSymRef->getSymbol()->castToMethodSymbol()->getMethodAddress()),
deps,
vrlSymRef
);

cg->machine()->setLinkRegisterKilled(true);
}
else if (cg->comp()->target().cpu.isAtLeast(OMR_PROCESSOR_PPC_P8) && cg->comp()->target().cpu.supportsFeature(OMR_FEATURE_PPC_HAS_VSX))
if (cg->comp()->target().cpu.isAtLeast(OMR_PROCESSOR_PPC_P8) && cg->comp()->target().cpu.supportsFeature(OMR_FEATURE_PPC_HAS_VSX))
{
TR::Register *tempHiReg = cg->allocateRegister(TR_FPR);
TR::Register *tempLoReg = cg->allocateRegister(TR_FPR);
Expand Down Expand Up @@ -309,35 +309,35 @@ void OMR::Power::LoadStoreHandlerImpl::generatePairedStoreSequence(TR::CodeGener
#ifdef J9_PROJECT_SPECIFIC
StoreSyncRequirements sync = getStoreSyncRequirements(cg, node);

if (sync != StoreSyncRequirements::None)
if (node->getSymbolReference()->isUnresolved())
{
if (node->getSymbolReference()->isUnresolved())
{
TR::Register *addrReg = cg->allocateRegister();
TR::SymbolReference *vwlSymRef = cg->comp()->getSymRefTab()->findOrCreateVolatileWriteLongSymbolRef(cg->comp()->getMethodSymbol());

memRef->getUnresolvedSnippet()->setIs32BitLong();

TR::RegisterDependencyConditions *deps = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(5, 5, cg->trMemory());
TR::addDependency(deps, addrReg, TR::RealRegister::gr3, TR_GPR, cg);
TR::addDependency(deps, srcReg->getHighOrder(), TR::RealRegister::gr4, TR_GPR, cg);
TR::addDependency(deps, srcReg->getLowOrder(), TR::RealRegister::gr5, TR_GPR, cg);
TR::addDependency(deps, NULL, TR::RealRegister::gr11, TR_GPR, cg);

generateTrg1MemInstruction(cg, TR::InstOpCode::addi2, node, addrReg, memRef);
generateDepImmSymInstruction(
cg,
TR::InstOpCode::bl,
node,
reinterpret_cast<uintptr_t>(vwlSymRef->getSymbol()->castToMethodSymbol()->getMethodAddress()),
deps,
vwlSymRef
);

cg->machine()->setLinkRegisterKilled(true);
cg->stopUsingRegister(addrReg);
}
else if (cg->comp()->target().cpu.isAtLeast(OMR_PROCESSOR_PPC_P8) && cg->comp()->target().cpu.supportsFeature(OMR_FEATURE_PPC_HAS_VSX))
TR::Register *addrReg = cg->allocateRegister();
TR::SymbolReference *vwlSymRef = cg->comp()->getSymRefTab()->findOrCreateVolatileWriteLongSymbolRef(cg->comp()->getMethodSymbol());

memRef->getUnresolvedSnippet()->setIs32BitLong();

TR::RegisterDependencyConditions *deps = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(5, 5, cg->trMemory());
TR::addDependency(deps, addrReg, TR::RealRegister::gr3, TR_GPR, cg);
TR::addDependency(deps, srcReg->getHighOrder(), TR::RealRegister::gr4, TR_GPR, cg);
TR::addDependency(deps, srcReg->getLowOrder(), TR::RealRegister::gr5, TR_GPR, cg);
TR::addDependency(deps, NULL, TR::RealRegister::gr11, TR_GPR, cg);

generateTrg1MemInstruction(cg, TR::InstOpCode::addi2, node, addrReg, memRef);
generateDepImmSymInstruction(
cg,
TR::InstOpCode::bl,
node,
reinterpret_cast<uintptr_t>(vwlSymRef->getSymbol()->castToMethodSymbol()->getMethodAddress()),
deps,
vwlSymRef
);

cg->machine()->setLinkRegisterKilled(true);
cg->stopUsingRegister(addrReg);
}
else if (sync != StoreSyncRequirements::None)
{
if (cg->comp()->target().cpu.isAtLeast(OMR_PROCESSOR_PPC_P8) && cg->comp()->target().cpu.supportsFeature(OMR_FEATURE_PPC_HAS_VSX))
{
TR::Register *tempHiReg = cg->allocateRegister(TR_FPR);
TR::Register *tempLoReg = cg->allocateRegister(TR_FPR);
Expand Down

0 comments on commit 6bfb49b

Please sign in to comment.