diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 69babc7c9cf3e..c12eba5dfdd8c 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -9,6 +9,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_llvm::RustString; use rustc_middle::bug; use rustc_middle::mir::coverage::CoverageKind; +use rustc_middle::mir::{Statement, StatementKind}; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::Instance; use rustc_target::abi::{Align, Size}; @@ -92,9 +93,8 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { fn init_coverage(&mut self, instance: Instance<'tcx>) { - let Some(function_coverage_info) = - self.tcx.instance_mir(instance.def).function_coverage_info.as_deref() - else { + let mir_body = self.tcx.instance_mir(instance.def); + let Some(function_coverage_info) = mir_body.function_coverage_info.as_deref() else { return; }; @@ -103,6 +103,22 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { return; } + let is_mcdc_statement = |statement: &Statement<'_>| { + let StatementKind::Coverage(cov_kind) = &statement.kind else { + return false; + }; + matches!( + cov_kind, + CoverageKind::TestVectorBitmapUpdate { .. } | CoverageKind::CondBitmapUpdate { .. } + ) + }; + // Some instances like `DropGlue` clone mir body from others and modified the basic blocks after coverage pass. + // Such instances might have same `function_coverage_info` as the primary but have no associated coverage statement. + // Ignore these instances here. + if !mir_body.basic_blocks.iter().map(|bb| &bb.statements).flatten().any(is_mcdc_statement) { + return; + } + let fn_name = self.get_pgo_func_name_var(instance); let hash = self.const_u64(function_coverage_info.function_source_hash); let bitmap_bytes = self.const_u32(function_coverage_info.mcdc_bitmap_bytes);