diff --git a/llvm/lib/CodeGen/SelectOptimize.cpp b/llvm/lib/CodeGen/SelectOptimize.cpp --- a/llvm/lib/CodeGen/SelectOptimize.cpp +++ b/llvm/lib/CodeGen/SelectOptimize.cpp @@ -29,6 +29,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/ProfDataUtils.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" @@ -425,6 +426,21 @@ // Delete the unconditional branch that was just created by the split. StartBlock->getTerminator()->eraseFromParent(); + // Move any lifetime-end intrinsic calls found in the StartBlock to the + // newly-created end block to ensure sound lifetime info after sinking (in + // case any use is sinked). + SmallVector EndLifetimeCalls; + for (Instruction &I : *StartBlock) { + if (IntrinsicInst *II = dyn_cast(&I)) { + if (II->getIntrinsicID() == Intrinsic::lifetime_end) { + EndLifetimeCalls.push_back(&I); + } + } + } + for (auto *LC : EndLifetimeCalls) { + LC->moveBefore(&*EndBlock->getFirstInsertionPt()); + } + // Move any debug/pseudo instructions that were in-between the select // group to the newly-created end block. SmallVector DebugPseudoINS;