Index: lib/CodeGen/StackProtector.cpp =================================================================== --- lib/CodeGen/StackProtector.cpp +++ lib/CodeGen/StackProtector.cpp @@ -71,15 +71,14 @@ void StackProtector::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); + AU.addRequired(); AU.addPreserved(); } bool StackProtector::runOnFunction(Function &Fn) { F = &Fn; M = F->getParent(); - DominatorTreeWrapperPass *DTWP = - getAnalysisIfAvailable(); - DT = DTWP ? &DTWP->getDomTree() : nullptr; + DT = &getAnalysis().getDomTree(); TM = &getAnalysis().getTM(); Trip = TM->getTargetTriple(); TLI = TM->getSubtargetImpl(Fn)->getTargetLowering(); @@ -158,6 +157,21 @@ bool StackProtector::HasAddressTaken(const Instruction *AI) { for (const User *U : AI->users()) { + // Don't bother examining the user if it's in a basic block that isn't + // reachable from the entry BB. That code will probably be removed later + // anyway, and it won't be executed so we don't need to care about it. + // + // The usual SSA rules don't apply for code that isn't reachable from the + // entry, so we might find a user like + // + // %user = select i1 %bool, i8* %ai, i8* %user + // + // which is using itself, and then when examining that we would make + // HasAddressTaken recurse until it blows the stack. + const Instruction *UI = cast(U); + if (!DT->isReachableFromEntry(UI->getParent())) + continue; + if (const StoreInst *SI = dyn_cast(U)) { if (AI == SI->getValueOperand()) return true; @@ -456,8 +470,8 @@ // Split the basic block before the return instruction. BasicBlock *NewBB = BB->splitBasicBlock(RI->getIterator(), "SP_return"); - // Update the dominator tree if we need to. - if (DT && DT->isReachableFromEntry(BB)) { + // Update the dominator tree. + if (DT->isReachableFromEntry(BB)) { DT->addNewBlock(NewBB, BB); DT->addNewBlock(FailBB, BB); } Index: test/CodeGen/AArch64/O0-pipeline.ll =================================================================== --- test/CodeGen/AArch64/O0-pipeline.ll +++ test/CodeGen/AArch64/O0-pipeline.ll @@ -30,6 +30,7 @@ ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Exception handling preparation ; CHECK-NEXT: Safe Stack instrumentation pass +; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Insert stack protectors ; CHECK-NEXT: Module Verifier ; CHECK-NEXT: Analysis containing CSE Info Index: test/CodeGen/AArch64/O3-pipeline.ll =================================================================== --- test/CodeGen/AArch64/O3-pipeline.ll +++ test/CodeGen/AArch64/O3-pipeline.ll @@ -66,9 +66,9 @@ ; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Merge internal globals ; CHECK-NEXT: Safe Stack instrumentation pass +; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Insert stack protectors ; CHECK-NEXT: Module Verifier -; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Basic Alias Analysis (stateless AA impl) ; CHECK-NEXT: Function Alias Analysis Results ; CHECK-NEXT: Natural Loop Information Index: test/CodeGen/X86/O0-pipeline.ll =================================================================== --- test/CodeGen/X86/O0-pipeline.ll +++ test/CodeGen/X86/O0-pipeline.ll @@ -34,6 +34,7 @@ ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Exception handling preparation ; CHECK-NEXT: Safe Stack instrumentation pass +; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Insert stack protectors ; CHECK-NEXT: Module Verifier ; CHECK-NEXT: X86 DAG->DAG Instruction Selection Index: test/CodeGen/X86/O3-pipeline.ll =================================================================== --- test/CodeGen/X86/O3-pipeline.ll +++ test/CodeGen/X86/O3-pipeline.ll @@ -56,9 +56,9 @@ ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Exception handling preparation ; CHECK-NEXT: Safe Stack instrumentation pass +; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Insert stack protectors ; CHECK-NEXT: Module Verifier -; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Basic Alias Analysis (stateless AA impl) ; CHECK-NEXT: Function Alias Analysis Results ; CHECK-NEXT: Natural Loop Information Index: test/CodeGen/X86/stack-protector-unreachable-code.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/stack-protector-unreachable-code.ll @@ -0,0 +1,28 @@ +; RUN: llc -mtriple=x86_64-unknown-unknown -start-before=stack-protector -stop-after=stack-protector %s -o - | FileCheck %s + +; The self-referencing instruction %user shouldn't cause infinite recursion. + +define void @f() sspreq { +entry: + %ai = alloca i8, align 1 + ret void + +dead: + %user = select i1 undef, i8* %ai, i8* %user + unreachable +} + +; CHECK: @__stack_chk_guard = external global i8* + +; CHECK: define void @f() #0 { +; CHECK-NEXT: entry: +; CHECK-NEXT: %StackGuardSlot = alloca i8* +; CHECK-NEXT: %0 = call i8* @llvm.stackguard() +; CHECK-NEXT: call void @llvm.stackprotector(i8* %0, i8** %StackGuardSlot) +; CHECK-NEXT: %ai = alloca i8, align 1 +; CHECK-NEXT: ret void + +; CHECK: dead: ; No predecessors! +; CHECK-NEXT: %user = select i1 undef, i8* %ai, i8* %user +; CHECK-NEXT: unreachable +; CHECK-NEXT: }