diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index e48953b7f29..ebefdb31a44 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -96,6 +96,7 @@ namespace { virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); + AU.addPreservedID(LCSSAID); AU.setPreservesCFG(); } @@ -6251,56 +6252,59 @@ static bool DeadPHICycle(PHINode *PN, std::set &PotentiallyDeadPHIs) { // PHINode simplification // Instruction *InstCombiner::visitPHINode(PHINode &PN) { - if (Value *V = PN.hasConstantValue()) - return ReplaceInstUsesWith(PN, V); + // If LCSSA is around, don't nuke PHIs. + if (!mustPreserveAnalysisID(LCSSAID)) { + if (Value *V = PN.hasConstantValue()) + return ReplaceInstUsesWith(PN, V); - // If the only user of this instruction is a cast instruction, and all of the - // incoming values are constants, change this PHI to merge together the casted - // constants. - if (PN.hasOneUse()) - if (CastInst *CI = dyn_cast(PN.use_back())) - if (CI->getType() != PN.getType()) { // noop casts will be folded - bool AllConstant = true; - for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) - if (!isa(PN.getIncomingValue(i))) { - AllConstant = false; - break; - } - if (AllConstant) { - // Make a new PHI with all casted values. - PHINode *New = new PHINode(CI->getType(), PN.getName(), &PN); - for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { - Constant *OldArg = cast(PN.getIncomingValue(i)); - New->addIncoming(ConstantExpr::getCast(OldArg, New->getType()), - PN.getIncomingBlock(i)); - } + // If the only user of this instruction is a cast instruction, and all of + //the incoming values are constants, change this PHI to merge together the + // casted constants. + if (PN.hasOneUse()) + if (CastInst *CI = dyn_cast(PN.use_back())) + if (CI->getType() != PN.getType()) { // noop casts will be folded + bool AllConstant = true; + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) + if (!isa(PN.getIncomingValue(i))) { + AllConstant = false; + break; + } + if (AllConstant) { + // Make a new PHI with all casted values. + PHINode *New = new PHINode(CI->getType(), PN.getName(), &PN); + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { + Constant *OldArg = cast(PN.getIncomingValue(i)); + New->addIncoming(ConstantExpr::getCast(OldArg, New->getType()), + PN.getIncomingBlock(i)); + } - // Update the cast instruction. - CI->setOperand(0, New); - WorkList.push_back(CI); // revisit the cast instruction to fold. - WorkList.push_back(New); // Make sure to revisit the new Phi - return &PN; // PN is now dead! + // Update the cast instruction. + CI->setOperand(0, New); + WorkList.push_back(CI); // revisit the cast instruction to fold. + WorkList.push_back(New); // Make sure to revisit the new Phi + return &PN; // PN is now dead! + } } + + // If all PHI operands are the same operation, pull them through the PHI, + // reducing code size. + if (isa(PN.getIncomingValue(0)) && + PN.getIncomingValue(0)->hasOneUse()) + if (Instruction *Result = FoldPHIArgOpIntoPHI(PN)) + return Result; + + // If this is a trivial cycle in the PHI node graph, remove it. Basically, + // if this PHI only has a single use (a PHI), and if that PHI only has one + // use (a PHI)... break the cycle. + if (PN.hasOneUse()) + if (PHINode *PU = dyn_cast(PN.use_back())) { + std::set PotentiallyDeadPHIs; + PotentiallyDeadPHIs.insert(&PN); + if (DeadPHICycle(PU, PotentiallyDeadPHIs)) + return ReplaceInstUsesWith(PN, UndefValue::get(PN.getType())); } - - // If all PHI operands are the same operation, pull them through the PHI, - // reducing code size. - if (isa(PN.getIncomingValue(0)) && - PN.getIncomingValue(0)->hasOneUse()) - if (Instruction *Result = FoldPHIArgOpIntoPHI(PN)) - return Result; - - // If this is a trivial cycle in the PHI node graph, remove it. Basically, if - // this PHI only has a single use (a PHI), and if that PHI only has one use (a - // PHI)... break the cycle. - if (PN.hasOneUse()) - if (PHINode *PU = dyn_cast(PN.use_back())) { - std::set PotentiallyDeadPHIs; - PotentiallyDeadPHIs.insert(&PN); - if (DeadPHICycle(PU, PotentiallyDeadPHIs)) - return ReplaceInstUsesWith(PN, UndefValue::get(PN.getType())); - } - + } + return 0; }