diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp | 1 |
2 files changed, 20 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 6d05466b9be..23e76ee499f 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -519,9 +519,17 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) { return 0; // We normally only transform phis with a single use, unless we're trying - // hard to make jump threading happen. - if (!PN->hasOneUse()) - return 0; + // hard to make jump threading happen. However, if a PHI has multiple uses + // and they are all the same operation, we can fold *all* of the uses into the + // PHI. + if (!PN->hasOneUse()) { + // Walk the use list for the instruction, comparing them to I. + for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end(); + UI != E; ++UI) + if (!I.isIdenticalTo(cast<Instruction>(*UI))) + return 0; + // Otherwise, we can replace *all* users with the new PHI we form. + } // Check to see if all of the operands of the PHI are simple constants // (constantint/constantfp/undef). If there is one non-constant value, @@ -628,6 +636,14 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) { NewPN->addIncoming(InV, PN->getIncomingBlock(i)); } } + + for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end(); + UI != E; ) { + Instruction *User = cast<Instruction>(*UI++); + if (User == &I) continue; + ReplaceInstUsesWith(*User, NewPN); + EraseInstFromFunction(*User); + } return ReplaceInstUsesWith(I, NewPN); } diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 13902552ebd..0375d826f6b 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -1279,6 +1279,7 @@ void SROA::RewriteForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset, // address operand will be updated, so nothing else needs to be done. } else if (LoadInst *LI = dyn_cast<LoadInst>(User)) { const Type *LIType = LI->getType(); + if (isCompatibleAggregate(LIType, AI->getAllocatedType())) { // Replace: // %res = load { i32, i32 }* %alloc |