Index: include/llvm/Transforms/Utils/BasicBlockUtils.h =================================================================== --- include/llvm/Transforms/Utils/BasicBlockUtils.h +++ include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -102,6 +102,7 @@ bool MergeIdenticalEdges = false; bool DontDeleteUselessPHIs = false; bool PreserveLCSSA = false; + bool IgnoreUnreachableDests = false; CriticalEdgeSplittingOptions(DominatorTree *DT = nullptr, LoopInfo *LI = nullptr, @@ -122,6 +123,11 @@ PreserveLCSSA = true; return *this; } + + CriticalEdgeSplittingOptions &setIgnoreUnreachableDests() { + IgnoreUnreachableDests = true; + return *this; + } }; /// If this edge is a critical edge, insert a new node to split the critical Index: lib/Transforms/Instrumentation/SanitizerCoverage.cpp =================================================================== --- lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -535,7 +535,7 @@ isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) return false; if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge) - SplitAllCriticalEdges(F); + SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests()); SmallVector IndirCalls; SmallVector BlocksToInstrument; SmallVector CmpTraceTargets; Index: lib/Transforms/Utils/BreakCriticalEdges.cpp =================================================================== --- lib/Transforms/Utils/BreakCriticalEdges.cpp +++ lib/Transforms/Utils/BreakCriticalEdges.cpp @@ -148,6 +148,10 @@ if (isa(TI) && SuccNum > 0) return nullptr; + if (Options.IgnoreUnreachableDests && + isa(DestBB->getTerminator())) + return nullptr; + // Create a new basic block, linking it into the CFG. BasicBlock *NewBB = BasicBlock::Create(TI->getContext(), TIBB->getName() + "." + DestBB->getName() + "_crit_edge"); Index: test/Instrumentation/SanitizerCoverage/unreachable-critedge.ll =================================================================== --- test/Instrumentation/SanitizerCoverage/unreachable-critedge.ll +++ test/Instrumentation/SanitizerCoverage/unreachable-critedge.ll @@ -3,47 +3,39 @@ define i32 @foo(i32 %c, i32 %d) { ; CHECK-LABEL: @foo( -; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* getelementptr inbounds ([8 x i32], [8 x i32]* @__sancov_gen_, i32 0, i32 0)) +; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* getelementptr inbounds ([6 x i32], [6 x i32]* @__sancov_gen_, i32 0, i32 0)) ; CHECK-NEXT: call void asm sideeffect "", ""() -; CHECK-NEXT: switch i32 [[C:%.*]], label [[DOTUNREACHABLE_BB_CRIT_EDGE:%.*]] [ +; CHECK-NEXT: switch i32 [[C:%.*]], label [[UNREACHABLE_BB:%.*]] [ ; CHECK-NEXT: i32 0, label [[EXIT0:%.*]] ; CHECK-NEXT: i32 1, label [[EXIT1:%.*]] ; CHECK-NEXT: i32 2, label [[DOTCONT_CRIT_EDGE:%.*]] ; CHECK-NEXT: ] ; CHECK: .cont_crit_edge: ; CHECK-NEXT: br label [[CONT:%.*]] -; CHECK: .unreachable_bb_crit_edge: -; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([8 x i32]* @__sancov_gen_ to i64), i64 4) to i32*)) -; CHECK-NEXT: call void asm sideeffect "", ""() -; CHECK-NEXT: br label [[UNREACHABLE_BB:%.*]] ; CHECK: cont: -; CHECK-NEXT: switch i32 [[D:%.*]], label [[CONT_UNREACHABLE_BB_CRIT_EDGE:%.*]] [ +; CHECK-NEXT: switch i32 [[D:%.*]], label [[UNREACHABLE_BB]] [ ; CHECK-NEXT: i32 0, label [[EXIT2:%.*]] ; CHECK-NEXT: i32 1, label [[EXIT3:%.*]] ; CHECK-NEXT: i32 2, label [[CONT_CONT_CRIT_EDGE:%.*]] ; CHECK-NEXT: ] ; CHECK: cont.cont_crit_edge: -; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([8 x i32]* @__sancov_gen_ to i64), i64 8) to i32*)) +; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([6 x i32]* @__sancov_gen_ to i64), i64 4) to i32*)) ; CHECK-NEXT: call void asm sideeffect "", ""() ; CHECK-NEXT: br label [[CONT]] -; CHECK: cont.unreachable_bb_crit_edge: -; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([8 x i32]* @__sancov_gen_ to i64), i64 12) to i32*)) -; CHECK-NEXT: call void asm sideeffect "", ""() -; CHECK-NEXT: br label [[UNREACHABLE_BB]] ; CHECK: exit0: -; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([8 x i32]* @__sancov_gen_ to i64), i64 16) to i32*)) +; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([6 x i32]* @__sancov_gen_ to i64), i64 8) to i32*)) ; CHECK-NEXT: call void asm sideeffect "", ""() ; CHECK-NEXT: ret i32 0 ; CHECK: exit1: -; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([8 x i32]* @__sancov_gen_ to i64), i64 20) to i32*)) +; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([6 x i32]* @__sancov_gen_ to i64), i64 12) to i32*)) ; CHECK-NEXT: call void asm sideeffect "", ""() ; CHECK-NEXT: ret i32 1 ; CHECK: exit2: -; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([8 x i32]* @__sancov_gen_ to i64), i64 24) to i32*)) +; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([6 x i32]* @__sancov_gen_ to i64), i64 16) to i32*)) ; CHECK-NEXT: call void asm sideeffect "", ""() ; CHECK-NEXT: ret i32 2 ; CHECK: exit3: -; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([8 x i32]* @__sancov_gen_ to i64), i64 28) to i32*)) +; CHECK-NEXT: call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 add (i64 ptrtoint ([6 x i32]* @__sancov_gen_ to i64), i64 20) to i32*)) ; CHECK-NEXT: call void asm sideeffect "", ""() ; CHECK-NEXT: ret i32 3 ; CHECK: unreachable_bb: