Skip to content

Commit

Permalink
Merge pull request #44 from pnkfelix/use-edge-into-phi-as-context-for…
Browse files Browse the repository at this point in the history
…-issue-69841

Backport of part of D71181.
  • Loading branch information
nikic committed Mar 30, 2020
2 parents 992e608 + c3ffe91 commit 130721d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
10 changes: 8 additions & 2 deletions llvm/lib/Analysis/InstructionSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,10 +543,16 @@ static Value *ThreadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS,

// Evaluate the BinOp on the incoming phi values.
Value *CommonValue = nullptr;
for (Value *Incoming : PI->incoming_values()) {
for (unsigned u = 0, e = PI->getNumIncomingValues(); u < e; ++u) {
Value *Incoming = PI->getIncomingValue(u);
Instruction *InTI = PI->getIncomingBlock(u)->getTerminator();
// If the incoming value is the phi node itself, it can safely be skipped.
if (Incoming == PI) continue;
Value *V = SimplifyCmpInst(Pred, Incoming, RHS, Q, MaxRecurse);
// Change the context instruction to the "edge" that flows into the phi.
// This is important because that is where incoming is actually "evaluated"
// even though it is used later somewhere else.
Value *V = SimplifyCmpInst(Pred, Incoming, RHS, Q.getWithInstruction(InTI),
MaxRecurse);
// If the operation failed to simplify, or simplified to a different value
// to previously, then give up.
if (!V || (CommonValue && V != CommonValue))
Expand Down
27 changes: 23 additions & 4 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,8 @@ static void computeKnownBitsFromOperator(const Operator *I, KnownBits &Known,
for (unsigned i = 0; i != 2; ++i) {
Value *L = P->getIncomingValue(i);
Value *R = P->getIncomingValue(!i);
Instruction *RInst = P->getIncomingBlock(!i)->getTerminator();
Instruction *LInst = P->getIncomingBlock(i)->getTerminator();
Operator *LU = dyn_cast<Operator>(L);
if (!LU)
continue;
Expand All @@ -1367,13 +1369,22 @@ static void computeKnownBitsFromOperator(const Operator *I, KnownBits &Known,
L = LL;
else
break;

// Change the context instruction to the "edge" that flows into the
// phi. This is important because that is where the value is actually
// "evaluated" even though it is used later somewhere else. (see also
// D69571).
Query RecQ = Q;

// Ok, we have a PHI of the form L op= R. Check for low
// zero bits.
computeKnownBits(R, Known2, Depth + 1, Q);
RecQ.CxtI = RInst;
computeKnownBits(R, Known2, Depth + 1, RecQ);

// We need to take the minimum number of known bits
KnownBits Known3(Known);
computeKnownBits(L, Known3, Depth + 1, Q);
RecQ.CxtI = LInst;
computeKnownBits(L, Known3, Depth + 1, RecQ);

Known.Zero.setLowBits(std::min(Known2.countMinTrailingZeros(),
Known3.countMinTrailingZeros()));
Expand Down Expand Up @@ -1429,14 +1440,22 @@ static void computeKnownBitsFromOperator(const Operator *I, KnownBits &Known,

Known.Zero.setAllBits();
Known.One.setAllBits();
for (Value *IncValue : P->incoming_values()) {
for (unsigned u = 0, e = P->getNumIncomingValues(); u < e; ++u) {
Value *IncValue = P->getIncomingValue(u);
// Skip direct self references.
if (IncValue == P) continue;

// Change the context instruction to the "edge" that flows into the
// phi. This is important because that is where the value is actually
// "evaluated" even though it is used later somewhere else. (see also
// D69571).
Query RecQ = Q;
RecQ.CxtI = P->getIncomingBlock(u)->getTerminator();

Known2 = KnownBits(BitWidth);
// Recurse, but cap the recursion to one level, because we don't
// want to waste time spinning around in loops.
computeKnownBits(IncValue, Known2, MaxDepth - 1, Q);
computeKnownBits(IncValue, Known2, MaxDepth - 1, RecQ);
Known.Zero &= Known2.Zero;
Known.One &= Known2.One;
// If all bits have been ruled out, there's no need to check
Expand Down

0 comments on commit 130721d

Please sign in to comment.