From: Devang Patel Date: Sat, 7 Nov 2009 01:32:59 +0000 (+0000) Subject: Revert following patches to fix llvmgcc bootstrap. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=12d53dba36905d20b02cf7c4cdae057ae4a5a5e1;p=oota-llvm.git Revert following patches to fix llvmgcc bootstrap. 86289, 86278, 86270, 86267, 86266 & 86264 Chris, please take a look. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86321 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index 7cd1602e92c..e623f917662 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/lib/Transforms/Scalar/JumpThreading.cpp @@ -75,19 +75,14 @@ namespace { bool ThreadEdge(BasicBlock *BB, BasicBlock *PredBB, BasicBlock *SuccBB); bool DuplicateCondBranchOnPHIIntoPred(BasicBlock *BB, BasicBlock *PredBB); - - typedef SmallVectorImpl > PredValueInfo; - - bool ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB, - PredValueInfo &Result); - bool ProcessThreadableEdges(Instruction *CondInst, BasicBlock *BB); - - + + BasicBlock *FactorCommonPHIPreds(PHINode *PN, Value *Val); bool ProcessBranchOnDuplicateCond(BasicBlock *PredBB, BasicBlock *DestBB); bool ProcessSwitchOnDuplicateCond(BasicBlock *PredBB, BasicBlock *DestBB); bool ProcessJumpOnPHI(PHINode *PN); + bool ProcessBranchOnLogical(Value *V, BasicBlock *BB, bool isAnd); + bool ProcessBranchOnCompare(CmpInst *Cmp, BasicBlock *BB); bool SimplifyPartiallyRedundantLoad(LoadInst *LI); }; @@ -203,133 +198,28 @@ void JumpThreading::FindLoopHeaders(Function &F) { LoopHeaders.insert(const_cast(Edges[i].second)); } -/// GetResultOfComparison - Given an icmp/fcmp predicate and the left and right -/// hand sides of the compare instruction, try to determine the result. If the -/// result can not be determined, a null pointer is returned. -static Constant *GetResultOfComparison(CmpInst::Predicate pred, - Value *LHS, Value *RHS) { - if (Constant *CLHS = dyn_cast(LHS)) - if (Constant *CRHS = dyn_cast(RHS)) - return ConstantExpr::getCompare(pred, CLHS, CRHS); - - if (LHS == RHS) - if (isa(LHS->getType()) || isa(LHS->getType())) { - if (ICmpInst::isTrueWhenEqual(pred)) - return ConstantInt::getTrue(LHS->getContext()); - else - return ConstantInt::getFalse(LHS->getContext()); - } - return 0; -} - - -/// ComputeValueKnownInPredecessors - Given a basic block BB and a value V, see -/// if we can infer that the value is a known ConstantInt in any of our -/// predecessors. If so, return the known the list of value and pred BB in the -/// result vector. If a value is known to be undef, it is returned as null. -/// -/// The BB basic block is known to start with a PHI node. -/// -/// This returns true if there were any known values. +/// FactorCommonPHIPreds - If there are multiple preds with the same incoming +/// value for the PHI, factor them together so we get one block to thread for +/// the whole group. +/// This is important for things like "phi i1 [true, true, false, true, x]" +/// where we only need to clone the block for the true blocks once. /// -/// -/// TODO: Per PR2563, we could infer value range information about a predecessor -/// based on its terminator. -bool JumpThreading:: -ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){ - PHINode *TheFirstPHI = cast(BB->begin()); - - // If V is a constantint, then it is known in all predecessors. - if (isa(V) || isa(V)) { - ConstantInt *CI = dyn_cast(V); - Result.resize(TheFirstPHI->getNumIncomingValues()); - for (unsigned i = 0, e = Result.size(); i != e; ++i) - Result[i] = std::make_pair(CI, TheFirstPHI->getIncomingBlock(i)); - return true; - } - - // If V is a non-instruction value, or an instruction in a different block, - // then it can't be derived from a PHI. - Instruction *I = dyn_cast(V); - if (I == 0 || I->getParent() != BB) - return false; - - /// If I is a PHI node, then we know the incoming values for any constants. - if (PHINode *PN = dyn_cast(I)) { - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { - Value *InVal = PN->getIncomingValue(i); - if (isa(InVal) || isa(InVal)) { - ConstantInt *CI = dyn_cast(InVal); - Result.push_back(std::make_pair(CI, PN->getIncomingBlock(i))); - } - } - return !Result.empty(); - } - - SmallVector, 8> LHSVals, RHSVals; - - // Handle some boolean conditions. - if (I->getType()->getPrimitiveSizeInBits() == 1) { - // X | true -> true - // X & false -> false - if (I->getOpcode() == Instruction::Or || - I->getOpcode() == Instruction::And) { - ComputeValueKnownInPredecessors(I->getOperand(0), BB, LHSVals); - ComputeValueKnownInPredecessors(I->getOperand(1), BB, RHSVals); - - if (LHSVals.empty() && RHSVals.empty()) - return false; - - ConstantInt *InterestingVal; - if (I->getOpcode() == Instruction::Or) - InterestingVal = ConstantInt::getTrue(I->getContext()); - else - InterestingVal = ConstantInt::getFalse(I->getContext()); - - // Scan for the sentinel. - for (unsigned i = 0, e = LHSVals.size(); i != e; ++i) - if (LHSVals[i].first == InterestingVal || LHSVals[i].first == 0) - Result.push_back(LHSVals[i]); - for (unsigned i = 0, e = RHSVals.size(); i != e; ++i) - if (RHSVals[i].first == InterestingVal || RHSVals[i].first == 0) - Result.push_back(RHSVals[i]); - return !Result.empty(); - } - - // TODO: Should handle the NOT form of XOR. +BasicBlock *JumpThreading::FactorCommonPHIPreds(PHINode *PN, Value *Val) { + SmallVector CommonPreds; + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + if (PN->getIncomingValue(i) == Val) + CommonPreds.push_back(PN->getIncomingBlock(i)); + + if (CommonPreds.size() == 1) + return CommonPreds[0]; - } - - // Handle compare with phi operand, where the PHI is defined in this block. - if (CmpInst *Cmp = dyn_cast(I)) { - PHINode *PN = dyn_cast(Cmp->getOperand(0)); - if (PN && PN->getParent() == BB) { - // We can do this simplification if any comparisons fold to true or false. - // See if any do. - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { - BasicBlock *PredBB = PN->getIncomingBlock(i); - Value *LHS = PN->getIncomingValue(i); - Value *RHS = Cmp->getOperand(1)->DoPHITranslation(BB, PredBB); - - Constant *Res = GetResultOfComparison(Cmp->getPredicate(), LHS, RHS); - if (Res == 0) continue; - - if (isa(Res)) - Result.push_back(std::make_pair((ConstantInt*)0, PredBB)); - else if (ConstantInt *CI = dyn_cast(Res)) - Result.push_back(std::make_pair(CI, PredBB)); - } - - return !Result.empty(); - } - - // TODO: We could also recurse to see if we can determine constants another - // way. - } - return false; + DEBUG(errs() << " Factoring out " << CommonPreds.size() + << " common predecessors.\n"); + return SplitBlockPredecessors(PN->getParent(), + &CommonPreds[0], CommonPreds.size(), + ".thr_comm", this); } - - + /// GetBestDestForBranchOnUndef - If we determine that the specified block ends /// in an undefined jump, decide which block is best to revector to. @@ -360,7 +250,7 @@ bool JumpThreading::ProcessBlock(BasicBlock *BB) { // successor, merge the blocks. This encourages recursive jump threading // because now the condition in this block can be threaded through // predecessors of our predecessor block. - if (BasicBlock *SinglePred = BB->getSinglePredecessor()) { + if (BasicBlock *SinglePred = BB->getSinglePredecessor()) if (SinglePred->getTerminator()->getNumSuccessors() == 1 && SinglePred != BB) { // If SinglePred was a loop header, BB becomes one. @@ -376,10 +266,10 @@ bool JumpThreading::ProcessBlock(BasicBlock *BB) { BB->moveBefore(&BB->getParent()->getEntryBlock()); return true; } - } - - // Look to see if the terminator is a branch of switch, if not we can't thread - // it. + + // See if this block ends with a branch or switch. If so, see if the + // condition is a phi node. If so, and if an entry of the phi node is a + // constant, we can thread the block. Value *Condition; if (BranchInst *BI = dyn_cast(BB->getTerminator())) { // Can't thread an unconditional jump. @@ -455,26 +345,44 @@ bool JumpThreading::ProcessBlock(BasicBlock *BB) { if (PN->getParent() == BB) return ProcessJumpOnPHI(PN); + // If this is a conditional branch whose condition is and/or of a phi, try to + // simplify it. + if ((CondInst->getOpcode() == Instruction::And || + CondInst->getOpcode() == Instruction::Or) && + isa(BB->getTerminator()) && + ProcessBranchOnLogical(CondInst, BB, + CondInst->getOpcode() == Instruction::And)) + return true; + if (CmpInst *CondCmp = dyn_cast(CondInst)) { - if (!isa(CondCmp->getOperand(0)) || - cast(CondCmp->getOperand(0))->getParent() != BB) { - // If we have a comparison, loop over the predecessors to see if there is - // a condition with a lexically identical value. - pred_iterator PI = pred_begin(BB), E = pred_end(BB); - for (; PI != E; ++PI) - if (BranchInst *PBI = dyn_cast((*PI)->getTerminator())) - if (PBI->isConditional() && *PI != BB) { - if (CmpInst *CI = dyn_cast(PBI->getCondition())) { - if (CI->getOperand(0) == CondCmp->getOperand(0) && - CI->getOperand(1) == CondCmp->getOperand(1) && - CI->getPredicate() == CondCmp->getPredicate()) { - // TODO: Could handle things like (x != 4) --> (x == 17) - if (ProcessBranchOnDuplicateCond(*PI, BB)) - return true; - } + if (isa(CondCmp->getOperand(0))) { + // If we have "br (phi != 42)" and the phi node has any constant values + // as operands, we can thread through this block. + // + // If we have "br (cmp phi, x)" and the phi node contains x such that the + // comparison uniquely identifies the branch target, we can thread + // through this block. + + if (ProcessBranchOnCompare(CondCmp, BB)) + return true; + } + + // If we have a comparison, loop over the predecessors to see if there is + // a condition with the same value. + pred_iterator PI = pred_begin(BB), E = pred_end(BB); + for (; PI != E; ++PI) + if (BranchInst *PBI = dyn_cast((*PI)->getTerminator())) + if (PBI->isConditional() && *PI != BB) { + if (CmpInst *CI = dyn_cast(PBI->getCondition())) { + if (CI->getOperand(0) == CondCmp->getOperand(0) && + CI->getOperand(1) == CondCmp->getOperand(1) && + CI->getPredicate() == CondCmp->getPredicate()) { + // TODO: Could handle things like (x != 4) --> (x == 17) + if (ProcessBranchOnDuplicateCond(*PI, BB)) + return true; } } - } + } } // Check for some cases that are worth simplifying. Right now we want to look @@ -493,19 +401,6 @@ bool JumpThreading::ProcessBlock(BasicBlock *BB) { if (SimplifyPartiallyRedundantLoad(LI)) return true; - - // Handle a variety of cases where we are branching on something derived from - // a PHI node in the current block. If we can prove that any predecessors - // compute a predictable value based on a PHI node, thread those predecessors. - // - // We only bother doing this if the current block has a PHI node and if the - // conditional instruction lives in the current block. If either condition - // fail, this won't be a computable value anyway. - if (CondInst->getParent() == BB && isa(BB->front())) - if (ProcessThreadableEdges(CondInst, BB)) - return true; - - // TODO: If we have: "br (X > 0)" and we have a predecessor where we know // "(X == 4)" thread through this block. @@ -794,197 +689,55 @@ bool JumpThreading::SimplifyPartiallyRedundantLoad(LoadInst *LI) { return true; } -/// FindMostPopularDest - The specified list contains multiple possible -/// threadable destinations. Pick the one that occurs the most frequently in -/// the list. -static BasicBlock * -FindMostPopularDest(BasicBlock *BB, - const SmallVectorImpl > &PredToDestList) { - assert(!PredToDestList.empty()); - - // Determine popularity. If there are multiple possible destinations, we - // explicitly choose to ignore 'undef' destinations. We prefer to thread - // blocks with known and real destinations to threading undef. We'll handle - // them later if interesting. - DenseMap DestPopularity; - for (unsigned i = 0, e = PredToDestList.size(); i != e; ++i) - if (PredToDestList[i].second) - DestPopularity[PredToDestList[i].second]++; - - // Find the most popular dest. - DenseMap::iterator DPI = DestPopularity.begin(); - BasicBlock *MostPopularDest = DPI->first; - unsigned Popularity = DPI->second; - SmallVector SamePopularity; - - for (++DPI; DPI != DestPopularity.end(); ++DPI) { - // If the popularity of this entry isn't higher than the popularity we've - // seen so far, ignore it. - if (DPI->second < Popularity) - ; // ignore. - else if (DPI->second == Popularity) { - // If it is the same as what we've seen so far, keep track of it. - SamePopularity.push_back(DPI->first); - } else { - // If it is more popular, remember it. - SamePopularity.clear(); - MostPopularDest = DPI->first; - Popularity = DPI->second; - } - } - - // Okay, now we know the most popular destination. If there is more than - // destination, we need to determine one. This is arbitrary, but we need - // to make a deterministic decision. Pick the first one that appears in the - // successor list. - if (!SamePopularity.empty()) { - SamePopularity.push_back(MostPopularDest); - TerminatorInst *TI = BB->getTerminator(); - for (unsigned i = 0; ; ++i) { - assert(i != TI->getNumSuccessors() && "Didn't find any successor!"); - - if (std::find(SamePopularity.begin(), SamePopularity.end(), - TI->getSuccessor(i)) == SamePopularity.end()) - continue; - - MostPopularDest = TI->getSuccessor(i); - break; - } - } - - // Okay, we have finally picked the most popular destination. - return MostPopularDest; -} -bool JumpThreading::ProcessThreadableEdges(Instruction *CondInst, - BasicBlock *BB) { - // If threading this would thread across a loop header, don't even try to - // thread the edge. - if (LoopHeaders.count(BB)) - return false; - - +/// ProcessJumpOnPHI - We have a conditional branch or switch on a PHI node in +/// the current block. See if there are any simplifications we can do based on +/// inputs to the phi node. +/// +bool JumpThreading::ProcessJumpOnPHI(PHINode *PN) { + BasicBlock *BB = PN->getParent(); - SmallVector, 8> PredValues; - if (!ComputeValueKnownInPredecessors(CondInst, BB, PredValues)) - return false; - assert(!PredValues.empty() && - "ComputeValueKnownInPredecessors returned true with no values"); - - DEBUG(errs() << "IN BB: " << *BB; - for (unsigned i = 0, e = PredValues.size(); i != e; ++i) { - errs() << " BB '" << BB->getName() << "': FOUND condition = "; - if (PredValues[i].first) - errs() << *PredValues[i].first; - else - errs() << "UNDEF"; - errs() << " for pred '" << PredValues[i].second->getName() - << "'.\n"; - }); - - // Decide what we want to thread through. Convert our list of known values to - // a list of known destinations for each pred. This also discards duplicate - // predecessors and keeps track of the undefined inputs (which are represented - // as a null dest in the PredToDestList. - SmallPtrSet SeenPreds; - SmallVector, 16> PredToDestList; - - BasicBlock *OnlyDest = 0; - BasicBlock *MultipleDestSentinel = (BasicBlock*)(intptr_t)~0ULL; - - for (unsigned i = 0, e = PredValues.size(); i != e; ++i) { - BasicBlock *Pred = PredValues[i].second; - if (!SeenPreds.insert(Pred)) - continue; // Duplicate predecessor entry. - - // If the predecessor ends with an indirect goto, we can't change its - // destination. - if (isa(Pred->getTerminator())) - continue; - - ConstantInt *Val = PredValues[i].first; + // See if the phi node has any constant integer or undef values. If so, we + // can determine where the corresponding predecessor will branch. + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + Value *PredVal = PN->getIncomingValue(i); - BasicBlock *DestBB; - if (Val == 0) // Undef. - DestBB = 0; - else if (BranchInst *BI = dyn_cast(BB->getTerminator())) - DestBB = BI->getSuccessor(Val->isZero()); - else { - SwitchInst *SI = cast(BB->getTerminator()); - DestBB = SI->getSuccessor(SI->findCaseValue(Val)); + // Check to see if this input is a constant integer. If so, the direction + // of the branch is predictable. + if (ConstantInt *CI = dyn_cast(PredVal)) { + // Merge any common predecessors that will act the same. + BasicBlock *PredBB = FactorCommonPHIPreds(PN, CI); + + BasicBlock *SuccBB; + if (BranchInst *BI = dyn_cast(BB->getTerminator())) + SuccBB = BI->getSuccessor(CI->isZero()); + else { + SwitchInst *SI = cast(BB->getTerminator()); + SuccBB = SI->getSuccessor(SI->findCaseValue(CI)); + } + + // Ok, try to thread it! + return ThreadEdge(BB, PredBB, SuccBB); } - - // If we have exactly one destination, remember it for efficiency below. - if (i == 0) - OnlyDest = DestBB; - else if (OnlyDest != DestBB) - OnlyDest = MultipleDestSentinel; - PredToDestList.push_back(std::make_pair(Pred, DestBB)); - } - - // If all edges were unthreadable, we fail. - if (PredToDestList.empty()) - return false; - - // Determine which is the most common successor. If we have many inputs and - // this block is a switch, we want to start by threading the batch that goes - // to the most popular destination first. If we only know about one - // threadable destination (the common case) we can avoid this. - BasicBlock *MostPopularDest = OnlyDest; - - if (MostPopularDest == MultipleDestSentinel) - MostPopularDest = FindMostPopularDest(BB, PredToDestList); - - // Now that we know what the most popular destination is, factor all - // predecessors that will jump to it into a single predecessor. - SmallVector PredsToFactor; - for (unsigned i = 0, e = PredToDestList.size(); i != e; ++i) - if (PredToDestList[i].second == MostPopularDest) { - BasicBlock *Pred = PredToDestList[i].first; + // If the input is an undef, then it doesn't matter which way it will go. + // Pick an arbitrary dest and thread the edge. + if (UndefValue *UV = dyn_cast(PredVal)) { + // Merge any common predecessors that will act the same. + BasicBlock *PredBB = FactorCommonPHIPreds(PN, UV); + BasicBlock *SuccBB = + BB->getTerminator()->getSuccessor(GetBestDestForJumpOnUndef(BB)); - // This predecessor may be a switch or something else that has multiple - // edges to the block. Factor each of these edges by listing them - // according to # occurrences in PredsToFactor. - TerminatorInst *PredTI = Pred->getTerminator(); - for (unsigned i = 0, e = PredTI->getNumSuccessors(); i != e; ++i) - if (PredTI->getSuccessor(i) == BB) - PredsToFactor.push_back(Pred); + // Ok, try to thread it! + return ThreadEdge(BB, PredBB, SuccBB); } - - BasicBlock *PredToThread; - if (PredsToFactor.size() == 1) - PredToThread = PredsToFactor[0]; - else { - DEBUG(errs() << " Factoring out " << PredsToFactor.size() - << " common predecessors.\n"); - PredToThread = SplitBlockPredecessors(BB, &PredsToFactor[0], - PredsToFactor.size(), - ".thr_comm", this); } - // If the threadable edges are branching on an undefined value, we get to pick - // the destination that these predecessors should get to. - if (MostPopularDest == 0) - MostPopularDest = BB->getTerminator()-> - getSuccessor(GetBestDestForJumpOnUndef(BB)); - - // Ok, try to thread it! - return ThreadEdge(BB, PredToThread, MostPopularDest); -} - -/// ProcessJumpOnPHI - We have a conditional branch or switch on a PHI node in -/// the current block. See if there are any simplifications we can do based on -/// inputs to the phi node. -/// -bool JumpThreading::ProcessJumpOnPHI(PHINode *PN) { - BasicBlock *BB = PN->getParent(); - - // If any of the predecessor blocks end in an unconditional branch, we can - // *duplicate* the jump into that block in order to further encourage jump - // threading and to eliminate cases where we have branch on a phi of an icmp - // (branch on icmp is much better). + // If the incoming values are all variables, we don't know the destination of + // any predecessors. However, if any of the predecessor blocks end in an + // unconditional branch, we can *duplicate* the jump into that block in order + // to further encourage jump threading and to eliminate cases where we have + // branch on a phi of an icmp (branch on icmp is much better). // We don't want to do this tranformation for switches, because we don't // really want to duplicate a switch. @@ -1005,6 +758,137 @@ bool JumpThreading::ProcessJumpOnPHI(PHINode *PN) { } +/// ProcessJumpOnLogicalPHI - PN's basic block contains a conditional branch +/// whose condition is an AND/OR where one side is PN. If PN has constant +/// operands that permit us to evaluate the condition for some operand, thread +/// through the block. For example with: +/// br (and X, phi(Y, Z, false)) +/// the predecessor corresponding to the 'false' will always jump to the false +/// destination of the branch. +/// +bool JumpThreading::ProcessBranchOnLogical(Value *V, BasicBlock *BB, + bool isAnd) { + // If this is a binary operator tree of the same AND/OR opcode, check the + // LHS/RHS. + if (BinaryOperator *BO = dyn_cast(V)) + if ((isAnd && BO->getOpcode() == Instruction::And) || + (!isAnd && BO->getOpcode() == Instruction::Or)) { + if (ProcessBranchOnLogical(BO->getOperand(0), BB, isAnd)) + return true; + if (ProcessBranchOnLogical(BO->getOperand(1), BB, isAnd)) + return true; + } + + // If this isn't a PHI node, we can't handle it. + PHINode *PN = dyn_cast(V); + if (!PN || PN->getParent() != BB) return false; + + // We can only do the simplification for phi nodes of 'false' with AND or + // 'true' with OR. See if we have any entries in the phi for this. + unsigned PredNo = ~0U; + ConstantInt *PredCst = ConstantInt::get(Type::getInt1Ty(BB->getContext()), + !isAnd); + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + if (PN->getIncomingValue(i) == PredCst) { + PredNo = i; + break; + } + } + + // If no match, bail out. + if (PredNo == ~0U) + return false; + + // If so, we can actually do this threading. Merge any common predecessors + // that will act the same. + BasicBlock *PredBB = FactorCommonPHIPreds(PN, PredCst); + + // Next, figure out which successor we are threading to. If this was an AND, + // the constant must be FALSE, and we must be targeting the 'false' block. + // If this is an OR, the constant must be TRUE, and we must be targeting the + // 'true' block. + BasicBlock *SuccBB = BB->getTerminator()->getSuccessor(isAnd); + + // Ok, try to thread it! + return ThreadEdge(BB, PredBB, SuccBB); +} + +/// GetResultOfComparison - Given an icmp/fcmp predicate and the left and right +/// hand sides of the compare instruction, try to determine the result. If the +/// result can not be determined, a null pointer is returned. +static Constant *GetResultOfComparison(CmpInst::Predicate pred, + Value *LHS, Value *RHS, + LLVMContext &Context) { + if (Constant *CLHS = dyn_cast(LHS)) + if (Constant *CRHS = dyn_cast(RHS)) + return ConstantExpr::getCompare(pred, CLHS, CRHS); + + if (LHS == RHS) + if (isa(LHS->getType()) || isa(LHS->getType())) + return ICmpInst::isTrueWhenEqual(pred) ? + ConstantInt::getTrue(Context) : ConstantInt::getFalse(Context); + + return 0; +} + +/// ProcessBranchOnCompare - We found a branch on a comparison between a phi +/// node and a value. If we can identify when the comparison is true between +/// the phi inputs and the value, we can fold the compare for that edge and +/// thread through it. +bool JumpThreading::ProcessBranchOnCompare(CmpInst *Cmp, BasicBlock *BB) { + PHINode *PN = cast(Cmp->getOperand(0)); + Value *RHS = Cmp->getOperand(1); + + // If the phi isn't in the current block, an incoming edge to this block + // doesn't control the destination. + if (PN->getParent() != BB) + return false; + + // We can do this simplification if any comparisons fold to true or false. + // See if any do. + Value *PredVal = 0; + bool TrueDirection = false; + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + PredVal = PN->getIncomingValue(i); + + Constant *Res = GetResultOfComparison(Cmp->getPredicate(), PredVal, + RHS, Cmp->getContext()); + if (!Res) { + PredVal = 0; + continue; + } + + // If this folded to a constant expr, we can't do anything. + if (ConstantInt *ResC = dyn_cast(Res)) { + TrueDirection = ResC->getZExtValue(); + break; + } + // If this folded to undef, just go the false way. + if (isa(Res)) { + TrueDirection = false; + break; + } + + // Otherwise, we can't fold this input. + PredVal = 0; + } + + // If no match, bail out. + if (PredVal == 0) + return false; + + // If so, we can actually do this threading. Merge any common predecessors + // that will act the same. + BasicBlock *PredBB = FactorCommonPHIPreds(PN, PredVal); + + // Next, get our successor. + BasicBlock *SuccBB = BB->getTerminator()->getSuccessor(!TrueDirection); + + // Ok, try to thread it! + return ThreadEdge(BB, PredBB, SuccBB); +} + + /// AddPHINodeEntriesForMappedBlock - We're adding 'NewPred' as a new /// predecessor to the PHIBB block. If it has PHI nodes, add entries for /// NewPred using the entries from OldPred (suitably mapped). diff --git a/test/Transforms/JumpThreading/basic.ll b/test/Transforms/JumpThreading/basic.ll index 7b444ad0a91..3d936b8f30f 100644 --- a/test/Transforms/JumpThreading/basic.ll +++ b/test/Transforms/JumpThreading/basic.ll @@ -170,36 +170,5 @@ BB4: } -;; This tests that the branch in 'merge' can be cloned up into T1. -;; rdar://7367025 -define i32 @test7(i1 %cond, i1 %cond2) { -Entry: -; CHECK: @test7 - %v1 = call i32 @f1() - br i1 %cond, label %Merge, label %F1 - -F1: - %v2 = call i32 @f2() - br label %Merge - -Merge: - %B = phi i32 [%v1, %Entry], [%v2, %F1] - %M = icmp ne i32 %B, %v1 - %N = icmp eq i32 %B, 47 - %O = and i1 %M, %N - br i1 %O, label %T2, label %F2 -; CHECK: Merge: -; CHECK-NOT: phi -; CHECK-NEXT: %v2 = call i32 @f2() - -T2: - call void @f3() - ret i32 %B - -F2: - ret i32 %B -; CHECK: F2: -; CHECK-NEXT: phi i32 -} diff --git a/test/Transforms/JumpThreading/crash.ll b/test/Transforms/JumpThreading/crash.ll index 7e2a2a047d1..862b40378bc 100644 --- a/test/Transforms/JumpThreading/crash.ll +++ b/test/Transforms/JumpThreading/crash.ll @@ -170,25 +170,3 @@ bb32.i: ret i32 1 } - -define fastcc void @test5(i1 %tmp, i32 %tmp1) nounwind ssp { -entry: - br i1 %tmp, label %bb12, label %bb13 - - -bb12: - br label %bb13 - -bb13: - %.lcssa31 = phi i32 [ undef, %bb12 ], [ %tmp1, %entry ] - %A = and i1 undef, undef - br i1 %A, label %bb15, label %bb61 - -bb15: - ret void - - -bb61: - ret void -} -