Skip to content

Make coverage robust against MIR optimizations removing all counter-increment statements #116171

Closed
@Zalathar

Description

@Zalathar

When coverage instrumentation and MIR opts are both enabled, coverage relies on two assumptions:

  • MIR opts that would delete StatementKind::Coverage statements instead move them into bb0 and change them to CoverageKind::Unreachable.

  • MIR opts won't delete all CoverageKind::Counter statements from an instrumented function.

The first assumption will be lifted by #116046, which stores coverage mappings in a separate per-function struct, so the original mappings will be available during codegen even if MIR opts delete arbitrary coverage statements.


The second assumption is trickier. If a function is instrumented for coverage, but MIR opts remove all of its counter-increment statements (e.g. because bb0's ends with TerminatorKind::Unreachable), then we will codegen a function with no llvm.instrprof.increment intrinsics. This causes LLVM to assume that the function wasn't instrumented, so it will disappear from the final coverage mappings and won't participate in coverage reports.

Coverage has special code for handling functions that are deemed “unused” at the MIR level, but if a function is used (e.g. as a function pointer) but its body is unreachable, then that special code isn't applied.


Ideally what we need is some way for coverage codegen to detect that an instrumented function has no remaining counter-increment statements, and take special action to either re-insert at least one counter-increment (so LLVM treats it as instrumented), or treat it as though it were unused (so that it shows up in reports as never-executed).


@rustbot label +A-code-coverage +T-compiler

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-code-coverageArea: Source-based code coverage (-Cinstrument-coverage)A-mir-optArea: MIR optimizationsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions