diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -196,6 +196,15 @@ ->getFirstInsertionPt().getNonConst(); } + /// Returns an iterator to the first instruction in this block that is + /// not a PHINode, a debug intrinsic, a static alloca or any pseudo operation. + const_iterator getFirstNonPHIOrDbgOrAlloca() const; + iterator getFirstNonPHIOrDbgOrAlloca() { + return static_cast(this) + ->getFirstNonPHIOrDbgOrAlloca() + .getNonConst(); + } + /// Return a const iterator range over the instructions in the block, skipping /// any debug instructions. Skip any pseudo operations as well if \c /// SkipPseudoOp is true. diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -199,6 +199,14 @@ SetCurrentDebugLocation(IP->getDebugLoc()); } + /// This specifies that created instructions should inserted at the beginning + /// end of the specified function, but after already existing static alloca + /// instructions that are at the start. + void SetInsertPointPastAllocas(Function *F) { + BB = &F->getEntryBlock(); + InsertPt = BB->getFirstNonPHIOrDbgOrAlloca(); + } + /// Set location information used by debugging information. void SetCurrentDebugLocation(DebugLoc L) { AddOrRemoveMetadataToCopy(LLVMContext::MD_dbg, L.getAsMDNode()); diff --git a/llvm/lib/CodeGen/ShadowStackGCLowering.cpp b/llvm/lib/CodeGen/ShadowStackGCLowering.cpp --- a/llvm/lib/CodeGen/ShadowStackGCLowering.cpp +++ b/llvm/lib/CodeGen/ShadowStackGCLowering.cpp @@ -320,9 +320,8 @@ Instruction *StackEntry = AtEntry.CreateAlloca(ConcreteStackEntryTy, nullptr, "gc_frame"); - while (isa(IP)) - ++IP; - AtEntry.SetInsertPoint(IP->getParent(), IP); + AtEntry.SetInsertPointPastAllocas(&F); + IP = AtEntry.GetInsertPoint(); // Initialize the map pointer and load the current head of the shadow stack. Instruction *CurrentHead = diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -253,6 +253,30 @@ return InsertPt; } +BasicBlock::const_iterator BasicBlock::getFirstNonPHIOrDbgOrAlloca() const { + const Instruction *FirstNonPHI = getFirstNonPHI(); + if (!FirstNonPHI) + return end(); + + const_iterator InsertPt = FirstNonPHI->getIterator(); + if (InsertPt->isEHPad()) + ++InsertPt; + + if (isEntryBlock()) { + const_iterator End = end(); + while (InsertPt != End && + (isa(*InsertPt) || isa(*InsertPt) || + isa(*InsertPt))) { + if (const AllocaInst *AI = dyn_cast(&*InsertPt)) { + if (!AI->isStaticAlloca()) + break; + } + ++InsertPt; + } + } + return InsertPt; +} + void BasicBlock::dropAllReferences() { for (Instruction &I : *this) I.dropAllReferences(); diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3937,9 +3937,8 @@ // replacement below is still necessary. Instruction *MoveBefore; if (isa(Op)) { - MoveBefore = &FI.getFunction()->getEntryBlock().front(); - while (isa(MoveBefore)) - MoveBefore = MoveBefore->getNextNode(); + MoveBefore = + &*FI.getFunction()->getEntryBlock().getFirstNonPHIOrDbgOrAlloca(); } else { MoveBefore = cast(Op)->getInsertionPointAfterDef(); if (!MoveBefore)