Index: lib/Transforms/Utils/CloneFunction.cpp =================================================================== --- lib/Transforms/Utils/CloneFunction.cpp +++ lib/Transforms/Utils/CloneFunction.cpp @@ -475,11 +475,14 @@ // // Defer PHI resolution until rest of function is resolved. SmallVector PHIToResolve; + std::vector ReachableBBsInOldFunc; for (const BasicBlock &BI : *OldFunc) { Value *V = VMap.lookup(&BI); BasicBlock *NewBB = cast_or_null(V); if (!NewBB) continue; // Dead block. + // This was a reachable BB from the StartingBB. + ReachableBBsInOldFunc.push_back(&BI); // Add the new block to the new function. NewFunc->getBasicBlockList().push_back(NewBB); @@ -595,6 +598,18 @@ if (isa(VMap[PHIToResolve[Idx]])) Worklist.insert(PHIToResolve[Idx]); + // In this second pass, we also add all instructions reachable from + // StartingInst. This allows simplification of instructions that previously + // could not be simplified because they were not tied to any basic block. + for (auto &I: make_range(StartingInst->getIterator(), StartingBB->end())) + Worklist.insert(&I); + + for (auto *BB: ReachableBBsInOldFunc) { + if (BB == StartingBB) + continue; + for (auto &I: *BB) + Worklist.insert(&I); + } // Note that we must test the size on each iteration, the worklist can grow. for (unsigned Idx = 0; Idx != Worklist.size(); ++Idx) { const Value *OrigV = Worklist[Idx]; Index: test/Transforms/Inline/inline_inv_group.ll =================================================================== --- test/Transforms/Inline/inline_inv_group.ll +++ test/Transforms/Inline/inline_inv_group.ll @@ -4,14 +4,13 @@ target triple = "x86_64-unknown-linux-gnu" define i8* @callee() alwaysinline { -; CHECK-LABEL: define i8* @callee() %1 = call i8* @llvm.strip.invariant.group.p0i8(i8* null) ret i8* %1 } define i8* @caller() { ; CHECK-LABEL: define i8* @caller() -; CHECK-NEXT: call i8* @llvm.strip.invariant.group.p0i8(i8* null) +; CHECK-NEXT: ret i8* null %1 = call i8* @callee() ret i8* %1 }