From 56dc7fc6d3119375950db4275379326db03c060d Mon Sep 17 00:00:00 2001 From: clc5q <clc5q@git.zephyr-software.com> Date: Thu, 10 Aug 2017 19:21:15 +0000 Subject: [PATCH] Fix constant tracing for func ptrs and handle conditional move tracing. Former-commit-id: 8b168e63aac8ff541f7a3e3899be1800087469d4 --- src/base/SMPFunction.cpp | 49 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp index ba8d70e4..929b2b5e 100644 --- a/src/base/SMPFunction.cpp +++ b/src/base/SMPFunction.cpp @@ -13528,7 +13528,52 @@ bool SMPFunction::FindShadowingPoint2(const ShadowPoint CriticalOp, const bool T break; // cannot follow chain any higher, but previous chain info is still valid. } STARSOpndTypePtr NewUseOp = nullptr; - if (!CurrInst->IsSimpleCopy(NewUseOp)) { + // If we have a conditional move instruction, then there will be two USEs. One is the + // operand that will be copied to the DEF if the condition is true, and the other is + // the operand that represents the unchanged DEF if the copy does not happen, e.g. + // if (guard) RDX5 := RAX3; will have USEs RAX3 and RDX4, where RDX4 is the value + // that becomes RDX5 when the guard is not true. We need to treat this instruction as + // a Phi DEF with two Phi USEs and trace both USEs. + if (CurrInst->MDIsConditionalMoveInstr()) { + // For each USE other than the flags register, recurse. + ShadowSet TempShadowAddrSet; // only union these into ShadowAddrSet if all Phi USE recursions succeed. + for (STARSDefUseIter UseIter = CurrInst->GetFirstUse(); UseIter != CurrInst->GetLastUse(); ++UseIter) { + int UseSSANum = UseIter->GetSSANum(); + if (0 > UseSSANum) { + SMP_msg("ERROR: FindShadowingPoint2() cannot trace uninitialized CondMove USE at CurrShadowAddr %p in func at %p\n", + CurrShadowAddr, this->GetFirstFuncAddr()); + ValidShadowing = false; + break; + } + STARSOpndTypePtr CondMoveUseOp = UseIter->GetOp()->clone(); + bool FlagsReg = (CondMoveUseOp->IsRegOp() && (CondMoveUseOp->MatchesReg(MD_FLAGS_REG))); + if (!FlagsReg) { + this->TempShadowList.SetRef(CondMoveUseOp, UseIter->GetType(), UseSSANum); + ShadowPoint UsePoint(CurrShadowAddr, this->TempShadowList.GetSize() - 1); + ValidShadowing = this->FindShadowingPoint2(UsePoint, TracingMemWrite, TempShadowAddrSet, MemUnsafe, NewCriticalOps, NonConstSourceFound, ConstValues); + if (!ValidShadowing) { + break; // we must succeed on all conditional move USEs + } + } + } + if (ValidShadowing) { // All USEs succeeded + // Remove current CriticalOp from ShadowAddrSet (if present); let the UseOps logically take its place + ShadowSet::iterator OldIter = ShadowAddrSet.find(CriticalOp); + if (OldIter != ShadowAddrSet.end()) { // found it + OldIter = ShadowAddrSet.erase(OldIter); + } + // Insert the shadow points for all the USEs now that all USE recursions succeeded. +#if 0 + ShadowAddrSet.insert(TempShadowAddrSet.begin(), TempShadowAddrSet.end()); +#else + for (ShadowSet::const_iterator TempIter = TempShadowAddrSet.cbegin(); TempIter != TempShadowAddrSet.cend(); ++TempIter) { + pair<ShadowSet::iterator, bool> InsertResult = ShadowAddrSet.insert(*TempIter); + } +#endif + } + break; // success if ValidShadowing is true, failure otherwise + } + else if (!CurrInst->IsSimpleCopy(NewUseOp)) { NonConstSourceFound = true; // We could have something like [rsp+32] := [rsp+32] + 8. // The DEF is the DEF of our CriticalOp, and we cannot trace any farther for this shadowing index. @@ -13689,7 +13734,7 @@ bool SMPFunction::FindShadowingPoint2(const ShadowPoint CriticalOp, const bool T } else { // Save in the set of constant values we traced back to. - pair<set<STARS_uval_t>::iterator, bool> InsertResult = ConstValues.insert(ShadowCheckUseOp->GetImmedValue()); + pair<set<STARS_uval_t>::iterator, bool> InsertResult = ConstValues.insert(NewUseOp->GetImmedValue()); assert(InsertResult.first != ConstValues.end()); } break; -- GitLab