Index: lib/Transforms/Instrumentation/SanitizerCoverage.cpp =================================================================== --- lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -401,7 +401,10 @@ if (Options.NoPrune || &F.getEntryBlock() == BB) return true; - return !(isFullDominator(BB, DT) || isFullPostDominator(BB, PDT)); + // Do not instrument full dominators, or full post-dominators with multiple + // predecessors. + return !isFullDominator(BB, DT) + && !(isFullPostDominator(BB, PDT) && !BB->getSinglePredecessor()); } bool SanitizerCoverageModule::runOnFunction(Function &F) { Index: test/Instrumentation/SanitizerCoverage/chains.ll =================================================================== --- /dev/null +++ test/Instrumentation/SanitizerCoverage/chains.ll @@ -0,0 +1,33 @@ +; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s + +define i32 @blah(i32) #0 { + %2 = icmp sgt i32 %0, 1 + br i1 %2, label %branch, label %exit +; CHECK: call void @__sanitizer_cov_trace_pc() + +branch: + br label %pos2 +; CHECK-LABEL: branch: +; CHECK-NOT: call void @__sanitizer_cov_trace_pc() + +pos2: + br label %pos3 +; CHECK-LABEL: pos2: +; CHECK-NOT: call void @__sanitizer_cov_trace_pc() + +pos3: + br label %pos4 +; CHECK-LABEL: pos3: +; CHECK-NOT: call void @__sanitizer_cov_trace_pc() + +pos4: + ret i32 0 +; CHECK-LABEL: pos4: +; CHECK: call void @__sanitizer_cov_trace_pc() + +exit: + ret i32 0 +; CHECK-LABEL: exit: +; CHECK: call void @__sanitizer_cov_trace_pc() + +} Index: test/Instrumentation/SanitizerCoverage/postdominator_check.ll =================================================================== --- /dev/null +++ test/Instrumentation/SanitizerCoverage/postdominator_check.ll @@ -0,0 +1,55 @@ +; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s + +define i32 @foo(i32) #0 { + %2 = icmp sgt i32 %0, 0 + br i1 %2, label %left, label %right +; CHECK: call void @__sanitizer_cov_trace_pc() + +left: + %3 = icmp sgt i32 %0, 10 + br i1 %3, label %left_left, label %left_right +; CHECK-LABEL: left: +; CHECK-NOT: call void @__sanitizer_cov_trace_pc() + +left_left: + br label %left_join +; CHECK-LABEL: left_left: +; CHECK: call void @__sanitizer_cov_trace_pc() + +left_right: + br label %left_join +; CHECK-LABEL: left_right: +; CHECK: call void @__sanitizer_cov_trace_pc() + +left_join: + br label %finish +; CHECK-LABEL: left_join: +; CHECK-NOT: call void @__sanitizer_cov_trace_pc() + +right: + %4 = icmp sgt i32 %0, 10 + br i1 %4, label %right_left, label %right_right +; CHECK-LABEL: right: +; CHECK-NOT: call void @__sanitizer_cov_trace_pc() + +right_left: + br label %right_join +; CHECK-LABEL: right_left: +; CHECK: call void @__sanitizer_cov_trace_pc() + +right_right: + br label %right_join +; CHECK-LABEL: right_right: +; CHECK: call void @__sanitizer_cov_trace_pc() + +right_join: + br label %finish +; CHECK-LABEL: right_join: +; CHECK-NOT: call void @__sanitizer_cov_trace_pc() + +finish: + ret i32 %0 +; CHECK-LABEL: finish: +; CHECK-NOT: call void @__sanitizer_cov_trace_pc() + +}