diff options
| author | Rich Kadel <richkadel@google.com> | 2020-08-27 14:13:04 -0700 |
|---|---|---|
| committer | Rich Kadel <richkadel@google.com> | 2020-09-03 00:20:29 -0700 |
| commit | 51d692cf7709de563cac6b5ee0080b8adf96f1df (patch) | |
| tree | c557be235c6ef828d1517ca31d3a248d0d8e162b | |
| parent | e36e4bd0f7e722d3c97d1ca45387e58f81e4e8ea (diff) | |
| download | rust-51d692cf7709de563cac6b5ee0080b8adf96f1df.tar.gz rust-51d692cf7709de563cac6b5ee0080b8adf96f1df.zip | |
Tools, tests, and experimenting with MIR-derived coverage counters
Adds a new mir_dump output file in HTML/CSS to visualize code regions and the MIR features that they came from (including overlapping spans). See example below: Includes a basic, MIR-block-based implementation of coverage injection, available via `-Zexperimental-coverage`. This implementation has known flaws and omissions, but is simple enough to validate the new tools and tests. The existing `-Zinstrument-coverage` option currently enables function-level coverage only, which at least appears to generate accurate coverage reports at that level. Experimental coverage is not accurate at this time. When branch coverage works as intended, the `-Zexperimental-coverage` option should be removed. This PR replaces the bulk of PR #75828, with the remaining parts of that PR distributed among other separate and indentpent PRs. This PR depends on three of those other PRs: #76000, #76002, and Rust compiler MCP rust-lang/compiler-team#278 Relevant issue: #34701 - Implement support for LLVMs code coverage instrumentation 
28 files changed, 2072 insertions, 299 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 785a7f0c51a..453bc6ea6c7 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1530,7 +1530,24 @@ impl Debug for Statement<'_> { AscribeUserType(box (ref place, ref c_ty), ref variance) => { write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty) } - Coverage(box ref coverage) => write!(fmt, "{:?}", coverage), + Coverage(box ref coverage) => { + let rgn = &coverage.code_region; + match coverage.kind { + CoverageKind::Counter { id, .. } => { + write!(fmt, "Coverage::Counter({:?}) for {:?}", id.index(), rgn) + } + CoverageKind::Expression { id, lhs, op, rhs } => write!( + fmt, + "Coverage::Expression({:?}) = {} {} {} for {:?}", + id.index(), + lhs.index(), + if op == coverage::Op::Add { "+" } else { "-" }, + rhs.index(), + rgn + ), + CoverageKind::Unreachable => write!(fmt, "Coverage::Unreachable for {:?}", rgn), + } + } Nop => write!(fmt, "nop"), } } diff --git a/compiler/rustc_mir/src/transform/instrument_coverage.rs b/compiler/rustc_mir/src/transform/instrument_coverage.rs index f60e6da714a..d3a2bd24123 100644 --- a/compiler/rustc_mir/src/transform/instrument_coverage.rs +++ b/compiler/rustc_mir/src/transform/instrument_coverage.rs @@ -1,23 +1,34 @@ use crate::transform::{MirPass, MirSource}; +use crate::util::pretty; +use crate::util::spanview::{ + source_range_no_file, statement_kind_name, terminator_kind_name, write_spanview_document, + SpanViewable, TOOLTIP_INDENT, +}; + use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_index::bit_set::BitSet; use rustc_middle::hir; use rustc_middle::ich::StableHashingContext; use rustc_middle::mir; use rustc_middle::mir::coverage::*; use rustc_middle::mir::visit::Visitor; -use rustc_middle::mir::{BasicBlock, Coverage, CoverageInfo, Location, Statement, StatementKind}; +use rustc_middle::mir::{ + BasicBlock, BasicBlockData, Coverage, CoverageInfo, Location, Statement, StatementKind, + TerminatorKind, +}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::DefId; use rustc_span::{FileName, Pos, RealFileName, Span, Symbol}; -/// Inserts call to count_code_region() as a placeholder to be replaced during code generation with -/// the intrinsic llvm.instrprof.increment. +/// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected +/// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen +/// to construct the coverage map. pub struct InstrumentCoverage; -/// The `query` provider for `CoverageInfo`, requested by `codegen_intrinsic_call()` when -/// constructing the arguments for `llvm.instrprof.increment`. +/// The `query` provider for `CoverageInfo`, requested by `codegen_coverage()` (to inject each +/// counter) and `FunctionCoverage::new()` (to extract the coverage map metadata from the MIR). pub(crate) fn provide(providers: &mut Providers) { providers.coverageinfo = |tcx, def_id| coverageinfo_from_mir(tcx, def_id); } @@ -43,8 +54,8 @@ impl Visitor<'_> for CoverageVisitor { } } -fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, mir_def_id: DefId) -> CoverageInfo { - let mir_body = tcx.optimized_mir(mir_def_id); +fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo { + let mir_body = tcx.optimized_mir(def_id); // The `num_counters` argument to `llvm.instrprof.increment` is the number of injected // counters, with each counter having a counter ID from `0..num_counters-1`. MIR optimization @@ -63,18 +74,30 @@ fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, mir_def_id: DefId) -> Coverage } impl<'tcx> MirPass<'tcx> for InstrumentCoverage { - fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, mir_body: &mut mir::Body<'tcx>) { + fn run_pass( + &self, + tcx: TyCtxt<'tcx>, + mir_source: MirSource<'tcx>, + mir_body: &mut mir::Body<'tcx>, + ) { // If the InstrumentCoverage pass is called on promoted MIRs, skip them. // See: https://github.com/rust-lang/rust/pull/73011#discussion_r438317601 - if src.promoted.is_none() { - Instrumentor::new(tcx, src, mir_body).inject_counters(); + if mir_source.promoted.is_none() { + Instrumentor::new(&self.name(), tcx, mir_source, mir_body).inject_counters(); } } } +#[derive(Clone)] +struct CoverageRegion { + pub span: Span, + pub blocks: Vec<BasicBlock>, +} + struct Instrumentor<'a, 'tcx> { + pass_name: &'a str, tcx: TyCtxt<'tcx>, - mir_def_id: DefId, + mir_source: MirSource<'tcx>, mir_body: &'a mut mir::Body<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx>, function_source_hash: Option<u64>, @@ -83,12 +106,17 @@ struct Instrumentor<'a, 'tcx> { } impl<'a, 'tcx> Instrumentor<'a, 'tcx> { - fn new(tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, mir_body: &'a mut mir::Body<'tcx>) -> Self { - let mir_def_id = src.def_id(); - let hir_body = hir_body(tcx, mir_def_id); + fn new( + pass_name: &'a str, + tcx: TyCtxt<'tcx>, + mir_source: MirSource<'tcx>, + mir_body: &'a mut mir::Body<'tcx>, + ) -> Self { + let hir_body = hir_body(tcx, mir_source.def_id()); Self { + pass_name, tcx, - mir_def_id, + mir_source, mir_body, hir_body, function_source_hash: None, @@ -127,19 +155,100 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { } fn inject_counters(&mut self) { + let tcx = self.tcx; + let def_id = self.mir_source.def_id(); + let mir_body = &self.mir_body; let body_span = self.hir_body.value.span; - debug!("instrumenting {:?}, span: {:?}", self.mir_def_id, body_span); - - // FIXME(richkadel): As a first step, counters are only injected at the top of each - // function. The complete solution will inject counters at each conditional code branch. - let block = rustc_middle::mir::START_BLOCK; - let counter = self.make_counter(); - self.inject_statement(counter, body_span, block); - - // FIXME(richkadel): The next step to implement source based coverage analysis will be - // instrumenting branches within functions, and some regions will be counted by "counter - // expression". The function to inject counter expression is implemented. Replace this - // "fake use" with real use. + debug!( + "instrumenting {:?}, span: {}", + def_id, + tcx.sess.source_map().span_to_string(body_span) + ); + + if !tcx.sess.opts.debugging_opts.experimental_coverage { + // Coverage at the function level should be accurate. This is the default implementation + // if `-Z experimental-coverage` is *NOT* enabled. + let block = rustc_middle::mir::START_BLOCK; + let counter = self.make_counter(); + self.inject_statement(counter, body_span, block); + return; + } + // FIXME(richkadel): else if `-Z experimental-coverage` *IS* enabled: Efforts are still in + // progress to identify the correct code region spans and associated counters to generate + // accurate Rust coverage reports. + + let block_span = |data: &BasicBlockData<'tcx>| { + // The default span will be the `Terminator` span; but until we have a smarter solution, + // the coverage region also incorporates at least the statements in this BasicBlock as + // well. Extend the span to encompass all, if possible. + // FIXME(richkadel): Assuming the terminator's span is already known to be contained in `body_span`. + let mut span = data.terminator().source_info.span; + // FIXME(richkadel): It's looking unlikely that we should compute a span from MIR + // spans, but if we do keep something like this logic, we will need a smarter way + // to combine `Statement`s and/or `Terminator`s with `Span`s from different + // files. + for statement_span in data.statements.iter().map(|statement| statement.source_info.span) + { + // Only combine Spans from the function's body_span. + if body_span.contains(statement_span) { + span = span.to(statement_span); + } + } + span + }; + + // Traverse the CFG but ignore anything following an `unwind` + let cfg_without_unwind = ShortCircuitPreorder::new(mir_body, |term_kind| { + let mut successors = term_kind.successors(); + match &term_kind { + // SwitchInt successors are never unwind, and all of them should be traversed + TerminatorKind::SwitchInt { .. } => successors, + // For all other kinds, return only the first successor, if any, and ignore unwinds + _ => successors.next().into_iter().chain(&[]), + } + }); + + let mut coverage_regions = Vec::with_capacity(cfg_without_unwind.size_hint().0); + for (bb, data) in cfg_without_unwind { + if !body_span.contains(data.terminator().source_info.span) { + continue; + } + + // FIXME(richkadel): Regions will soon contain multiple blocks. + let mut blocks = Vec::new(); + blocks.push(bb); + let span = block_span(data); + coverage_regions.push(CoverageRegion { span, blocks }); + } + + let span_viewables = if pretty::dump_enabled(tcx, self.pass_name, def_id) { + Some(self.span_viewables(&coverage_regions)) + } else { + None + }; + + // Inject counters for the selected spans + for CoverageRegion { span, blocks } in coverage_regions { + debug!( + "Injecting counter at: {:?}:\n{}\n==========", + span, + tcx.sess.source_map().span_to_snippet(span).expect("Error getting source for span"), + ); + let counter = self.make_counter(); + self.inject_statement(counter, span, blocks[0]); + } + + if let Some(span_viewables) = span_viewables { + let mut file = + pretty::create_dump_file(tcx, "html", None, self.pass_name, &0, self.mir_source) + .expect("Unexpected error creating MIR spanview HTML file"); + write_spanview_document(tcx, def_id, span_viewables, &mut file) + .expect("Unexpected IO error dumping coverage spans as HTML"); + } + + // FIXME(richkadel): Some regions will be counted by "counter expression". Counter + // expressions are supported, but are not yet generated. When they are, remove this `fake_use` + // block. let fake_use = false; if fake_use { let add = false; @@ -193,6 +302,83 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { }; data.statements.push(statement); } + + /// Converts the computed `CoverageRegion`s into `SpanViewable`s. + fn span_viewables(&self, coverage_regions: &Vec<CoverageRegion>) -> Vec<SpanViewable> { + let mut span_viewables = Vec::new(); + for coverage_region in coverage_regions { + span_viewables.push(SpanViewable { + span: coverage_region.span, + title: format!("{}", coverage_region.blocks[0].index()), + tooltip: self.make_tooltip_text(coverage_region), + }); + } + span_viewables + } + + /// A custom tooltip renderer used in a spanview HTML+CSS document used for coverage analysis. + fn make_tooltip_text(&self, coverage_region: &CoverageRegion) -> String { + const INCLUDE_COVERAGE_STATEMENTS: bool = false; + let tcx = self.tcx; + let source_map = tcx.sess.source_map(); + let mut text = Vec::new(); + for (i, &bb) in coverage_region.blocks.iter().enumerate() { + if i > 0 { + text.push("\n".to_owned()); + } + text.push(format!("{:?}: {}:", bb, &source_map.span_to_string(coverage_region.span))); + let data = &self.mir_body.basic_blocks()[bb]; + for statement in &data.statements { + let statement_string = match statement.kind { + StatementKind::Coverage(box ref coverage) => match coverage.kind { + CoverageKind::Counter { id, .. } => { + if !INCLUDE_COVERAGE_STATEMENTS { + continue; + } + format!("increment counter #{}", id.index()) + } + CoverageKind::Expression { id, lhs, op, rhs } => { + if !INCLUDE_COVERAGE_STATEMENTS { + continue; + } + format!( + "expression #{} = {} {} {}", + id.index(), + lhs.index(), + if op == Op::Add { "+" } else { "-" }, + rhs.index() + ) + } + CoverageKind::Unreachable => { + if !INCLUDE_COVERAGE_STATEMENTS { + continue; + } + format!("unreachable") + } + }, + _ => format!("{:?}", statement), + }; + let source_range = source_range_no_file(tcx, &statement.source_info.span); + text.push(format!( + "\n{}{}: {}: {}", + TOOLTIP_INDENT, + source_range, + statement_kind_name(statement), + statement_string + )); + } + let term = data.terminator(); + let source_range = source_range_no_file(tcx, &term.source_info.span); + text.push(format!( + "\n{}{}: {}: {:?}", + TOOLTIP_INDENT, + source_range, + terminator_kind_name(term), + term.kind + )); + } + text.join("") + } } /// Convert the Span into its file name, start line and column, and end line and column @@ -227,7 +413,7 @@ fn make_code_region<'tcx>(tcx: TyCtxt<'tcx>, span: &Span) -> CodeRegion { } fn hir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx rustc_hir::Body<'tcx> { - let hir_node = tcx.hir().get_if_local(def_id).expect("DefId is local"); + let hir_node = tcx.hir().get_if_local(def_id).expect("expected DefId is local"); let fn_body_id = hir::map::associated_body(hir_node).expect("HIR node is a function with body"); tcx.hir().body(fn_body_id) } @@ -245,3 +431,61 @@ fn hash( node.hash_stable(hcx, &mut stable_hasher); stable_hasher.finish() } + +pub struct ShortCircuitPreorder< + 'a, + 'tcx, + F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>, +> { + body: &'a mir::Body<'tcx>, + visited: BitSet<BasicBlock>, + worklist: Vec<BasicBlock>, + filtered_successors: F, +} + +impl<'a, 'tcx, F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>> + ShortCircuitPreorder<'a, 'tcx, F> +{ + pub fn new( + body: &'a mir::Body<'tcx>, + filtered_successors: F, + ) -> ShortCircuitPreorder<'a, 'tcx, F> { + let worklist = vec![mir::START_BLOCK]; + + ShortCircuitPreorder { + body, + visited: BitSet::new_empty(body.basic_blocks().len()), + worklist, + filtered_successors, + } + } +} + +impl<'a: 'tcx, 'tcx, F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>> Iterator + for ShortCircuitPreorder<'a, 'tcx, F> +{ + type Item = (BasicBlock, &'a BasicBlockData<'tcx>); + + fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { + while let Some(idx) = self.worklist.pop() { + if !self.visited.insert(idx) { + continue; + } + + let data = &self.body[idx]; + + if let Some(ref term) = data.terminator { + self.worklist.extend((self.filtered_successors)(&term.kind)); + } + + return Some((idx, data)); + } + + None + } + + fn size_hint(&self) -> (usize, Option<usize>) { + let size = self.body.basic_blocks().len() - self.visited.count(); + (size, Some(size)) + } +} diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 6861314a88f..7db2557453b 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1724,6 +1724,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { ); } + if debugging_opts.experimental_coverage { + debugging_opts.instrument_coverage = true; + } + if debugging_opts.instrument_coverage { if cg.profile_generate.enabled() || cg.profile_use.is_some() { early_error( diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index a28c17917df..44a18bd7831 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -890,6 +890,11 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, all statements)."), emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], "emit a section containing stack size metadata (default: no)"), + experimental_coverage: bool = (false, parse_bool, [TRACKED], + "enable and extend the `-Z instrument-coverage` function-level coverage \ + feature, adding additional experimental (likely inaccurate) counters and \ + code regions (used by `rustc` compiler developers to test new coverage \ + counter placements) (default: no)"), fewer_names: bool = (false, parse_bool, [TRACKED], "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \ (default: no)"), diff --git a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff index 01d837d155a..5b2572655cc 100644 --- a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff +++ b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff @@ -6,7 +6,7 @@ bb0: { _0 = const true; // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9 -+ Coverage { kind: Counter { function_source_hash: 10208505205182607101, id: CounterValueReference(0) }, code_region: /the/src/instrument_coverage.rs:19:18 - 21:2 }; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2 ++ Coverage::Counter(0) for /the/src/instrument_coverage.rs:19:18 - 21:2; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2 return; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2 } } diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff index 43c8be8f45d..03affed0505 100644 --- a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff +++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff @@ -8,7 +8,7 @@ let mut _3: !; // in scope 0 at /the/src/instrument_coverage.rs:12:18: 14:10 bb0: { -+ Coverage { kind: Counter { function_source_hash: 16004455475339839479, id: CounterValueReference(0) }, code_region: /the/src/instrument_coverage.rs:10:11 - 16:2 }; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 ++ Coverage::Counter(0) for /the/src/instrument_coverage.rs:10:11 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 } diff --git a/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/Makefile b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/Makefile new file mode 100644 index 00000000000..a16b4f61dcb --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/Makefile @@ -0,0 +1,77 @@ +# needs-profiler-support + +# ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and +# `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw`. +# See ../instrument-coverage/coverage_tools.mk for more information. + +-include ../instrument-coverage/coverage_tools.mk + +BASEDIR=../instrument-coverage-cov-reports-base +SOURCEDIR=../instrument-coverage + +all: $(patsubst $(SOURCEDIR)/%.rs,%,$(wildcard $(SOURCEDIR)/*.rs)) + +# Ensure there are no `expected` results for tests that may have been removed or renamed +.PHONY: clear_expected_if_blessed +clear_expected_if_blessed: +ifdef RUSTC_BLESS_TEST + rm -f expected_export_coverage.*.json + rm -f typical_show_coverage.*.txt +endif + +-include clear_expected_if_blessed + +%: $(SOURCEDIR)/%.rs + # Compile the test program with "experimental" coverage instrumentation and generate relevant MIR. + # + # FIXME(richkadel): `-Zexperimental-coverage` to `-Zinstrument-coverage` once we are + # satisfied with the branch-level instrumentation. + $(RUSTC) $(SOURCEDIR)/$@.rs \ + -Zexperimental-coverage \ + -Clink-dead-code=$(LINK_DEAD_CODE) + + # Run it in order to generate some profiling data, + # with `LLVM_PROFILE_FILE=<profdata_file>` environment variable set to + # output the coverage stats for this run. + LLVM_PROFILE_FILE="$(TMPDIR)"/$@.profraw \ + $(call RUN,$@) + + # Postprocess the profiling data so it can be used by the llvm-cov tool + "$(LLVM_BIN_DIR)"/llvm-profdata merge --sparse \ + "$(TMPDIR)"/$@.profraw \ + -o "$(TMPDIR)"/$@.profdata + + # Generate a coverage report using `llvm-cov show`. The output ordering + # can be non-deterministic, so ignore the return status. If the test fails + # when comparing the JSON `export`, the `show` output may be useful when + # debugging. + "$(LLVM_BIN_DIR)"/llvm-cov show \ + --Xdemangler="$(RUST_DEMANGLER)" \ + --show-line-counts-or-regions \ + --instr-profile="$(TMPDIR)"/$@.profdata \ + $(call BIN,"$(TMPDIR)"/$@) \ + > "$(TMPDIR)"/actual_show_coverage.$@.txt + +ifdef RUSTC_BLESS_TEST + cp "$(TMPDIR)"/actual_show_coverage.$@.txt typical_show_coverage.$@.txt +else + # Compare the show coverage output (`--bless` refreshes `typical` files) + $(DIFF) typical_show_coverage.$@.txt "$(TMPDIR)"/actual_show_coverage.$@.txt || \ + >&2 echo 'diff failed for `llvm-cov show` on $@ (might not be an error)' +endif + + # Generate a coverage report in JSON, using `llvm-cov export`, and fail if + # there are differences from the expected output. + "$(LLVM_BIN_DIR)"/llvm-cov export \ + --summary-only \ + --instr-profile="$(TMPDIR)"/$@.profdata \ + $(call BIN,"$(TMPDIR)"/$@) \ + | "$(PYTHON)" $(BASEDIR)/prettify_json.py \ + > "$(TMPDIR)"/actual_export_coverage.$@.json + +ifdef RUSTC_BLESS_TEST + cp "$(TMPDIR)"/actual_export_coverage.$@.json expected_export_coverage.$@.json +else + # Check that exported JSON coverage data matches what we expect (`--bless` refreshes `expected`) + $(DIFF) expected_export_coverage.$@.json "$(TMPDIR)"/actual_export_coverage.$@.json +endif diff --git a/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/expected_export_coverage.coverage_of_if_else.json b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/expected_export_coverage.coverage_of_if_else.json new file mode 100644 index 00000000000..b9041ebebef --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/expected_export_coverage.coverage_of_if_else.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../instrument-coverage/coverage_of_if_else.rs", + "summary": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 46, + "covered": 19, + "percent": 41.30434782608695 + }, + "regions": { + "count": 75, + "covered": 23, + "notcovered": 52, + "percent": 30.666666666666664 + } + } + } + ], + "totals": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 46, + "covered": 19, + "percent": 41.30434782608695 + }, + "regions": { + "count": 75, + "covered": 23, + "notcovered": 52, + "percent": 30.666666666666664 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/instrument-coverage/prettify_json.py b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/prettify_json.py index ed9279841f7..ed9279841f7 100644 --- a/src/test/run-make-fulldeps/instrument-coverage/prettify_json.py +++ b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/prettify_json.py diff --git a/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/typical_show_coverage.coverage_of_if_else.txt b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/typical_show_coverage.coverage_of_if_else.txt new file mode 100644 index 00000000000..0c711559603 --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/typical_show_coverage.coverage_of_if_else.txt @@ -0,0 +1,64 @@ + 1| |#![allow(unused_assignments)] + 2| | + 3| |fn main() { + 4| | let mut countdown = 0; + 5| 2| if true { + ^1 + 6| 2| countdown = 10; + 7| 2| } + 8| | + 9| 2| if countdown > 7 { + ^1 + 10| 2| countdown -= 4; + ^1 + 11| 2| } else if countdown > 2 { + ^0 ^0 + 12| 0| if countdown < 1 || countdown > 5 || countdown != 9 { + 13| 0| countdown = 0; + 14| 0| } + 15| 0| countdown -= 5; + 16| 0| } else { + 17| 0| return; + 18| 0| } + 19| 0| + 20| 0| let mut countdown = 0; + 21| 2| if true { + ^1 + 22| 2| countdown = 10; + 23| 2| } + 24| 0| + 25| 2| if countdown > 7 { + ^1 + 26| 2| countdown -= 4; + ^1 + 27| 2| } else if countdown > 2 { + ^0 ^0 + 28| 0| if countdown < 1 || countdown > 5 || countdown != 9 { + 29| 0| countdown = 0; + 30| 0| } + 31| 0| countdown -= 5; + 32| 0| } else { + 33| 0| return; + 34| 0| } + 35| 0| + 36| 0| let mut countdown = 0; + 37| 2| if true { + ^1 + 38| 2| countdown = 10; + 39| 2| } + 40| 0| + 41| 2| if countdown > 7 { + ^1 + 42| 2| countdown -= 4; + ^1 + 43| 2| } else if countdown > 2 { + ^0 ^0 + 44| 0| if countdown < 1 || countdown > 5 || countdown != 9 { + 45| 0| countdown = 0; + 46| 0| } + 47| 0| countdown -= 5; + 48| 0| } else { + 49| 0| return; + 50| 0| } + 51| 1|} + diff --git a/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/Makefile b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/Makefile new file mode 100644 index 00000000000..08f311f1702 --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/Makefile @@ -0,0 +1,11 @@ +# needs-profiler-support +# ignore-msvc + +# LINK_DEAD_CODE requires ignore-msvc due to Issue #76038 +LINK_DEAD_CODE=yes + +-include ../instrument-coverage-cov-reports-base/Makefile + +# ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and +# `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw`. +# See ../instrument-coverage/coverage_tools.mk for more information. \ No newline at end of file diff --git a/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/expected_export_coverage.coverage_of_if_else.json b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/expected_export_coverage.coverage_of_if_else.json new file mode 100644 index 00000000000..b9041ebebef --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/expected_export_coverage.coverage_of_if_else.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../instrument-coverage/coverage_of_if_else.rs", + "summary": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 46, + "covered": 19, + "percent": 41.30434782608695 + }, + "regions": { + "count": 75, + "covered": 23, + "notcovered": 52, + "percent": 30.666666666666664 + } + } + } + ], + "totals": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 46, + "covered": 19, + "percent": 41.30434782608695 + }, + "regions": { + "count": 75, + "covered": 23, + "notcovered": 52, + "percent": 30.666666666666664 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/typical_show_coverage.coverage_of_if_else.txt b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/typical_show_coverage.coverage_of_if_else.txt new file mode 100644 index 00000000000..0c711559603 --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/typical_show_coverage.coverage_of_if_else.txt @@ -0,0 +1,64 @@ + 1| |#![allow(unused_assignments)] + 2| | + 3| |fn main() { + 4| | let mut countdown = 0; + 5| 2| if true { + ^1 + 6| 2| countdown = 10; + 7| 2| } + 8| | + 9| 2| if countdown > 7 { + ^1 + 10| 2| countdown -= 4; + ^1 + 11| 2| } else if countdown > 2 { + ^0 ^0 + 12| 0| if countdown < 1 || countdown > 5 || countdown != 9 { + 13| 0| countdown = 0; + 14| 0| } + 15| 0| countdown -= 5; + 16| 0| } else { + 17| 0| return; + 18| 0| } + 19| 0| + 20| 0| let mut countdown = 0; + 21| 2| if true { + ^1 + 22| 2| countdown = 10; + 23| 2| } + 24| 0| + 25| 2| if countdown > 7 { + ^1 + 26| 2| countdown -= 4; + ^1 + 27| 2| } else if countdown > 2 { + ^0 ^0 + 28| 0| if countdown < 1 || countdown > 5 || countdown != 9 { + 29| 0| countdown = 0; + 30| 0| } + 31| 0| countdown -= 5; + 32| 0| } else { + 33| 0| return; + 34| 0| } + 35| 0| + 36| 0| let mut countdown = 0; + 37| 2| if true { + ^1 + 38| 2| countdown = 10; + 39| 2| } + 40| 0| + 41| 2| if countdown > 7 { + ^1 + 42| 2| countdown -= 4; + ^1 + 43| 2| } else if countdown > 2 { + ^0 ^0 + 44| 0| if countdown < 1 || countdown > 5 || countdown != 9 { + 45| 0| countdown = 0; + 46| 0| } + 47| 0| countdown -= 5; + 48| 0| } else { + 49| 0| return; + 50| 0| } + 51| 1|} + diff --git a/src/test/run-make-fulldeps/instrument-coverage-llvm-ir-base/Makefile b/src/test/run-make-fulldeps/instrument-coverage-llvm-ir-base/Makefile new file mode 100644 index 00000000000..f623248ab57 --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-llvm-ir-base/Makefile @@ -0,0 +1,65 @@ +# needs-profiler-support + +# ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and +# `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw`. +# See ../instrument-coverage/coverage_tools.mk for more information. + +-include ../instrument-coverage/coverage_tools.mk + +BASEDIR=../instrument-coverage-llvm-ir-base + +ifeq ($(UNAME),Darwin) + INSTR_PROF_DATA_SUFFIX=,regular,live_support + DATA_SECTION_PREFIX=__DATA, + LLVM_COV_SECTION_PREFIX=__LLVM_COV, +else + INSTR_PROF_DATA_SUFFIX= + DATA_SECTION_PREFIX= + LLVM_COV_SECTION_PREFIX= +endif + +ifeq ($(LINK_DEAD_CODE),yes) + DEFINE_INTERNAL=define hidden +else + DEFINE_INTERNAL=define internal +endif + +ifdef IS_WINDOWS + LLVM_FILECHECK_OPTIONS=\ + -check-prefixes=CHECK,WINDOWS \ + -DPRIVATE_GLOBAL='internal global' \ + -DDEFINE_INTERNAL='$(DEFINE_INTERNAL)' \ + -DINSTR_PROF_DATA='.lprfd$$M' \ + -DINSTR_PROF_NAME='.lprfn$$M' \ + -DINSTR_PROF_CNTS='.lprfc$$M' \ + -DINSTR_PROF_VALS='.lprfv$$M' \ + -DINSTR_PROF_VNODES='.lprfnd$$M' \ + -DINSTR_PROF_COVMAP='.lcovmap$$M' \ + -DINSTR_PROF_ORDERFILE='.lorderfile$$M' +else + LLVM_FILECHECK_OPTIONS=\ + -check-prefixes=CHECK \ + -DPRIVATE_GLOBAL='private global' \ + -DDEFINE_INTERNAL='$(DEFINE_INTERNAL)' \ + -DINSTR_PROF_DATA='$(DATA_SECTION_PREFIX)__llvm_prf_data$(INSTR_PROF_DATA_SUFFIX)' \ + -DINSTR_PROF_NAME='$(DATA_SECTION_PREFIX)__llvm_prf_names' \ + -DINSTR_PROF_CNTS='$(DATA_SECTION_PREFIX)__llvm_prf_cnts' \ + -DINSTR_PROF_VALS='$(DATA_SECTION_PREFIX)__llvm_prf_vals' \ + -DINSTR_PROF_VNODES='$(DATA_SECTION_PREFIX)__llvm_prf_vnds' \ + -DINSTR_PROF_COVMAP='$(LLVM_COV_SECTION_PREFIX)__llvm_covmap' \ + -DINSTR_PROF_ORDERFILE='$(DATA_SECTION_PREFIX)__llvm_orderfile' +endif + +all: + # Compile the test program with non-experimental coverage instrumentation, and generate LLVM IR + # + # Note: `-Clink-dead-code=no` disables the option, needed because the option is automatically + # enabled for some platforms, but not for Windows MSVC (due to Issue #76038). The state of this + # option affects the generated MIR and coverage, so it is enabled for tests to ensure the + # tests results are the same across platforms. + $(RUSTC) $(BASEDIR)/testprog.rs \ + -Zinstrument-coverage \ + -Clink-dead-code=$(LINK_DEAD_CODE) \ + --emit=llvm-ir + + cat "$(TMPDIR)"/testprog.ll | "$(LLVM_FILECHECK)" $(BASEDIR)/filecheck.testprog.txt $(LLVM_FILECHECK_OPTIONS) diff --git a/src/test/run-make-fulldeps/instrument-coverage-llvm-ir-base/filecheck.testprog.txt b/src/test/run-make-fulldeps/instrument-coverage-llvm-ir-base/filecheck.testprog.txt new file mode 100644 index 00000000000..0a3c4aedd55 --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-llvm-ir-base/filecheck.testprog.txt @@ -0,0 +1,49 @@ +# Check for metadata, variables, declarations, and function definitions injected +# into LLVM IR when compiling with -Zinstrument-coverage. + +WINDOWS: $__llvm_profile_runtime_user = comdat any + +CHECK: @__llvm_coverage_mapping = internal constant +CHECK-SAME: section "[[INSTR_PROF_COVMAP]]", align 8 + +WINDOWS: @__llvm_profile_runtime = external global i32 + +CHECK: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = [[PRIVATE_GLOBAL]] +CHECK-SAME: section "[[INSTR_PROF_CNTS]]", align 8 + +CHECK: @__profd__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = [[PRIVATE_GLOBAL]] +CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called, +CHECK-SAME: section "[[INSTR_PROF_DATA]]", align 8 + +CHECK: @__profc__R{{[a-zA-Z0-9_]+}}testprog4main = [[PRIVATE_GLOBAL]] +CHECK-SAME: section "[[INSTR_PROF_CNTS]]", align 8 + +CHECK: @__profd__R{{[a-zA-Z0-9_]+}}testprog4main = [[PRIVATE_GLOBAL]] +CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog4main, +CHECK-SAME: section "[[INSTR_PROF_DATA]]", align 8 + +CHECK: @__llvm_prf_nm = private constant +CHECK-SAME: section "[[INSTR_PROF_NAME]]", align 1 + +CHECK: @llvm.used = appending global +CHECK-SAME: i8* bitcast ({ {{.*}} }* @__llvm_coverage_mapping to i8*) +WINDOWS-SAME: i8* bitcast (i32 ()* @__llvm_profile_runtime_user to i8*) +CHECK-SAME: i8* bitcast ({ {{.*}} }* @__profd__R{{[a-zA-Z0-9_]*}}testprog4main to i8*) +CHECK-SAME: i8* getelementptr inbounds ({{.*}}* @__llvm_prf_nm, i32 0, i32 0) +CHECK-SAME: section "llvm.metadata" + +CHECK: [[DEFINE_INTERNAL]] { {{.*}} } @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called() unnamed_addr #{{[0-9]+}} { +CHECK-NEXT: start: +CHECK-NOT: bb{{[0-9]+}}: +CHECK: %pgocount = load i64, i64* getelementptr inbounds +CHECK-SAME: * @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called, + +CHECK: declare void @llvm.instrprof.increment(i8*, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]] + +WINDOWS: define linkonce_odr hidden i32 @__llvm_profile_runtime_user() #[[LLVM_PROFILE_RUNTIME_USER_ATTR:[0-9]+]] comdat { +WINDOWS-NEXT: %1 = load i32, i32* @__llvm_profile_runtime +WINDOWS-NEXT: ret i32 %1 +WINDOWS-NEXT: } + +CHECK: attributes #[[LLVM_INSTRPROF_INCREMENT_ATTR]] = { nounwind } +WINDOWS: attributes #[[LLVM_PROFILE_RUNTIME_USER_ATTR]] = { noinline } diff --git a/src/test/run-make-fulldeps/instrument-coverage/testprog.rs b/src/test/run-make-fulldeps/instrument-coverage-llvm-ir-base/testprog.rs index 358c25677ae..358c25677ae 100644 --- a/src/test/run-make-fulldeps/instrument-coverage/testprog.rs +++ b/src/test/run-make-fulldeps/instrument-coverage-llvm-ir-base/testprog.rs diff --git a/src/test/run-make-fulldeps/instrument-coverage-llvm-ir-link-dead-code/Makefile b/src/test/run-make-fulldeps/instrument-coverage-llvm-ir-link-dead-code/Makefile new file mode 100644 index 00000000000..ba2126a6b3f --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-llvm-ir-link-dead-code/Makefile @@ -0,0 +1,11 @@ +# needs-profiler-support +# ignore-msvc + +# LINK_DEAD_CODE requires ignore-msvc due to Issue #76038 +LINK_DEAD_CODE=yes + +-include ../instrument-coverage-llvm-ir-base/Makefile + +# ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and +# `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw`. +# See ../instrument-coverage/coverage_tools.mk for more information. \ No newline at end of file diff --git a/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-base/Makefile b/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-base/Makefile new file mode 100644 index 00000000000..5cd425979ea --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-base/Makefile @@ -0,0 +1,42 @@ +# needs-profiler-support + +# ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and +# `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw`. +# See ../instrument-coverage/coverage_tools.mk for more information. + +-include ../instrument-coverage/coverage_tools.mk + +SOURCEDIR=../instrument-coverage + +all: $(patsubst $(SOURCEDIR)/%.rs,%,$(wildcard $(SOURCEDIR)/*.rs)) + +# Ensure there are no `expected` results for tests that may have been removed or renamed +.PHONY: clear_expected_if_blessed +clear_expected_if_blessed: +ifdef RUSTC_BLESS_TEST + rm -rf expected_mir_dump.*/ +endif + +-include clear_expected_if_blessed + +%: $(SOURCEDIR)/%.rs + # Compile the test program with "experimental" coverage instrumentation and generate relevant MIR. + # + # FIXME(richkadel): `-Zexperimental-coverage` to `-Zinstrument-coverage` once we are + # satisfied with the branch-level instrumentation. + $(RUSTC) $(SOURCEDIR)/$@.rs \ + -Zexperimental-coverage \ + -Clink-dead-code=$(LINK_DEAD_CODE) \ + -Zdump-mir=InstrumentCoverage \ + -Zdump-mir-dir="$(TMPDIR)"/mir_dump.$@ + +ifdef RUSTC_BLESS_TEST + mkdir -p expected_mir_dump.$@ + cp "$(TMPDIR)"/mir_dump.$@/*InstrumentCoverage.0.html expected_mir_dump.$@/ +else + # Check that the selected `mir_dump` files match what we expect (`--bless` refreshes `expected`) + mkdir -p "$(TMPDIR)"/actual_mir_dump.$@ + rm -f "$(TMPDIR)"/actual_mir_dump.$@/* + cp "$(TMPDIR)"/mir_dump.$@/*InstrumentCoverage.0.html "$(TMPDIR)"/actual_mir_dump.$@/ + $(DIFF) -r expected_mir_dump.$@/ "$(TMPDIR)"/actual_mir_dump.$@/ +endif diff --git a/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-base/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-base/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..faa5d65e7e7 --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-base/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,583 @@ +<!DOCTYPE html> +<html> +<head> + <title>coverage_of_if_else - Code Regions</title> + <style> + .line { + counter-increment: line; + } + .line:before { + content: counter(line) ": "; + font-family: Menlo, Monaco, monospace; + font-style: italic; + width: 3.8em; + display: inline-block; + text-align: right; + filter: opacity(50%); + -webkit-user-select: none; + } + .code { + color: #dddddd; + background-color: #222222; + font-family: Menlo, Monaco, monospace; + line-height: 1.4em; + border-bottom: 2px solid #222222; + white-space: pre; + display: inline-block; + } + .odd { + background-color: #55bbff; + color: #223311; + } + .even { + background-color: #ee7756; + color: #551133; + } + .code { + --index: calc(var(--layer) - 1); + padding-top: calc(var(--index) * 0.15em); + filter: + hue-rotate(calc(var(--index) * 25deg)) + saturate(calc(100% - (var(--index) * 2%))) + brightness(calc(100% - (var(--index) * 1.5%))); + } + .annotation { + color: #4444ff; + font-family: monospace; + font-style: italic; + display: none; + -webkit-user-select: none; + } + body:active .annotation { + /* requires holding mouse down anywhere on the page */ + display: inline-block; + } + span:hover .annotation { + /* requires hover over a span ONLY on its first line */ + display: inline-block; + } + </style> +</head> +<body> +<div class="code" style="counter-reset: line 2"><span class="line"><span class="code" style="--layer: 0">fn main() {</span></span> +<span class="line"><span class="code" style="--layer: 0"> let mut countdown = 0;</span></span> +<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code even" style="--layer: 1" title="bb2: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6: + 5:5-7:6: FalseEdge: falseEdge -> [real: bb4, imaginary: bb3]"><span class="annotation">@2</span></span></span><span class="code even" style="--layer: 2" title="bb4: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6: + 6:9-6:23: Assign: _1 = const 10_i32 + 5:13-7:6: Assign: _2 = const () + 5:5-7:6: Goto: goto -> bb5"><span class="annotation">@4</span></span><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6: + 5:5-7:6: Assign: _2 = const () + 5:5-7:6: Goto: goto -> bb5"><span class="annotation">@3:</span> if </span><span class="code even" style="--layer: 4" title="bb0: ../instrument-coverage/coverage_of_if_else.rs:5:8: 5:12: + 4:9-4:22: StorageLive: StorageLive(_1) + 4:25-4:26: Assign: _1 = const 0_i32 + 4:9-4:22: FakeRead: FakeRead(ForLet, _1) + 5:5-7:6: StorageLive: StorageLive(_2) + 5:8-5:12: StorageLive: StorageLive(_3) + 5:8-5:12: Assign: _3 = const true + 5:8-5:12: FakeRead: FakeRead(ForMatchedPlace, _3) + 5:5-7:6: SwitchInt: switchInt(_3) -> [false: bb3, otherwise: bb2]"><span class="annotation">@0:</span> true</span><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6: + 5:5-7:6: Assign: _2 = const () + 5:5-7:6: Goto: goto -> bb5"><span class="annotation">@3:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6: + 5:5-7:6: Assign: _2 = const () + 5:5-7:6: Goto: goto -> bb5"> countdown = 10;</span></span> +<span class="line"><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6: + 5:5-7:6: Assign: _2 = const () + 5:5-7:6: Goto: goto -> bb5"> }</span><span class="code" style="--layer: 0"></span></span> +<span class="line"><span class="code" style="--layer: 0"></span></span> +<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code even" style="--layer: 1" title="bb6: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 9:5-18:6: FalseEdge: falseEdge -> [real: bb8, imaginary: bb7]"><span class="annotation">@6</span></span></span><span class="code even" style="--layer: 2" title="bb9: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 10:9-10:23: Assign: _1 = move (_7.0: i32) + 9:22-11:6: Assign: _4 = const () + 9:5-18:6: Goto: goto -> bb28"><span class="annotation">@9</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 15:9-15:23: Assign: _1 = move (_19.0: i32) + 11:29-16:6: Assign: _4 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 9:5-18:6: Goto: goto -> bb28"><span class="annotation">@25:</span> if </span><span class="code even" style="--layer: 4" title="bb5: ../instrument-coverage/coverage_of_if_else.rs:9:8: 9:21: + 7:5-7:6: StorageDead: StorageDead(_3) + 7:5-7:6: StorageDead: StorageDead(_2) + 9:5-18:6: StorageLive: StorageLive(_4) + 9:8-9:21: StorageLive: StorageLive(_5) + 9:8-9:17: StorageLive: StorageLive(_6) + 9:8-9:17: Assign: _6 = _1 + 9:8-9:21: Assign: _5 = Gt(move _6, const 7_i32) + 9:20-9:21: StorageDead: StorageDead(_6) + 9:8-9:21: FakeRead: FakeRead(ForMatchedPlace, _5) + 9:5-18:6: SwitchInt: switchInt(_5) -> [false: bb7, otherwise: bb6]"><span class="annotation">@5:</span> countdown > 7</span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 15:9-15:23: Assign: _1 = move (_19.0: i32) + 11:29-16:6: Assign: _4 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 9:5-18:6: Goto: goto -> bb28"><span class="annotation">@25:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 15:9-15:23: Assign: _1 = move (_19.0: i32) + 11:29-16:6: Assign: _4 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 9:5-18:6: Goto: goto -> bb28"> </span><span class="code odd" style="--layer: 4" title="bb8: ../instrument-coverage/coverage_of_if_else.rs:10:9: 10:23: + 10:9-10:23: Assign: _7 = CheckedSub(_1, const 4_i32) + 10:9-10:23: Assert: assert(!move (_7.1: bool), "attempt to compute `{} - {}` which would overflow", _1, const 4_i32) -> [success: bb9, unwind: bb1]"><span class="annotation">@8:</span> countdown -= 4</span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 15:9-15:23: Assign: _1 = move (_19.0: i32) + 11:29-16:6: Assign: _4 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 9:5-18:6: Goto: goto -> bb28"><span class="annotation">@25:</span> ;</span></span> +<span class="line"><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 15:9-15:23: Assign: _1 = move (_19.0: i32) + 11:29-16:6: Assign: _4 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 9:5-18:6: Goto: goto -> bb28"> } else </span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6: + 11:12-18:6: FalseEdge: falseEdge -> [real: bb12, imaginary: bb11]"><span class="annotation">@10:</span> if </span><span class="code even" style="--layer: 5" title="bb7: ../instrument-coverage/coverage_of_if_else.rs:11:15: 11:28: + 11:15-11:28: StorageLive: StorageLive(_8) + 11:15-11:24: StorageLive: StorageLive(_9) + 11:15-11:24: Assign: _9 = _1 + 11:15-11:28: Assign: _8 = Gt(move _9, const 2_i32) + 11:27-11:28: StorageDead: StorageDead(_9) + 11:15-11:28: FakeRead: FakeRead(ForMatchedPlace, _8) + 11:12-18:6: SwitchInt: switchInt(_8) -> [false: bb11, otherwise: bb10]"><span class="annotation">@7:</span> countdown > 2</span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6: + 11:12-18:6: FalseEdge: falseEdge -> [real: bb12, imaginary: bb11]"><span class="annotation">@10:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6: + 11:12-18:6: FalseEdge: falseEdge -> [real: bb12, imaginary: bb11]"> </span><span class="code odd" style="--layer: 5" title="bb22: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10: + 12:9-14:10: Assign: _10 = const () + 12:9-14:10: Goto: goto -> bb24"><span class="annotation">@22</span></span><span class="code even" style="--layer: 6" title="bb23: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10: + 13:13-13:26: Assign: _1 = const 0_i32 + 12:61-14:10: Assign: _10 = const () + 12:9-14:10: Goto: goto -> bb24"><span class="annotation">@23</span></span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10: + 12:9-14:10: FalseEdge: falseEdge -> [real: bb23, imaginary: bb22]"><span class="annotation">@21:</span> if </span><span class="code even" style="--layer: 8" title="bb14: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:12-12:60: Assign: _11 = const false + 12:12-12:60: Goto: goto -> bb16"><span class="annotation">@14</span></span><span class="code even" style="--layer: 9" title="bb15: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:46-12:60: StorageLive: StorageLive(_17) + 12:46-12:55: StorageLive: StorageLive(_18) + 12:46-12:55: Assign: _18 = _1 + 12:46-12:60: Assign: _17 = Ne(move _18, const 9_i32) + 12:59-12:60: StorageDead: StorageDead(_18) + 12:12-12:60: SwitchInt: switchInt(move _17) -> [false: bb14, otherwise: bb13]"><span class="annotation">@15</span></span><span class="code even" style="--layer: 10" title="bb16: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:59-12:60: StorageDead: StorageDead(_17) + 12:59-12:60: StorageDead: StorageDead(_12) + 12:12-12:60: FakeRead: FakeRead(ForMatchedPlace, _11) + 12:9-14:10: SwitchInt: switchInt(_11) -> [false: bb22, otherwise: bb21]"><span class="annotation">@16</span></span><span class="code even" style="--layer: 11" title="bb13: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:12-12:60: Assign: _11 = const true + 12:12-12:60: Goto: goto -> bb16"><span class="annotation">@13</span></span><span class="code even" style="--layer: 12" title="bb20: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:41-12:42: StorageDead: StorageDead(_15) + 12:41-12:42: StorageDead: StorageDead(_13) + 12:12-12:60: SwitchInt: switchInt(move _12) -> [false: bb15, otherwise: bb13]"><span class="annotation">@20</span></span><span class="code even" style="--layer: 13" title="bb12: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:9-14:10: StorageLive: StorageLive(_10) + 12:12-12:60: StorageLive: StorageLive(_11) + 12:12-12:42: StorageLive: StorageLive(_12) + 12:12-12:25: StorageLive: StorageLive(_13) + 12:12-12:21: StorageLive: StorageLive(_14) + 12:12-12:21: Assign: _14 = _1 + 12:12-12:25: Assign: _13 = Lt(move _14, const 1_i32) + 12:24-12:25: StorageDead: StorageDead(_14) + 12:12-12:42: SwitchInt: switchInt(move _13) -> [false: bb19, otherwise: bb17]"><span class="annotation">@12</span></span><span class="code even" style="--layer: 14" title="bb18: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42: + 12:12-12:42: Assign: _12 = const false + 12:12-12:42: Goto: goto -> bb20"><span class="annotation">@18</span></span><span class="code even" style="--layer: 15" title="bb19: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42: + 12:29-12:42: StorageLive: StorageLive(_15) + 12:29-12:38: StorageLive: StorageLive(_16) + 12:29-12:38: Assign: _16 = _1 + 12:29-12:42: Assign: _15 = Gt(move _16, const 5_i32) + 12:41-12:42: StorageDead: StorageDead(_16) + 12:12-12:42: SwitchInt: switchInt(move _15) -> [false: bb18, otherwise: bb17]"><span class="annotation">@19</span></span><span class="code even" style="--layer: 16" title="bb17: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42: + 12:12-12:42: Assign: _12 = const true + 12:12-12:42: Goto: goto -> bb20"><span class="annotation">@17:</span> countdown < 1 || countdown > 5</span><span class="code even" style="--layer: 13" title="bb12: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:9-14:10: StorageLive: StorageLive(_10) + 12:12-12:60: StorageLive: StorageLive(_11) + 12:12-12:42: StorageLive: StorageLive(_12) + 12:12-12:25: StorageLive: StorageLive(_13) + 12:12-12:21: StorageLive: StorageLive(_14) + 12:12-12:21: Assign: _14 = _1 + 12:12-12:25: Assign: _13 = Lt(move _14, const 1_i32) + 12:24-12:25: StorageDead: StorageDead(_14) + 12:12-12:42: SwitchInt: switchInt(move _13) -> [false: bb19, otherwise: bb17]"><span class="annotation">@12:</span> || countdown != 9</span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10: + 12:9-14:10: FalseEdge: falseEdge -> [real: bb23, imaginary: bb22]"><span class="annotation">@21:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10: + 12:9-14:10: FalseEdge: falseEdge -> [real: bb23, imaginary: bb22]"> countdown = 0;</span></span> +<span class="line"><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10: + 12:9-14:10: FalseEdge: falseEdge -> [real: bb23, imaginary: bb22]"> </span><span class="code odd" style="--layer: 8" title="bb24: ../instrument-coverage/coverage_of_if_else.rs:14:9: 15:23: + 14:9-14:10: StorageDead: StorageDead(_11) + 14:9-14:10: StorageDead: StorageDead(_10) + 15:9-15:23: Assign: _19 = CheckedSub(_1, const 5_i32) + 15:9-15:23: Assert: assert(!move (_19.1: bool), "attempt to compute `{} - {}` which would overflow", _1, const 5_i32) -> [success: bb25, unwind: bb1]"><span class="annotation">@24:</span> }</span></span> +<span class="line"><span class="code odd" style="--layer: 8" title="bb24: ../instrument-coverage/coverage_of_if_else.rs:14:9: 15:23: + 14:9-14:10: StorageDead: StorageDead(_11) + 14:9-14:10: StorageDead: StorageDead(_10) + 15:9-15:23: Assign: _19 = CheckedSub(_1, const 5_i32) + 15:9-15:23: Assert: assert(!move (_19.1: bool), "attempt to compute `{} - {}` which would overflow", _1, const 5_i32) -> [success: bb25, unwind: bb1]"> countdown -= 5</span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6: + 11:12-18:6: FalseEdge: falseEdge -> [real: bb12, imaginary: bb11]"><span class="annotation">@10:</span> ;</span></span> +<span class="line"><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6: + 11:12-18:6: FalseEdge: falseEdge -> [real: bb12, imaginary: bb11]"> } else {</span></span> +<span class="line"><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6: + 11:12-18:6: FalseEdge: falseEdge -> [real: bb12, imaginary: bb11]"> </span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"><span class="annotation">@27</span></span><span class="code even" style="--layer: 6" title="bb11: ../instrument-coverage/coverage_of_if_else.rs:17:9: 18:6: + 17:9-17:15: Assign: _0 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 18:5-18:6: StorageDead: StorageDead(_5) + 18:5-18:6: StorageDead: StorageDead(_4) + 17:9-17:15: Goto: goto -> bb27"><span class="annotation">@11:</span> return;</span></span> +<span class="line"><span class="code even" style="--layer: 6" title="bb11: ../instrument-coverage/coverage_of_if_else.rs:17:9: 18:6: + 17:9-17:15: Assign: _0 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 18:5-18:6: StorageDead: StorageDead(_5) + 18:5-18:6: StorageDead: StorageDead(_4) + 17:9-17:15: Goto: goto -> bb27"> }</span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"><span class="annotation">@27:</span> </span></span> +<span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"></span></span> +<span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"> let mut countdown = 0;</span></span> +<span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"> </span><span class="code odd" style="--layer: 6" title="bb30: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6: + 21:5-23:6: Assign: _22 = const () + 21:5-23:6: Goto: goto -> bb32"><span class="annotation">@30</span></span><span class="code even" style="--layer: 7" title="bb31: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6: + 22:9-22:23: Assign: _21 = const 10_i32 + 21:13-23:6: Assign: _22 = const () + 21:5-23:6: Goto: goto -> bb32"><span class="annotation">@31</span></span><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6: + 21:5-23:6: FalseEdge: falseEdge -> [real: bb31, imaginary: bb30]"><span class="annotation">@29:</span> if </span><span class="code even" style="--layer: 9" title="bb28: ../instrument-coverage/coverage_of_if_else.rs:21:8: 21:12: + 18:5-18:6: StorageDead: StorageDead(_5) + 18:5-18:6: StorageDead: StorageDead(_4) + 20:9-20:22: StorageLive: StorageLive(_21) + 20:25-20:26: Assign: _21 = const 0_i32 + 20:9-20:22: FakeRead: FakeRead(ForLet, _21) + 21:5-23:6: StorageLive: StorageLive(_22) + 21:8-21:12: StorageLive: StorageLive(_23) + 21:8-21:12: Assign: _23 = const true + 21:8-21:12: FakeRead: FakeRead(ForMatchedPlace, _23) + 21:5-23:6: SwitchInt: switchInt(_23) -> [false: bb30, otherwise: bb29]"><span class="annotation">@28:</span> true</span><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6: + 21:5-23:6: FalseEdge: falseEdge -> [real: bb31, imaginary: bb30]"><span class="annotation">@29:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6: + 21:5-23:6: FalseEdge: falseEdge -> [real: bb31, imaginary: bb30]"> countdown = 10;</span></span> +<span class="line"><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6: + 21:5-23:6: FalseEdge: falseEdge -> [real: bb31, imaginary: bb30]"> }</span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"><span class="annotation">@27:</span> </span></span> +<span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"></span></span> +<span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"> </span><span class="code even" style="--layer: 6" title="bb33: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 25:5-34:6: FalseEdge: falseEdge -> [real: bb35, imaginary: bb34]"><span class="annotation">@33</span></span><span class="code even" style="--layer: 7" title="bb52: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 31:9-31:23: Assign: _21 = move (_39.0: i32) + 27:29-32:6: Assign: _24 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 25:5-34:6: Goto: goto -> bb53"><span class="annotation">@52</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 26:9-26:23: Assign: _21 = move (_27.0: i32) + 25:22-27:6: Assign: _24 = const () + 25:5-34:6: Goto: goto -> bb53"><span class="annotation">@36:</span> if </span><span class="code even" style="--layer: 9" title="bb32: ../instrument-coverage/coverage_of_if_else.rs:25:8: 25:21: + 23:5-23:6: StorageDead: StorageDead(_23) + 23:5-23:6: StorageDead: StorageDead(_22) + 25:5-34:6: StorageLive: StorageLive(_24) + 25:8-25:21: StorageLive: StorageLive(_25) + 25:8-25:17: StorageLive: StorageLive(_26) + 25:8-25:17: Assign: _26 = _21 + 25:8-25:21: Assign: _25 = Gt(move _26, const 7_i32) + 25:20-25:21: StorageDead: StorageDead(_26) + 25:8-25:21: FakeRead: FakeRead(ForMatchedPlace, _25) + 25:5-34:6: SwitchInt: switchInt(_25) -> [false: bb34, otherwise: bb33]"><span class="annotation">@32:</span> countdown > 7</span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 26:9-26:23: Assign: _21 = move (_27.0: i32) + 25:22-27:6: Assign: _24 = const () + 25:5-34:6: Goto: goto -> bb53"><span class="annotation">@36:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 26:9-26:23: Assign: _21 = move (_27.0: i32) + 25:22-27:6: Assign: _24 = const () + 25:5-34:6: Goto: goto -> bb53"> </span><span class="code odd" style="--layer: 9" title="bb35: ../instrument-coverage/coverage_of_if_else.rs:26:9: 26:23: + 26:9-26:23: Assign: _27 = CheckedSub(_21, const 4_i32) + 26:9-26:23: Assert: assert(!move (_27.1: bool), "attempt to compute `{} - {}` which would overflow", _21, const 4_i32) -> [success: bb36, unwind: bb1]"><span class="annotation">@35:</span> countdown -= 4</span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 26:9-26:23: Assign: _21 = move (_27.0: i32) + 25:22-27:6: Assign: _24 = const () + 25:5-34:6: Goto: goto -> bb53"><span class="annotation">@36:</span> ;</span></span> +<span class="line"><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 26:9-26:23: Assign: _21 = move (_27.0: i32) + 25:22-27:6: Assign: _24 = const () + 25:5-34:6: Goto: goto -> bb53"> } else </span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6: + 27:12-34:6: FalseEdge: falseEdge -> [real: bb39, imaginary: bb38]"><span class="annotation">@37:</span> if </span><span class="code even" style="--layer: 10" title="bb34: ../instrument-coverage/coverage_of_if_else.rs:27:15: 27:28: + 27:15-27:28: StorageLive: StorageLive(_28) + 27:15-27:24: StorageLive: StorageLive(_29) + 27:15-27:24: Assign: _29 = _21 + 27:15-27:28: Assign: _28 = Gt(move _29, const 2_i32) + 27:27-27:28: StorageDead: StorageDead(_29) + 27:15-27:28: FakeRead: FakeRead(ForMatchedPlace, _28) + 27:12-34:6: SwitchInt: switchInt(_28) -> [false: bb38, otherwise: bb37]"><span class="annotation">@34:</span> countdown > 2</span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6: + 27:12-34:6: FalseEdge: falseEdge -> [real: bb39, imaginary: bb38]"><span class="annotation">@37:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6: + 27:12-34:6: FalseEdge: falseEdge -> [real: bb39, imaginary: bb38]"> </span><span class="code odd" style="--layer: 10" title="bb48: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10: + 28:9-30:10: FalseEdge: falseEdge -> [real: bb50, imaginary: bb49]"><span class="annotation">@48</span></span><span class="code even" style="--layer: 11" title="bb50: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10: + 29:13-29:26: Assign: _21 = const 0_i32 + 28:61-30:10: Assign: _30 = const () + 28:9-30:10: Goto: goto -> bb51"><span class="annotation">@50</span></span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10: + 28:9-30:10: Assign: _30 = const () + 28:9-30:10: Goto: goto -> bb51"><span class="annotation">@49:</span> if </span><span class="code even" style="--layer: 13" title="bb39: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:9-30:10: StorageLive: StorageLive(_30) + 28:12-28:60: StorageLive: StorageLive(_31) + 28:12-28:42: StorageLive: StorageLive(_32) + 28:12-28:25: StorageLive: StorageLive(_33) + 28:12-28:21: StorageLive: StorageLive(_34) + 28:12-28:21: Assign: _34 = _21 + 28:12-28:25: Assign: _33 = Lt(move _34, const 1_i32) + 28:24-28:25: StorageDead: StorageDead(_34) + 28:12-28:42: SwitchInt: switchInt(move _33) -> [false: bb46, otherwise: bb44]"><span class="annotation">@39</span></span><span class="code even" style="--layer: 14" title="bb47: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:41-28:42: StorageDead: StorageDead(_35) + 28:41-28:42: StorageDead: StorageDead(_33) + 28:12-28:60: SwitchInt: switchInt(move _32) -> [false: bb42, otherwise: bb40]"><span class="annotation">@47</span></span><span class="code even" style="--layer: 15" title="bb40: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:12-28:60: Assign: _31 = const true + 28:12-28:60: Goto: goto -> bb43"><span class="annotation">@40</span></span><span class="code even" style="--layer: 16" title="bb43: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:59-28:60: StorageDead: StorageDead(_37) + 28:59-28:60: StorageDead: StorageDead(_32) + 28:12-28:60: FakeRead: FakeRead(ForMatchedPlace, _31) + 28:9-30:10: SwitchInt: switchInt(_31) -> [false: bb49, otherwise: bb48]"><span class="annotation">@43</span></span><span class="code even" style="--layer: 17" title="bb42: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:46-28:60: StorageLive: StorageLive(_37) + 28:46-28:55: StorageLive: StorageLive(_38) + 28:46-28:55: Assign: _38 = _21 + 28:46-28:60: Assign: _37 = Ne(move _38, const 9_i32) + 28:59-28:60: StorageDead: StorageDead(_38) + 28:12-28:60: SwitchInt: switchInt(move _37) -> [false: bb41, otherwise: bb40]"><span class="annotation">@42</span></span><span class="code even" style="--layer: 18" title="bb41: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:12-28:60: Assign: _31 = const false + 28:12-28:60: Goto: goto -> bb43"><span class="annotation">@41</span></span><span class="code even" style="--layer: 19" title="bb46: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42: + 28:29-28:42: StorageLive: StorageLive(_35) + 28:29-28:38: StorageLive: StorageLive(_36) + 28:29-28:38: Assign: _36 = _21 + 28:29-28:42: Assign: _35 = Gt(move _36, const 5_i32) + 28:41-28:42: StorageDead: StorageDead(_36) + 28:12-28:42: SwitchInt: switchInt(move _35) -> [false: bb45, otherwise: bb44]"><span class="annotation">@46</span></span><span class="code even" style="--layer: 20" title="bb45: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42: + 28:12-28:42: Assign: _32 = const false + 28:12-28:42: Goto: goto -> bb47"><span class="annotation">@45</span></span><span class="code even" style="--layer: 21" title="bb44: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42: + 28:12-28:42: Assign: _32 = const true + 28:12-28:42: Goto: goto -> bb47"><span class="annotation">@44:</span> countdown < 1 || countdown > 5</span><span class="code even" style="--layer: 18" title="bb41: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:12-28:60: Assign: _31 = const false + 28:12-28:60: Goto: goto -> bb43"><span class="annotation">@41:</span> || countdown != 9</span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10: + 28:9-30:10: Assign: _30 = const () + 28:9-30:10: Goto: goto -> bb51"><span class="annotation">@49:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10: + 28:9-30:10: Assign: _30 = const () + 28:9-30:10: Goto: goto -> bb51"> countdown = 0;</span></span> +<span class="line"><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10: + 28:9-30:10: Assign: _30 = const () + 28:9-30:10: Goto: goto -> bb51"> </span><span class="code odd" style="--layer: 13" title="bb51: ../instrument-coverage/coverage_of_if_else.rs:30:9: 31:23: + 30:9-30:10: StorageDead: StorageDead(_31) + 30:9-30:10: StorageDead: StorageDead(_30) + 31:9-31:23: Assign: _39 = CheckedSub(_21, const 5_i32) + 31:9-31:23: Assert: assert(!move (_39.1: bool), "attempt to compute `{} - {}` which would overflow", _21, const 5_i32) -> [success: bb52, unwind: bb1]"><span class="annotation">@51:</span> }</span></span> +<span class="line"><span class="code odd" style="--layer: 13" title="bb51: ../instrument-coverage/coverage_of_if_else.rs:30:9: 31:23: + 30:9-30:10: StorageDead: StorageDead(_31) + 30:9-30:10: StorageDead: StorageDead(_30) + 31:9-31:23: Assign: _39 = CheckedSub(_21, const 5_i32) + 31:9-31:23: Assert: assert(!move (_39.1: bool), "attempt to compute `{} - {}` which would overflow", _21, const 5_i32) -> [success: bb52, unwind: bb1]"> countdown -= 5</span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6: + 27:12-34:6: FalseEdge: falseEdge -> [real: bb39, imaginary: bb38]"><span class="annotation">@37:</span> ;</span></span> +<span class="line"><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6: + 27:12-34:6: FalseEdge: falseEdge -> [real: bb39, imaginary: bb38]"> } else {</span></span> +<span class="line"><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6: + 27:12-34:6: FalseEdge: falseEdge -> [real: bb39, imaginary: bb38]"> </span><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"><span class="annotation">@38:</span> return;</span></span> +<span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"> }</span></span> +<span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"></span></span> +<span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"> let mut countdown = 0;</span></span> +<span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"> </span><span class="code even" style="--layer: 11" title="bb56: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6: + 38:9-38:23: Assign: _41 = const 10_i32 + 37:13-39:6: Assign: _42 = const () + 37:5-39:6: Goto: goto -> bb57"><span class="annotation">@56</span></span><span class="code even" style="--layer: 12" title="bb54: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6: + 37:5-39:6: FalseEdge: falseEdge -> [real: bb56, imaginary: bb55]"><span class="annotation">@54</span></span><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6: + 37:5-39:6: Assign: _42 = const () + 37:5-39:6: Goto: goto -> bb57"><span class="annotation">@55:</span> if </span><span class="code even" style="--layer: 14" title="bb53: ../instrument-coverage/coverage_of_if_else.rs:37:8: 37:12: + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 36:9-36:22: StorageLive: StorageLive(_41) + 36:25-36:26: Assign: _41 = const 0_i32 + 36:9-36:22: FakeRead: FakeRead(ForLet, _41) + 37:5-39:6: StorageLive: StorageLive(_42) + 37:8-37:12: StorageLive: StorageLive(_43) + 37:8-37:12: Assign: _43 = const true + 37:8-37:12: FakeRead: FakeRead(ForMatchedPlace, _43) + 37:5-39:6: SwitchInt: switchInt(_43) -> [false: bb55, otherwise: bb54]"><span class="annotation">@53:</span> true</span><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6: + 37:5-39:6: Assign: _42 = const () + 37:5-39:6: Goto: goto -> bb57"><span class="annotation">@55:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6: + 37:5-39:6: Assign: _42 = const () + 37:5-39:6: Goto: goto -> bb57"> countdown = 10;</span></span> +<span class="line"><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6: + 37:5-39:6: Assign: _42 = const () + 37:5-39:6: Goto: goto -> bb57"> }</span><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"><span class="annotation">@38:</span> </span></span> +<span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"></span></span> +<span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"> </span><span class="code odd" style="--layer: 11" title="bb61: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 42:9-42:23: Assign: _41 = move (_46.0: i32) + 41:22-43:6: Assign: _0 = const () + 41:5-50:6: Goto: goto -> bb78"><span class="annotation">@61</span></span><span class="code even" style="--layer: 12" title="bb58: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 41:5-50:6: FalseEdge: falseEdge -> [real: bb60, imaginary: bb59]"><span class="annotation">@58</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 47:9-47:23: Assign: _41 = move (_58.0: i32) + 43:29-48:6: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 41:5-50:6: Goto: goto -> bb78"><span class="annotation">@77:</span> if </span><span class="code even" style="--layer: 14" title="bb57: ../instrument-coverage/coverage_of_if_else.rs:41:8: 41:21: + 39:5-39:6: StorageDead: StorageDead(_43) + 39:5-39:6: StorageDead: StorageDead(_42) + 41:8-41:21: StorageLive: StorageLive(_44) + 41:8-41:17: StorageLive: StorageLive(_45) + 41:8-41:17: Assign: _45 = _41 + 41:8-41:21: Assign: _44 = Gt(move _45, const 7_i32) + 41:20-41:21: StorageDead: StorageDead(_45) + 41:8-41:21: FakeRead: FakeRead(ForMatchedPlace, _44) + 41:5-50:6: SwitchInt: switchInt(_44) -> [false: bb59, otherwise: bb58]"><span class="annotation">@57:</span> countdown > 7</span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 47:9-47:23: Assign: _41 = move (_58.0: i32) + 43:29-48:6: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 41:5-50:6: Goto: goto -> bb78"><span class="annotation">@77:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 47:9-47:23: Assign: _41 = move (_58.0: i32) + 43:29-48:6: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 41:5-50:6: Goto: goto -> bb78"> </span><span class="code odd" style="--layer: 14" title="bb60: ../instrument-coverage/coverage_of_if_else.rs:42:9: 42:23: + 42:9-42:23: Assign: _46 = CheckedSub(_41, const 4_i32) + 42:9-42:23: Assert: assert(!move (_46.1: bool), "attempt to compute `{} - {}` which would overflow", _41, const 4_i32) -> [success: bb61, unwind: bb1]"><span class="annotation">@60:</span> countdown -= 4</span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 47:9-47:23: Assign: _41 = move (_58.0: i32) + 43:29-48:6: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 41:5-50:6: Goto: goto -> bb78"><span class="annotation">@77:</span> ;</span></span> +<span class="line"><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 47:9-47:23: Assign: _41 = move (_58.0: i32) + 43:29-48:6: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 41:5-50:6: Goto: goto -> bb78"> } else </span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6: + 43:12-50:6: FalseEdge: falseEdge -> [real: bb64, imaginary: bb63]"><span class="annotation">@62:</span> if </span><span class="code even" style="--layer: 15" title="bb59: ../instrument-coverage/coverage_of_if_else.rs:43:15: 43:28: + 43:15-43:28: StorageLive: StorageLive(_47) + 43:15-43:24: StorageLive: StorageLive(_48) + 43:15-43:24: Assign: _48 = _41 + 43:15-43:28: Assign: _47 = Gt(move _48, const 2_i32) + 43:27-43:28: StorageDead: StorageDead(_48) + 43:15-43:28: FakeRead: FakeRead(ForMatchedPlace, _47) + 43:12-50:6: SwitchInt: switchInt(_47) -> [false: bb63, otherwise: bb62]"><span class="annotation">@59:</span> countdown > 2</span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6: + 43:12-50:6: FalseEdge: falseEdge -> [real: bb64, imaginary: bb63]"><span class="annotation">@62:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6: + 43:12-50:6: FalseEdge: falseEdge -> [real: bb64, imaginary: bb63]"> </span><span class="code odd" style="--layer: 15" title="bb75: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10: + 45:13-45:26: Assign: _41 = const 0_i32 + 44:61-46:10: Assign: _49 = const () + 44:9-46:10: Goto: goto -> bb76"><span class="annotation">@75</span></span><span class="code even" style="--layer: 16" title="bb74: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10: + 44:9-46:10: Assign: _49 = const () + 44:9-46:10: Goto: goto -> bb76"><span class="annotation">@74</span></span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10: + 44:9-46:10: FalseEdge: falseEdge -> [real: bb75, imaginary: bb74]"><span class="annotation">@73:</span> if </span><span class="code even" style="--layer: 18" title="bb67: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:46-44:60: StorageLive: StorageLive(_56) + 44:46-44:55: StorageLive: StorageLive(_57) + 44:46-44:55: Assign: _57 = _41 + 44:46-44:60: Assign: _56 = Ne(move _57, const 9_i32) + 44:59-44:60: StorageDead: StorageDead(_57) + 44:12-44:60: SwitchInt: switchInt(move _56) -> [false: bb66, otherwise: bb65]"><span class="annotation">@67</span></span><span class="code even" style="--layer: 19" title="bb68: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:59-44:60: StorageDead: StorageDead(_56) + 44:59-44:60: StorageDead: StorageDead(_51) + 44:12-44:60: FakeRead: FakeRead(ForMatchedPlace, _50) + 44:9-46:10: SwitchInt: switchInt(_50) -> [false: bb74, otherwise: bb73]"><span class="annotation">@68</span></span><span class="code even" style="--layer: 20" title="bb65: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:12-44:60: Assign: _50 = const true + 44:12-44:60: Goto: goto -> bb68"><span class="annotation">@65</span></span><span class="code even" style="--layer: 21" title="bb72: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:41-44:42: StorageDead: StorageDead(_54) + 44:41-44:42: StorageDead: StorageDead(_52) + 44:12-44:60: SwitchInt: switchInt(move _51) -> [false: bb67, otherwise: bb65]"><span class="annotation">@72</span></span><span class="code even" style="--layer: 22" title="bb64: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:9-46:10: StorageLive: StorageLive(_49) + 44:12-44:60: StorageLive: StorageLive(_50) + 44:12-44:42: StorageLive: StorageLive(_51) + 44:12-44:25: StorageLive: StorageLive(_52) + 44:12-44:21: StorageLive: StorageLive(_53) + 44:12-44:21: Assign: _53 = _41 + 44:12-44:25: Assign: _52 = Lt(move _53, const 1_i32) + 44:24-44:25: StorageDead: StorageDead(_53) + 44:12-44:42: SwitchInt: switchInt(move _52) -> [false: bb71, otherwise: bb69]"><span class="annotation">@64</span></span><span class="code even" style="--layer: 23" title="bb66: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:12-44:60: Assign: _50 = const false + 44:12-44:60: Goto: goto -> bb68"><span class="annotation">@66</span></span><span class="code even" style="--layer: 24" title="bb69: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42: + 44:12-44:42: Assign: _51 = const true + 44:12-44:42: Goto: goto -> bb72"><span class="annotation">@69</span></span><span class="code even" style="--layer: 25" title="bb71: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42: + 44:29-44:42: StorageLive: StorageLive(_54) + 44:29-44:38: StorageLive: StorageLive(_55) + 44:29-44:38: Assign: _55 = _41 + 44:29-44:42: Assign: _54 = Gt(move _55, const 5_i32) + 44:41-44:42: StorageDead: StorageDead(_55) + 44:12-44:42: SwitchInt: switchInt(move _54) -> [false: bb70, otherwise: bb69]"><span class="annotation">@71</span></span><span class="code even" style="--layer: 26" title="bb70: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42: + 44:12-44:42: Assign: _51 = const false + 44:12-44:42: Goto: goto -> bb72"><span class="annotation">@70:</span> countdown < 1 || countdown > 5</span><span class="code even" style="--layer: 23" title="bb66: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:12-44:60: Assign: _50 = const false + 44:12-44:60: Goto: goto -> bb68"><span class="annotation">@66:</span> || countdown != 9</span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10: + 44:9-46:10: FalseEdge: falseEdge -> [real: bb75, imaginary: bb74]"><span class="annotation">@73:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10: + 44:9-46:10: FalseEdge: falseEdge -> [real: bb75, imaginary: bb74]"> countdown = 0;</span></span> +<span class="line"><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10: + 44:9-46:10: FalseEdge: falseEdge -> [real: bb75, imaginary: bb74]"> </span><span class="code odd" style="--layer: 18" title="bb76: ../instrument-coverage/coverage_of_if_else.rs:46:9: 47:23: + 46:9-46:10: StorageDead: StorageDead(_50) + 46:9-46:10: StorageDead: StorageDead(_49) + 47:9-47:23: Assign: _58 = CheckedSub(_41, const 5_i32) + 47:9-47:23: Assert: assert(!move (_58.1: bool), "attempt to compute `{} - {}` which would overflow", _41, const 5_i32) -> [success: bb77, unwind: bb1]"><span class="annotation">@76:</span> }</span></span> +<span class="line"><span class="code odd" style="--layer: 18" title="bb76: ../instrument-coverage/coverage_of_if_else.rs:46:9: 47:23: + 46:9-46:10: StorageDead: StorageDead(_50) + 46:9-46:10: StorageDead: StorageDead(_49) + 47:9-47:23: Assign: _58 = CheckedSub(_41, const 5_i32) + 47:9-47:23: Assert: assert(!move (_58.1: bool), "attempt to compute `{} - {}` which would overflow", _41, const 5_i32) -> [success: bb77, unwind: bb1]"> countdown -= 5</span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6: + 43:12-50:6: FalseEdge: falseEdge -> [real: bb64, imaginary: bb63]"><span class="annotation">@62:</span> ;</span></span> +<span class="line"><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6: + 43:12-50:6: FalseEdge: falseEdge -> [real: bb64, imaginary: bb63]"> } else {</span></span> +<span class="line"><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6: + 43:12-50:6: FalseEdge: falseEdge -> [real: bb64, imaginary: bb63]"> </span><span class="code even" style="--layer: 15" title="bb63: ../instrument-coverage/coverage_of_if_else.rs:49:9: 51:2: + 49:9-49:15: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 51:1-51:2: StorageDead: StorageDead(_41) + 51:1-51:2: StorageDead: StorageDead(_21) + 51:1-51:2: StorageDead: StorageDead(_1) + 51:1-51:2: StorageDead: StorageDead(_44) + 49:9-49:15: Goto: goto -> bb26"><span class="annotation">@63:</span> return;</span></span> +<span class="line"><span class="code even" style="--layer: 15" title="bb63: ../instrument-coverage/coverage_of_if_else.rs:49:9: 51:2: + 49:9-49:15: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 51:1-51:2: StorageDead: StorageDead(_41) + 51:1-51:2: StorageDead: StorageDead(_21) + 51:1-51:2: StorageDead: StorageDead(_1) + 51:1-51:2: StorageDead: StorageDead(_44) + 49:9-49:15: Goto: goto -> bb26"> }</span><span class="code even" style="--layer: 16" title="bb78: ../instrument-coverage/coverage_of_if_else.rs:51:1: 51:2: + 51:1-51:2: StorageDead: StorageDead(_41) + 51:1-51:2: StorageDead: StorageDead(_21) + 51:1-51:2: StorageDead: StorageDead(_1) + 51:1-51:2: StorageDead: StorageDead(_44) + 51:2-51:2: Goto: goto -> bb26"><span class="annotation">@78:</span> }</span><span><span class="code even" style="--layer: 1" title="bb26: ../instrument-coverage/coverage_of_if_else.rs:51:2: 51:2: + 51:2-51:2: Return: return"><span class="annotation">@26</span></span></span></span></div> +</body> +</html> diff --git a/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-link-dead-code/Makefile b/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-link-dead-code/Makefile new file mode 100644 index 00000000000..0578949b3c8 --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-link-dead-code/Makefile @@ -0,0 +1,11 @@ +# needs-profiler-support +# ignore-msvc + +# LINK_DEAD_CODE requires ignore-msvc due to Issue #76038 +LINK_DEAD_CODE=yes + +-include ../instrument-coverage-mir-cov-html-base/Makefile + +# ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and +# `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw`. +# See ../instrument-coverage/coverage_tools.mk for more information. \ No newline at end of file diff --git a/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-link-dead-code/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-link-dead-code/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..faa5d65e7e7 --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-link-dead-code/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,583 @@ +<!DOCTYPE html> +<html> +<head> + <title>coverage_of_if_else - Code Regions</title> + <style> + .line { + counter-increment: line; + } + .line:before { + content: counter(line) ": "; + font-family: Menlo, Monaco, monospace; + font-style: italic; + width: 3.8em; + display: inline-block; + text-align: right; + filter: opacity(50%); + -webkit-user-select: none; + } + .code { + color: #dddddd; + background-color: #222222; + font-family: Menlo, Monaco, monospace; + line-height: 1.4em; + border-bottom: 2px solid #222222; + white-space: pre; + display: inline-block; + } + .odd { + background-color: #55bbff; + color: #223311; + } + .even { + background-color: #ee7756; + color: #551133; + } + .code { + --index: calc(var(--layer) - 1); + padding-top: calc(var(--index) * 0.15em); + filter: + hue-rotate(calc(var(--index) * 25deg)) + saturate(calc(100% - (var(--index) * 2%))) + brightness(calc(100% - (var(--index) * 1.5%))); + } + .annotation { + color: #4444ff; + font-family: monospace; + font-style: italic; + display: none; + -webkit-user-select: none; + } + body:active .annotation { + /* requires holding mouse down anywhere on the page */ + display: inline-block; + } + span:hover .annotation { + /* requires hover over a span ONLY on its first line */ + display: inline-block; + } + </style> +</head> +<body> +<div class="code" style="counter-reset: line 2"><span class="line"><span class="code" style="--layer: 0">fn main() {</span></span> +<span class="line"><span class="code" style="--layer: 0"> let mut countdown = 0;</span></span> +<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code even" style="--layer: 1" title="bb2: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6: + 5:5-7:6: FalseEdge: falseEdge -> [real: bb4, imaginary: bb3]"><span class="annotation">@2</span></span></span><span class="code even" style="--layer: 2" title="bb4: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6: + 6:9-6:23: Assign: _1 = const 10_i32 + 5:13-7:6: Assign: _2 = const () + 5:5-7:6: Goto: goto -> bb5"><span class="annotation">@4</span></span><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6: + 5:5-7:6: Assign: _2 = const () + 5:5-7:6: Goto: goto -> bb5"><span class="annotation">@3:</span> if </span><span class="code even" style="--layer: 4" title="bb0: ../instrument-coverage/coverage_of_if_else.rs:5:8: 5:12: + 4:9-4:22: StorageLive: StorageLive(_1) + 4:25-4:26: Assign: _1 = const 0_i32 + 4:9-4:22: FakeRead: FakeRead(ForLet, _1) + 5:5-7:6: StorageLive: StorageLive(_2) + 5:8-5:12: StorageLive: StorageLive(_3) + 5:8-5:12: Assign: _3 = const true + 5:8-5:12: FakeRead: FakeRead(ForMatchedPlace, _3) + 5:5-7:6: SwitchInt: switchInt(_3) -> [false: bb3, otherwise: bb2]"><span class="annotation">@0:</span> true</span><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6: + 5:5-7:6: Assign: _2 = const () + 5:5-7:6: Goto: goto -> bb5"><span class="annotation">@3:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6: + 5:5-7:6: Assign: _2 = const () + 5:5-7:6: Goto: goto -> bb5"> countdown = 10;</span></span> +<span class="line"><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6: + 5:5-7:6: Assign: _2 = const () + 5:5-7:6: Goto: goto -> bb5"> }</span><span class="code" style="--layer: 0"></span></span> +<span class="line"><span class="code" style="--layer: 0"></span></span> +<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code even" style="--layer: 1" title="bb6: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 9:5-18:6: FalseEdge: falseEdge -> [real: bb8, imaginary: bb7]"><span class="annotation">@6</span></span></span><span class="code even" style="--layer: 2" title="bb9: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 10:9-10:23: Assign: _1 = move (_7.0: i32) + 9:22-11:6: Assign: _4 = const () + 9:5-18:6: Goto: goto -> bb28"><span class="annotation">@9</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 15:9-15:23: Assign: _1 = move (_19.0: i32) + 11:29-16:6: Assign: _4 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 9:5-18:6: Goto: goto -> bb28"><span class="annotation">@25:</span> if </span><span class="code even" style="--layer: 4" title="bb5: ../instrument-coverage/coverage_of_if_else.rs:9:8: 9:21: + 7:5-7:6: StorageDead: StorageDead(_3) + 7:5-7:6: StorageDead: StorageDead(_2) + 9:5-18:6: StorageLive: StorageLive(_4) + 9:8-9:21: StorageLive: StorageLive(_5) + 9:8-9:17: StorageLive: StorageLive(_6) + 9:8-9:17: Assign: _6 = _1 + 9:8-9:21: Assign: _5 = Gt(move _6, const 7_i32) + 9:20-9:21: StorageDead: StorageDead(_6) + 9:8-9:21: FakeRead: FakeRead(ForMatchedPlace, _5) + 9:5-18:6: SwitchInt: switchInt(_5) -> [false: bb7, otherwise: bb6]"><span class="annotation">@5:</span> countdown > 7</span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 15:9-15:23: Assign: _1 = move (_19.0: i32) + 11:29-16:6: Assign: _4 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 9:5-18:6: Goto: goto -> bb28"><span class="annotation">@25:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 15:9-15:23: Assign: _1 = move (_19.0: i32) + 11:29-16:6: Assign: _4 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 9:5-18:6: Goto: goto -> bb28"> </span><span class="code odd" style="--layer: 4" title="bb8: ../instrument-coverage/coverage_of_if_else.rs:10:9: 10:23: + 10:9-10:23: Assign: _7 = CheckedSub(_1, const 4_i32) + 10:9-10:23: Assert: assert(!move (_7.1: bool), "attempt to compute `{} - {}` which would overflow", _1, const 4_i32) -> [success: bb9, unwind: bb1]"><span class="annotation">@8:</span> countdown -= 4</span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 15:9-15:23: Assign: _1 = move (_19.0: i32) + 11:29-16:6: Assign: _4 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 9:5-18:6: Goto: goto -> bb28"><span class="annotation">@25:</span> ;</span></span> +<span class="line"><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6: + 15:9-15:23: Assign: _1 = move (_19.0: i32) + 11:29-16:6: Assign: _4 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 9:5-18:6: Goto: goto -> bb28"> } else </span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6: + 11:12-18:6: FalseEdge: falseEdge -> [real: bb12, imaginary: bb11]"><span class="annotation">@10:</span> if </span><span class="code even" style="--layer: 5" title="bb7: ../instrument-coverage/coverage_of_if_else.rs:11:15: 11:28: + 11:15-11:28: StorageLive: StorageLive(_8) + 11:15-11:24: StorageLive: StorageLive(_9) + 11:15-11:24: Assign: _9 = _1 + 11:15-11:28: Assign: _8 = Gt(move _9, const 2_i32) + 11:27-11:28: StorageDead: StorageDead(_9) + 11:15-11:28: FakeRead: FakeRead(ForMatchedPlace, _8) + 11:12-18:6: SwitchInt: switchInt(_8) -> [false: bb11, otherwise: bb10]"><span class="annotation">@7:</span> countdown > 2</span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6: + 11:12-18:6: FalseEdge: falseEdge -> [real: bb12, imaginary: bb11]"><span class="annotation">@10:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6: + 11:12-18:6: FalseEdge: falseEdge -> [real: bb12, imaginary: bb11]"> </span><span class="code odd" style="--layer: 5" title="bb22: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10: + 12:9-14:10: Assign: _10 = const () + 12:9-14:10: Goto: goto -> bb24"><span class="annotation">@22</span></span><span class="code even" style="--layer: 6" title="bb23: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10: + 13:13-13:26: Assign: _1 = const 0_i32 + 12:61-14:10: Assign: _10 = const () + 12:9-14:10: Goto: goto -> bb24"><span class="annotation">@23</span></span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10: + 12:9-14:10: FalseEdge: falseEdge -> [real: bb23, imaginary: bb22]"><span class="annotation">@21:</span> if </span><span class="code even" style="--layer: 8" title="bb14: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:12-12:60: Assign: _11 = const false + 12:12-12:60: Goto: goto -> bb16"><span class="annotation">@14</span></span><span class="code even" style="--layer: 9" title="bb15: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:46-12:60: StorageLive: StorageLive(_17) + 12:46-12:55: StorageLive: StorageLive(_18) + 12:46-12:55: Assign: _18 = _1 + 12:46-12:60: Assign: _17 = Ne(move _18, const 9_i32) + 12:59-12:60: StorageDead: StorageDead(_18) + 12:12-12:60: SwitchInt: switchInt(move _17) -> [false: bb14, otherwise: bb13]"><span class="annotation">@15</span></span><span class="code even" style="--layer: 10" title="bb16: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:59-12:60: StorageDead: StorageDead(_17) + 12:59-12:60: StorageDead: StorageDead(_12) + 12:12-12:60: FakeRead: FakeRead(ForMatchedPlace, _11) + 12:9-14:10: SwitchInt: switchInt(_11) -> [false: bb22, otherwise: bb21]"><span class="annotation">@16</span></span><span class="code even" style="--layer: 11" title="bb13: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:12-12:60: Assign: _11 = const true + 12:12-12:60: Goto: goto -> bb16"><span class="annotation">@13</span></span><span class="code even" style="--layer: 12" title="bb20: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:41-12:42: StorageDead: StorageDead(_15) + 12:41-12:42: StorageDead: StorageDead(_13) + 12:12-12:60: SwitchInt: switchInt(move _12) -> [false: bb15, otherwise: bb13]"><span class="annotation">@20</span></span><span class="code even" style="--layer: 13" title="bb12: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:9-14:10: StorageLive: StorageLive(_10) + 12:12-12:60: StorageLive: StorageLive(_11) + 12:12-12:42: StorageLive: StorageLive(_12) + 12:12-12:25: StorageLive: StorageLive(_13) + 12:12-12:21: StorageLive: StorageLive(_14) + 12:12-12:21: Assign: _14 = _1 + 12:12-12:25: Assign: _13 = Lt(move _14, const 1_i32) + 12:24-12:25: StorageDead: StorageDead(_14) + 12:12-12:42: SwitchInt: switchInt(move _13) -> [false: bb19, otherwise: bb17]"><span class="annotation">@12</span></span><span class="code even" style="--layer: 14" title="bb18: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42: + 12:12-12:42: Assign: _12 = const false + 12:12-12:42: Goto: goto -> bb20"><span class="annotation">@18</span></span><span class="code even" style="--layer: 15" title="bb19: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42: + 12:29-12:42: StorageLive: StorageLive(_15) + 12:29-12:38: StorageLive: StorageLive(_16) + 12:29-12:38: Assign: _16 = _1 + 12:29-12:42: Assign: _15 = Gt(move _16, const 5_i32) + 12:41-12:42: StorageDead: StorageDead(_16) + 12:12-12:42: SwitchInt: switchInt(move _15) -> [false: bb18, otherwise: bb17]"><span class="annotation">@19</span></span><span class="code even" style="--layer: 16" title="bb17: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42: + 12:12-12:42: Assign: _12 = const true + 12:12-12:42: Goto: goto -> bb20"><span class="annotation">@17:</span> countdown < 1 || countdown > 5</span><span class="code even" style="--layer: 13" title="bb12: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60: + 12:9-14:10: StorageLive: StorageLive(_10) + 12:12-12:60: StorageLive: StorageLive(_11) + 12:12-12:42: StorageLive: StorageLive(_12) + 12:12-12:25: StorageLive: StorageLive(_13) + 12:12-12:21: StorageLive: StorageLive(_14) + 12:12-12:21: Assign: _14 = _1 + 12:12-12:25: Assign: _13 = Lt(move _14, const 1_i32) + 12:24-12:25: StorageDead: StorageDead(_14) + 12:12-12:42: SwitchInt: switchInt(move _13) -> [false: bb19, otherwise: bb17]"><span class="annotation">@12:</span> || countdown != 9</span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10: + 12:9-14:10: FalseEdge: falseEdge -> [real: bb23, imaginary: bb22]"><span class="annotation">@21:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10: + 12:9-14:10: FalseEdge: falseEdge -> [real: bb23, imaginary: bb22]"> countdown = 0;</span></span> +<span class="line"><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10: + 12:9-14:10: FalseEdge: falseEdge -> [real: bb23, imaginary: bb22]"> </span><span class="code odd" style="--layer: 8" title="bb24: ../instrument-coverage/coverage_of_if_else.rs:14:9: 15:23: + 14:9-14:10: StorageDead: StorageDead(_11) + 14:9-14:10: StorageDead: StorageDead(_10) + 15:9-15:23: Assign: _19 = CheckedSub(_1, const 5_i32) + 15:9-15:23: Assert: assert(!move (_19.1: bool), "attempt to compute `{} - {}` which would overflow", _1, const 5_i32) -> [success: bb25, unwind: bb1]"><span class="annotation">@24:</span> }</span></span> +<span class="line"><span class="code odd" style="--layer: 8" title="bb24: ../instrument-coverage/coverage_of_if_else.rs:14:9: 15:23: + 14:9-14:10: StorageDead: StorageDead(_11) + 14:9-14:10: StorageDead: StorageDead(_10) + 15:9-15:23: Assign: _19 = CheckedSub(_1, const 5_i32) + 15:9-15:23: Assert: assert(!move (_19.1: bool), "attempt to compute `{} - {}` which would overflow", _1, const 5_i32) -> [success: bb25, unwind: bb1]"> countdown -= 5</span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6: + 11:12-18:6: FalseEdge: falseEdge -> [real: bb12, imaginary: bb11]"><span class="annotation">@10:</span> ;</span></span> +<span class="line"><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6: + 11:12-18:6: FalseEdge: falseEdge -> [real: bb12, imaginary: bb11]"> } else {</span></span> +<span class="line"><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6: + 11:12-18:6: FalseEdge: falseEdge -> [real: bb12, imaginary: bb11]"> </span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"><span class="annotation">@27</span></span><span class="code even" style="--layer: 6" title="bb11: ../instrument-coverage/coverage_of_if_else.rs:17:9: 18:6: + 17:9-17:15: Assign: _0 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 18:5-18:6: StorageDead: StorageDead(_5) + 18:5-18:6: StorageDead: StorageDead(_4) + 17:9-17:15: Goto: goto -> bb27"><span class="annotation">@11:</span> return;</span></span> +<span class="line"><span class="code even" style="--layer: 6" title="bb11: ../instrument-coverage/coverage_of_if_else.rs:17:9: 18:6: + 17:9-17:15: Assign: _0 = const () + 18:5-18:6: StorageDead: StorageDead(_8) + 18:5-18:6: StorageDead: StorageDead(_5) + 18:5-18:6: StorageDead: StorageDead(_4) + 17:9-17:15: Goto: goto -> bb27"> }</span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"><span class="annotation">@27:</span> </span></span> +<span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"></span></span> +<span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"> let mut countdown = 0;</span></span> +<span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"> </span><span class="code odd" style="--layer: 6" title="bb30: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6: + 21:5-23:6: Assign: _22 = const () + 21:5-23:6: Goto: goto -> bb32"><span class="annotation">@30</span></span><span class="code even" style="--layer: 7" title="bb31: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6: + 22:9-22:23: Assign: _21 = const 10_i32 + 21:13-23:6: Assign: _22 = const () + 21:5-23:6: Goto: goto -> bb32"><span class="annotation">@31</span></span><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6: + 21:5-23:6: FalseEdge: falseEdge -> [real: bb31, imaginary: bb30]"><span class="annotation">@29:</span> if </span><span class="code even" style="--layer: 9" title="bb28: ../instrument-coverage/coverage_of_if_else.rs:21:8: 21:12: + 18:5-18:6: StorageDead: StorageDead(_5) + 18:5-18:6: StorageDead: StorageDead(_4) + 20:9-20:22: StorageLive: StorageLive(_21) + 20:25-20:26: Assign: _21 = const 0_i32 + 20:9-20:22: FakeRead: FakeRead(ForLet, _21) + 21:5-23:6: StorageLive: StorageLive(_22) + 21:8-21:12: StorageLive: StorageLive(_23) + 21:8-21:12: Assign: _23 = const true + 21:8-21:12: FakeRead: FakeRead(ForMatchedPlace, _23) + 21:5-23:6: SwitchInt: switchInt(_23) -> [false: bb30, otherwise: bb29]"><span class="annotation">@28:</span> true</span><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6: + 21:5-23:6: FalseEdge: falseEdge -> [real: bb31, imaginary: bb30]"><span class="annotation">@29:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6: + 21:5-23:6: FalseEdge: falseEdge -> [real: bb31, imaginary: bb30]"> countdown = 10;</span></span> +<span class="line"><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6: + 21:5-23:6: FalseEdge: falseEdge -> [real: bb31, imaginary: bb30]"> }</span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"><span class="annotation">@27:</span> </span></span> +<span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"></span></span> +<span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2: + 51:1-51:2: StorageDead: StorageDead(_1) + 17:9-17:15: Goto: goto -> bb26"> </span><span class="code even" style="--layer: 6" title="bb33: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 25:5-34:6: FalseEdge: falseEdge -> [real: bb35, imaginary: bb34]"><span class="annotation">@33</span></span><span class="code even" style="--layer: 7" title="bb52: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 31:9-31:23: Assign: _21 = move (_39.0: i32) + 27:29-32:6: Assign: _24 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 25:5-34:6: Goto: goto -> bb53"><span class="annotation">@52</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 26:9-26:23: Assign: _21 = move (_27.0: i32) + 25:22-27:6: Assign: _24 = const () + 25:5-34:6: Goto: goto -> bb53"><span class="annotation">@36:</span> if </span><span class="code even" style="--layer: 9" title="bb32: ../instrument-coverage/coverage_of_if_else.rs:25:8: 25:21: + 23:5-23:6: StorageDead: StorageDead(_23) + 23:5-23:6: StorageDead: StorageDead(_22) + 25:5-34:6: StorageLive: StorageLive(_24) + 25:8-25:21: StorageLive: StorageLive(_25) + 25:8-25:17: StorageLive: StorageLive(_26) + 25:8-25:17: Assign: _26 = _21 + 25:8-25:21: Assign: _25 = Gt(move _26, const 7_i32) + 25:20-25:21: StorageDead: StorageDead(_26) + 25:8-25:21: FakeRead: FakeRead(ForMatchedPlace, _25) + 25:5-34:6: SwitchInt: switchInt(_25) -> [false: bb34, otherwise: bb33]"><span class="annotation">@32:</span> countdown > 7</span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 26:9-26:23: Assign: _21 = move (_27.0: i32) + 25:22-27:6: Assign: _24 = const () + 25:5-34:6: Goto: goto -> bb53"><span class="annotation">@36:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 26:9-26:23: Assign: _21 = move (_27.0: i32) + 25:22-27:6: Assign: _24 = const () + 25:5-34:6: Goto: goto -> bb53"> </span><span class="code odd" style="--layer: 9" title="bb35: ../instrument-coverage/coverage_of_if_else.rs:26:9: 26:23: + 26:9-26:23: Assign: _27 = CheckedSub(_21, const 4_i32) + 26:9-26:23: Assert: assert(!move (_27.1: bool), "attempt to compute `{} - {}` which would overflow", _21, const 4_i32) -> [success: bb36, unwind: bb1]"><span class="annotation">@35:</span> countdown -= 4</span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 26:9-26:23: Assign: _21 = move (_27.0: i32) + 25:22-27:6: Assign: _24 = const () + 25:5-34:6: Goto: goto -> bb53"><span class="annotation">@36:</span> ;</span></span> +<span class="line"><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6: + 26:9-26:23: Assign: _21 = move (_27.0: i32) + 25:22-27:6: Assign: _24 = const () + 25:5-34:6: Goto: goto -> bb53"> } else </span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6: + 27:12-34:6: FalseEdge: falseEdge -> [real: bb39, imaginary: bb38]"><span class="annotation">@37:</span> if </span><span class="code even" style="--layer: 10" title="bb34: ../instrument-coverage/coverage_of_if_else.rs:27:15: 27:28: + 27:15-27:28: StorageLive: StorageLive(_28) + 27:15-27:24: StorageLive: StorageLive(_29) + 27:15-27:24: Assign: _29 = _21 + 27:15-27:28: Assign: _28 = Gt(move _29, const 2_i32) + 27:27-27:28: StorageDead: StorageDead(_29) + 27:15-27:28: FakeRead: FakeRead(ForMatchedPlace, _28) + 27:12-34:6: SwitchInt: switchInt(_28) -> [false: bb38, otherwise: bb37]"><span class="annotation">@34:</span> countdown > 2</span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6: + 27:12-34:6: FalseEdge: falseEdge -> [real: bb39, imaginary: bb38]"><span class="annotation">@37:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6: + 27:12-34:6: FalseEdge: falseEdge -> [real: bb39, imaginary: bb38]"> </span><span class="code odd" style="--layer: 10" title="bb48: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10: + 28:9-30:10: FalseEdge: falseEdge -> [real: bb50, imaginary: bb49]"><span class="annotation">@48</span></span><span class="code even" style="--layer: 11" title="bb50: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10: + 29:13-29:26: Assign: _21 = const 0_i32 + 28:61-30:10: Assign: _30 = const () + 28:9-30:10: Goto: goto -> bb51"><span class="annotation">@50</span></span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10: + 28:9-30:10: Assign: _30 = const () + 28:9-30:10: Goto: goto -> bb51"><span class="annotation">@49:</span> if </span><span class="code even" style="--layer: 13" title="bb39: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:9-30:10: StorageLive: StorageLive(_30) + 28:12-28:60: StorageLive: StorageLive(_31) + 28:12-28:42: StorageLive: StorageLive(_32) + 28:12-28:25: StorageLive: StorageLive(_33) + 28:12-28:21: StorageLive: StorageLive(_34) + 28:12-28:21: Assign: _34 = _21 + 28:12-28:25: Assign: _33 = Lt(move _34, const 1_i32) + 28:24-28:25: StorageDead: StorageDead(_34) + 28:12-28:42: SwitchInt: switchInt(move _33) -> [false: bb46, otherwise: bb44]"><span class="annotation">@39</span></span><span class="code even" style="--layer: 14" title="bb47: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:41-28:42: StorageDead: StorageDead(_35) + 28:41-28:42: StorageDead: StorageDead(_33) + 28:12-28:60: SwitchInt: switchInt(move _32) -> [false: bb42, otherwise: bb40]"><span class="annotation">@47</span></span><span class="code even" style="--layer: 15" title="bb40: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:12-28:60: Assign: _31 = const true + 28:12-28:60: Goto: goto -> bb43"><span class="annotation">@40</span></span><span class="code even" style="--layer: 16" title="bb43: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:59-28:60: StorageDead: StorageDead(_37) + 28:59-28:60: StorageDead: StorageDead(_32) + 28:12-28:60: FakeRead: FakeRead(ForMatchedPlace, _31) + 28:9-30:10: SwitchInt: switchInt(_31) -> [false: bb49, otherwise: bb48]"><span class="annotation">@43</span></span><span class="code even" style="--layer: 17" title="bb42: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:46-28:60: StorageLive: StorageLive(_37) + 28:46-28:55: StorageLive: StorageLive(_38) + 28:46-28:55: Assign: _38 = _21 + 28:46-28:60: Assign: _37 = Ne(move _38, const 9_i32) + 28:59-28:60: StorageDead: StorageDead(_38) + 28:12-28:60: SwitchInt: switchInt(move _37) -> [false: bb41, otherwise: bb40]"><span class="annotation">@42</span></span><span class="code even" style="--layer: 18" title="bb41: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:12-28:60: Assign: _31 = const false + 28:12-28:60: Goto: goto -> bb43"><span class="annotation">@41</span></span><span class="code even" style="--layer: 19" title="bb46: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42: + 28:29-28:42: StorageLive: StorageLive(_35) + 28:29-28:38: StorageLive: StorageLive(_36) + 28:29-28:38: Assign: _36 = _21 + 28:29-28:42: Assign: _35 = Gt(move _36, const 5_i32) + 28:41-28:42: StorageDead: StorageDead(_36) + 28:12-28:42: SwitchInt: switchInt(move _35) -> [false: bb45, otherwise: bb44]"><span class="annotation">@46</span></span><span class="code even" style="--layer: 20" title="bb45: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42: + 28:12-28:42: Assign: _32 = const false + 28:12-28:42: Goto: goto -> bb47"><span class="annotation">@45</span></span><span class="code even" style="--layer: 21" title="bb44: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42: + 28:12-28:42: Assign: _32 = const true + 28:12-28:42: Goto: goto -> bb47"><span class="annotation">@44:</span> countdown < 1 || countdown > 5</span><span class="code even" style="--layer: 18" title="bb41: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60: + 28:12-28:60: Assign: _31 = const false + 28:12-28:60: Goto: goto -> bb43"><span class="annotation">@41:</span> || countdown != 9</span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10: + 28:9-30:10: Assign: _30 = const () + 28:9-30:10: Goto: goto -> bb51"><span class="annotation">@49:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10: + 28:9-30:10: Assign: _30 = const () + 28:9-30:10: Goto: goto -> bb51"> countdown = 0;</span></span> +<span class="line"><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10: + 28:9-30:10: Assign: _30 = const () + 28:9-30:10: Goto: goto -> bb51"> </span><span class="code odd" style="--layer: 13" title="bb51: ../instrument-coverage/coverage_of_if_else.rs:30:9: 31:23: + 30:9-30:10: StorageDead: StorageDead(_31) + 30:9-30:10: StorageDead: StorageDead(_30) + 31:9-31:23: Assign: _39 = CheckedSub(_21, const 5_i32) + 31:9-31:23: Assert: assert(!move (_39.1: bool), "attempt to compute `{} - {}` which would overflow", _21, const 5_i32) -> [success: bb52, unwind: bb1]"><span class="annotation">@51:</span> }</span></span> +<span class="line"><span class="code odd" style="--layer: 13" title="bb51: ../instrument-coverage/coverage_of_if_else.rs:30:9: 31:23: + 30:9-30:10: StorageDead: StorageDead(_31) + 30:9-30:10: StorageDead: StorageDead(_30) + 31:9-31:23: Assign: _39 = CheckedSub(_21, const 5_i32) + 31:9-31:23: Assert: assert(!move (_39.1: bool), "attempt to compute `{} - {}` which would overflow", _21, const 5_i32) -> [success: bb52, unwind: bb1]"> countdown -= 5</span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6: + 27:12-34:6: FalseEdge: falseEdge -> [real: bb39, imaginary: bb38]"><span class="annotation">@37:</span> ;</span></span> +<span class="line"><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6: + 27:12-34:6: FalseEdge: falseEdge -> [real: bb39, imaginary: bb38]"> } else {</span></span> +<span class="line"><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6: + 27:12-34:6: FalseEdge: falseEdge -> [real: bb39, imaginary: bb38]"> </span><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"><span class="annotation">@38:</span> return;</span></span> +<span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"> }</span></span> +<span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"></span></span> +<span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"> let mut countdown = 0;</span></span> +<span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"> </span><span class="code even" style="--layer: 11" title="bb56: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6: + 38:9-38:23: Assign: _41 = const 10_i32 + 37:13-39:6: Assign: _42 = const () + 37:5-39:6: Goto: goto -> bb57"><span class="annotation">@56</span></span><span class="code even" style="--layer: 12" title="bb54: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6: + 37:5-39:6: FalseEdge: falseEdge -> [real: bb56, imaginary: bb55]"><span class="annotation">@54</span></span><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6: + 37:5-39:6: Assign: _42 = const () + 37:5-39:6: Goto: goto -> bb57"><span class="annotation">@55:</span> if </span><span class="code even" style="--layer: 14" title="bb53: ../instrument-coverage/coverage_of_if_else.rs:37:8: 37:12: + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 36:9-36:22: StorageLive: StorageLive(_41) + 36:25-36:26: Assign: _41 = const 0_i32 + 36:9-36:22: FakeRead: FakeRead(ForLet, _41) + 37:5-39:6: StorageLive: StorageLive(_42) + 37:8-37:12: StorageLive: StorageLive(_43) + 37:8-37:12: Assign: _43 = const true + 37:8-37:12: FakeRead: FakeRead(ForMatchedPlace, _43) + 37:5-39:6: SwitchInt: switchInt(_43) -> [false: bb55, otherwise: bb54]"><span class="annotation">@53:</span> true</span><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6: + 37:5-39:6: Assign: _42 = const () + 37:5-39:6: Goto: goto -> bb57"><span class="annotation">@55:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6: + 37:5-39:6: Assign: _42 = const () + 37:5-39:6: Goto: goto -> bb57"> countdown = 10;</span></span> +<span class="line"><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6: + 37:5-39:6: Assign: _42 = const () + 37:5-39:6: Goto: goto -> bb57"> }</span><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"><span class="annotation">@38:</span> </span></span> +<span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"></span></span> +<span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2: + 33:9-33:15: Assign: _0 = const () + 34:5-34:6: StorageDead: StorageDead(_28) + 34:5-34:6: StorageDead: StorageDead(_25) + 34:5-34:6: StorageDead: StorageDead(_24) + 51:1-51:2: StorageDead: StorageDead(_21) + 33:9-33:15: Goto: goto -> bb27"> </span><span class="code odd" style="--layer: 11" title="bb61: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 42:9-42:23: Assign: _41 = move (_46.0: i32) + 41:22-43:6: Assign: _0 = const () + 41:5-50:6: Goto: goto -> bb78"><span class="annotation">@61</span></span><span class="code even" style="--layer: 12" title="bb58: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 41:5-50:6: FalseEdge: falseEdge -> [real: bb60, imaginary: bb59]"><span class="annotation">@58</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 47:9-47:23: Assign: _41 = move (_58.0: i32) + 43:29-48:6: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 41:5-50:6: Goto: goto -> bb78"><span class="annotation">@77:</span> if </span><span class="code even" style="--layer: 14" title="bb57: ../instrument-coverage/coverage_of_if_else.rs:41:8: 41:21: + 39:5-39:6: StorageDead: StorageDead(_43) + 39:5-39:6: StorageDead: StorageDead(_42) + 41:8-41:21: StorageLive: StorageLive(_44) + 41:8-41:17: StorageLive: StorageLive(_45) + 41:8-41:17: Assign: _45 = _41 + 41:8-41:21: Assign: _44 = Gt(move _45, const 7_i32) + 41:20-41:21: StorageDead: StorageDead(_45) + 41:8-41:21: FakeRead: FakeRead(ForMatchedPlace, _44) + 41:5-50:6: SwitchInt: switchInt(_44) -> [false: bb59, otherwise: bb58]"><span class="annotation">@57:</span> countdown > 7</span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 47:9-47:23: Assign: _41 = move (_58.0: i32) + 43:29-48:6: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 41:5-50:6: Goto: goto -> bb78"><span class="annotation">@77:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 47:9-47:23: Assign: _41 = move (_58.0: i32) + 43:29-48:6: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 41:5-50:6: Goto: goto -> bb78"> </span><span class="code odd" style="--layer: 14" title="bb60: ../instrument-coverage/coverage_of_if_else.rs:42:9: 42:23: + 42:9-42:23: Assign: _46 = CheckedSub(_41, const 4_i32) + 42:9-42:23: Assert: assert(!move (_46.1: bool), "attempt to compute `{} - {}` which would overflow", _41, const 4_i32) -> [success: bb61, unwind: bb1]"><span class="annotation">@60:</span> countdown -= 4</span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 47:9-47:23: Assign: _41 = move (_58.0: i32) + 43:29-48:6: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 41:5-50:6: Goto: goto -> bb78"><span class="annotation">@77:</span> ;</span></span> +<span class="line"><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6: + 47:9-47:23: Assign: _41 = move (_58.0: i32) + 43:29-48:6: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 41:5-50:6: Goto: goto -> bb78"> } else </span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6: + 43:12-50:6: FalseEdge: falseEdge -> [real: bb64, imaginary: bb63]"><span class="annotation">@62:</span> if </span><span class="code even" style="--layer: 15" title="bb59: ../instrument-coverage/coverage_of_if_else.rs:43:15: 43:28: + 43:15-43:28: StorageLive: StorageLive(_47) + 43:15-43:24: StorageLive: StorageLive(_48) + 43:15-43:24: Assign: _48 = _41 + 43:15-43:28: Assign: _47 = Gt(move _48, const 2_i32) + 43:27-43:28: StorageDead: StorageDead(_48) + 43:15-43:28: FakeRead: FakeRead(ForMatchedPlace, _47) + 43:12-50:6: SwitchInt: switchInt(_47) -> [false: bb63, otherwise: bb62]"><span class="annotation">@59:</span> countdown > 2</span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6: + 43:12-50:6: FalseEdge: falseEdge -> [real: bb64, imaginary: bb63]"><span class="annotation">@62:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6: + 43:12-50:6: FalseEdge: falseEdge -> [real: bb64, imaginary: bb63]"> </span><span class="code odd" style="--layer: 15" title="bb75: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10: + 45:13-45:26: Assign: _41 = const 0_i32 + 44:61-46:10: Assign: _49 = const () + 44:9-46:10: Goto: goto -> bb76"><span class="annotation">@75</span></span><span class="code even" style="--layer: 16" title="bb74: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10: + 44:9-46:10: Assign: _49 = const () + 44:9-46:10: Goto: goto -> bb76"><span class="annotation">@74</span></span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10: + 44:9-46:10: FalseEdge: falseEdge -> [real: bb75, imaginary: bb74]"><span class="annotation">@73:</span> if </span><span class="code even" style="--layer: 18" title="bb67: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:46-44:60: StorageLive: StorageLive(_56) + 44:46-44:55: StorageLive: StorageLive(_57) + 44:46-44:55: Assign: _57 = _41 + 44:46-44:60: Assign: _56 = Ne(move _57, const 9_i32) + 44:59-44:60: StorageDead: StorageDead(_57) + 44:12-44:60: SwitchInt: switchInt(move _56) -> [false: bb66, otherwise: bb65]"><span class="annotation">@67</span></span><span class="code even" style="--layer: 19" title="bb68: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:59-44:60: StorageDead: StorageDead(_56) + 44:59-44:60: StorageDead: StorageDead(_51) + 44:12-44:60: FakeRead: FakeRead(ForMatchedPlace, _50) + 44:9-46:10: SwitchInt: switchInt(_50) -> [false: bb74, otherwise: bb73]"><span class="annotation">@68</span></span><span class="code even" style="--layer: 20" title="bb65: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:12-44:60: Assign: _50 = const true + 44:12-44:60: Goto: goto -> bb68"><span class="annotation">@65</span></span><span class="code even" style="--layer: 21" title="bb72: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:41-44:42: StorageDead: StorageDead(_54) + 44:41-44:42: StorageDead: StorageDead(_52) + 44:12-44:60: SwitchInt: switchInt(move _51) -> [false: bb67, otherwise: bb65]"><span class="annotation">@72</span></span><span class="code even" style="--layer: 22" title="bb64: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:9-46:10: StorageLive: StorageLive(_49) + 44:12-44:60: StorageLive: StorageLive(_50) + 44:12-44:42: StorageLive: StorageLive(_51) + 44:12-44:25: StorageLive: StorageLive(_52) + 44:12-44:21: StorageLive: StorageLive(_53) + 44:12-44:21: Assign: _53 = _41 + 44:12-44:25: Assign: _52 = Lt(move _53, const 1_i32) + 44:24-44:25: StorageDead: StorageDead(_53) + 44:12-44:42: SwitchInt: switchInt(move _52) -> [false: bb71, otherwise: bb69]"><span class="annotation">@64</span></span><span class="code even" style="--layer: 23" title="bb66: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:12-44:60: Assign: _50 = const false + 44:12-44:60: Goto: goto -> bb68"><span class="annotation">@66</span></span><span class="code even" style="--layer: 24" title="bb69: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42: + 44:12-44:42: Assign: _51 = const true + 44:12-44:42: Goto: goto -> bb72"><span class="annotation">@69</span></span><span class="code even" style="--layer: 25" title="bb71: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42: + 44:29-44:42: StorageLive: StorageLive(_54) + 44:29-44:38: StorageLive: StorageLive(_55) + 44:29-44:38: Assign: _55 = _41 + 44:29-44:42: Assign: _54 = Gt(move _55, const 5_i32) + 44:41-44:42: StorageDead: StorageDead(_55) + 44:12-44:42: SwitchInt: switchInt(move _54) -> [false: bb70, otherwise: bb69]"><span class="annotation">@71</span></span><span class="code even" style="--layer: 26" title="bb70: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42: + 44:12-44:42: Assign: _51 = const false + 44:12-44:42: Goto: goto -> bb72"><span class="annotation">@70:</span> countdown < 1 || countdown > 5</span><span class="code even" style="--layer: 23" title="bb66: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60: + 44:12-44:60: Assign: _50 = const false + 44:12-44:60: Goto: goto -> bb68"><span class="annotation">@66:</span> || countdown != 9</span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10: + 44:9-46:10: FalseEdge: falseEdge -> [real: bb75, imaginary: bb74]"><span class="annotation">@73:</span> {</span></span> +<span class="line"><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10: + 44:9-46:10: FalseEdge: falseEdge -> [real: bb75, imaginary: bb74]"> countdown = 0;</span></span> +<span class="line"><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10: + 44:9-46:10: FalseEdge: falseEdge -> [real: bb75, imaginary: bb74]"> </span><span class="code odd" style="--layer: 18" title="bb76: ../instrument-coverage/coverage_of_if_else.rs:46:9: 47:23: + 46:9-46:10: StorageDead: StorageDead(_50) + 46:9-46:10: StorageDead: StorageDead(_49) + 47:9-47:23: Assign: _58 = CheckedSub(_41, const 5_i32) + 47:9-47:23: Assert: assert(!move (_58.1: bool), "attempt to compute `{} - {}` which would overflow", _41, const 5_i32) -> [success: bb77, unwind: bb1]"><span class="annotation">@76:</span> }</span></span> +<span class="line"><span class="code odd" style="--layer: 18" title="bb76: ../instrument-coverage/coverage_of_if_else.rs:46:9: 47:23: + 46:9-46:10: StorageDead: StorageDead(_50) + 46:9-46:10: StorageDead: StorageDead(_49) + 47:9-47:23: Assign: _58 = CheckedSub(_41, const 5_i32) + 47:9-47:23: Assert: assert(!move (_58.1: bool), "attempt to compute `{} - {}` which would overflow", _41, const 5_i32) -> [success: bb77, unwind: bb1]"> countdown -= 5</span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6: + 43:12-50:6: FalseEdge: falseEdge -> [real: bb64, imaginary: bb63]"><span class="annotation">@62:</span> ;</span></span> +<span class="line"><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6: + 43:12-50:6: FalseEdge: falseEdge -> [real: bb64, imaginary: bb63]"> } else {</span></span> +<span class="line"><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6: + 43:12-50:6: FalseEdge: falseEdge -> [real: bb64, imaginary: bb63]"> </span><span class="code even" style="--layer: 15" title="bb63: ../instrument-coverage/coverage_of_if_else.rs:49:9: 51:2: + 49:9-49:15: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 51:1-51:2: StorageDead: StorageDead(_41) + 51:1-51:2: StorageDead: StorageDead(_21) + 51:1-51:2: StorageDead: StorageDead(_1) + 51:1-51:2: StorageDead: StorageDead(_44) + 49:9-49:15: Goto: goto -> bb26"><span class="annotation">@63:</span> return;</span></span> +<span class="line"><span class="code even" style="--layer: 15" title="bb63: ../instrument-coverage/coverage_of_if_else.rs:49:9: 51:2: + 49:9-49:15: Assign: _0 = const () + 50:5-50:6: StorageDead: StorageDead(_47) + 51:1-51:2: StorageDead: StorageDead(_41) + 51:1-51:2: StorageDead: StorageDead(_21) + 51:1-51:2: StorageDead: StorageDead(_1) + 51:1-51:2: StorageDead: StorageDead(_44) + 49:9-49:15: Goto: goto -> bb26"> }</span><span class="code even" style="--layer: 16" title="bb78: ../instrument-coverage/coverage_of_if_else.rs:51:1: 51:2: + 51:1-51:2: StorageDead: StorageDead(_41) + 51:1-51:2: StorageDead: StorageDead(_21) + 51:1-51:2: StorageDead: StorageDead(_1) + 51:1-51:2: StorageDead: StorageDead(_44) + 51:2-51:2: Goto: goto -> bb26"><span class="annotation">@78:</span> }</span><span><span class="code even" style="--layer: 1" title="bb26: ../instrument-coverage/coverage_of_if_else.rs:51:2: 51:2: + 51:2-51:2: Return: return"><span class="annotation">@26</span></span></span></span></div> +</body> +</html> diff --git a/src/test/run-make-fulldeps/instrument-coverage/Makefile b/src/test/run-make-fulldeps/instrument-coverage/Makefile deleted file mode 100644 index 4392cfec080..00000000000 --- a/src/test/run-make-fulldeps/instrument-coverage/Makefile +++ /dev/null @@ -1,103 +0,0 @@ -# needs-profiler-support -# ignore-msvc - -# FIXME(richkadel): Debug the following problem, and reenable on Windows (by -# removing the `# ignore-msvc` directive above). The current implementation -# generates a segfault when running the instrumented `testprog` executable, -# after the `main()` function completes, but before the process terminates. -# This most likely points to a problem generating the LLVM "testprog.profraw" -# file. - --include ../tools.mk - -UNAME = $(shell uname) - -ifeq ($(UNAME),Darwin) - INSTR_PROF_DATA_SUFFIX=,regular,live_support - DATA_SECTION_PREFIX=__DATA, - LLVM_COV_SECTION_PREFIX=__LLVM_COV, -else - INSTR_PROF_DATA_SUFFIX= - DATA_SECTION_PREFIX= - LLVM_COV_SECTION_PREFIX= -endif - -# This test makes sure that LLVM coverage maps are genereated in LLVM IR. - -COMMON_FLAGS=-Zinstrument-coverage - -all: - # Compile the test program with instrumentation, and also generate LLVM IR - $(RUSTC) $(COMMON_FLAGS) testprog.rs \ - --emit=link,llvm-ir - - # check the LLVM IR -ifdef IS_WIN32 - cat "$(TMPDIR)"/testprog.ll | "$(LLVM_FILECHECK)" filecheck-patterns.txt \ - -check-prefixes=CHECK,WIN32 \ - -DPRIVATE_GLOBAL="internal global" \ - -DINSTR_PROF_DATA=".lprfd$$M" \ - -DINSTR_PROF_NAME=".lprfn$$M" \ - -DINSTR_PROF_CNTS=".lprfc$$M" \ - -DINSTR_PROF_VALS=".lprfv$$M" \ - -DINSTR_PROF_VNODES=".lprfnd$$M" \ - -DINSTR_PROF_COVMAP=".lcovmap$$M" \ - -DINSTR_PROF_ORDERFILE=".lorderfile$$M" -else - cat "$(TMPDIR)"/testprog.ll | "$(LLVM_FILECHECK)" filecheck-patterns.txt \ - -check-prefixes=CHECK \ - -DPRIVATE_GLOBAL="private global" \ - -DINSTR_PROF_DATA="$(DATA_SECTION_PREFIX)__llvm_prf_data$(INSTR_PROF_DATA_SUFFIX)" \ - -DINSTR_PROF_NAME="$(DATA_SECTION_PREFIX)__llvm_prf_names" \ - -DINSTR_PROF_CNTS="$(DATA_SECTION_PREFIX)__llvm_prf_cnts" \ - -DINSTR_PROF_VALS="$(DATA_SECTION_PREFIX)__llvm_prf_vals" \ - -DINSTR_PROF_VNODES="$(DATA_SECTION_PREFIX)__llvm_prf_vnds" \ - -DINSTR_PROF_COVMAP="$(LLVM_COV_SECTION_PREFIX)__llvm_covmap" \ - -DINSTR_PROF_ORDERFILE="$(DATA_SECTION_PREFIX)__llvm_orderfile" -endif - - # Run it in order to generate some profiling data, - # with `LLVM_PROFILE_FILE=<profdata_file>` environment variable set to - # output the coverage stats for this run. - LLVM_PROFILE_FILE="$(TMPDIR)"/testprog.profraw \ - $(call RUN,testprog) - - # Postprocess the profiling data so it can be used by the llvm-cov tool - "$(LLVM_BIN_DIR)"/llvm-profdata merge --sparse \ - "$(TMPDIR)"/testprog.profraw \ - -o "$(TMPDIR)"/testprog.profdata - - # Generate a coverage report using `llvm-cov show`. The output ordering - # can be non-deterministic, so ignore the return status. If the test fails - # when comparing the JSON `export`, the `show` output may be useful when - # debugging. - "$(LLVM_BIN_DIR)"/llvm-cov show \ - --Xdemangler="$(RUST_DEMANGLER)" \ - --show-line-counts-or-regions \ - --instr-profile="$(TMPDIR)"/testprog.profdata \ - $(call BIN,"$(TMPDIR)"/testprog) \ - > "$(TMPDIR)"/actual_show_coverage.txt - -ifdef RUSTC_BLESS_TEST - cp "$(TMPDIR)"/actual_show_coverage.txt typical_show_coverage.txt -else - # Compare the show coverage output - $(DIFF) typical_show_coverage.txt "$(TMPDIR)"/actual_show_coverage.txt || \ - >&2 echo 'diff failed for `llvm-cov show` (might not be an error)' -endif - - # Generate a coverage report in JSON, using `llvm-cov export`, and fail if - # there are differences from the expected output. - "$(LLVM_BIN_DIR)"/llvm-cov export \ - --summary-only \ - --instr-profile="$(TMPDIR)"/testprog.profdata \ - $(call BIN,"$(TMPDIR)"/testprog) \ - | "$(PYTHON)" prettify_json.py \ - > "$(TMPDIR)"/actual_export_coverage.json - -ifdef RUSTC_BLESS_TEST - cp "$(TMPDIR)"/actual_export_coverage.json expected_export_coverage.json -else - # Check that the exported JSON coverage data matches what we expect - $(DIFF) expected_export_coverage.json "$(TMPDIR)"/actual_export_coverage.json -endif diff --git a/src/test/run-make-fulldeps/instrument-coverage/compiletest-ignore-dir b/src/test/run-make-fulldeps/instrument-coverage/compiletest-ignore-dir new file mode 100644 index 00000000000..d57f66a4489 --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage/compiletest-ignore-dir @@ -0,0 +1,3 @@ +# Directory "instrument-coverage" supports the tests at prefix ../instrument-coverage-* + +# Use ./x.py [options] test src/test/run-make-fulldeps/instrument-coverage to run all related tests. \ No newline at end of file diff --git a/src/test/run-make-fulldeps/instrument-coverage/coverage_of_if_else.rs b/src/test/run-make-fulldeps/instrument-coverage/coverage_of_if_else.rs new file mode 100644 index 00000000000..91741cf8f0d --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage/coverage_of_if_else.rs @@ -0,0 +1,51 @@ +#![allow(unused_assignments)] + +fn main() { + let mut countdown = 0; + if true { + countdown = 10; + } + + if countdown > 7 { + countdown -= 4; + } else if countdown > 2 { + if countdown < 1 || countdown > 5 || countdown != 9 { + countdown = 0; + } + countdown -= 5; + } else { + return; + } + + let mut countdown = 0; + if true { + countdown = 10; + } + + if countdown > 7 { + countdown -= 4; + } else if countdown > 2 { + if countdown < 1 || countdown > 5 || countdown != 9 { + countdown = 0; + } + countdown -= 5; + } else { + return; + } + + let mut countdown = 0; + if true { + countdown = 10; + } + + if countdown > 7 { + countdown -= 4; + } else if countdown > 2 { + if countdown < 1 || countdown > 5 || countdown != 9 { + countdown = 0; + } + countdown -= 5; + } else { + return; + } +} diff --git a/src/test/run-make-fulldeps/instrument-coverage/coverage_tools.mk b/src/test/run-make-fulldeps/instrument-coverage/coverage_tools.mk new file mode 100644 index 00000000000..ad5f465c54f --- /dev/null +++ b/src/test/run-make-fulldeps/instrument-coverage/coverage_tools.mk @@ -0,0 +1,39 @@ +# Common Makefile include for Rust `run-make-fulldeps/instrument-coverage-* tests. Include this +# file with the line: +# +# -include ../instrument-coverage/coverage_tools.mk +# +# To enable the Rust compiler option `-C link-dead-code`, also set the following variable +# *BEFORE* the `-include` line: +# +# LINK_DEAD_CODE=yes + +-include ../tools.mk + +ifndef LINK_DEAD_CODE + LINK_DEAD_CODE=no +endif + +# ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and +# `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw` +# file, required for coverage reports. +# +# Enabling `-C link-dead-code` is preferred when compiling with `-Z instrument-coverage`, so +# `-C link-dead-code` is automatically enabled for all platform targets _except_ MSVC. +# +# Making the state of `-C link-dead-code` platform-dependent creates a problem for cross-platform +# tests because the injected counters, coverage reports, and some low-level output can be different, +# depending on the `-C link-dead-code` setting. For example, coverage reports will not report any +# coverage for a dead code region when the `-C link-dead-code` option is disabled, but with the +# option enabled, those same regions will show coverage counter values (of zero, of course). +# +# To ensure cross-platform `-Z instrument-coverage` generate consistent output, the +# `-C link-dead-code` option is always explicitly enabled or disabled. +# +# Since tests that execute binaries enabled with both `-Z instrument-coverage` and +# `-C link-dead-code` are known to fail, those tests will need the `# ignore-msvc` setting. +# +# If and when the above issue is resolved, the `# ignore-msvc` option can be removed, and the +# tests can be simplified to always test with `-C link-dead-code`. + +UNAME = $(shell uname) diff --git a/src/test/run-make-fulldeps/instrument-coverage/expected_export_coverage.json b/src/test/run-make-fulldeps/instrument-coverage/expected_export_coverage.json deleted file mode 100644 index 75bec80bdf8..00000000000 --- a/src/test/run-make-fulldeps/instrument-coverage/expected_export_coverage.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "data": [ - { - "files": [ - { - "filename": "testprog.rs", - "summary": { - "functions": { - "count": 7, - "covered": 5, - "percent": 71.42857142857143 - }, - "instantiations": { - "count": 8, - "covered": 6, - "percent": 75 - }, - "lines": { - "count": 30, - "covered": 25, - "percent": 83.33333333333334 - }, - "regions": { - "count": 7, - "covered": 5, - "notcovered": 2, - "percent": 71.42857142857143 - } - } - } - ], - "totals": { - "functions": { - "count": 7, - "covered": 5, - "percent": 71.42857142857143 - }, - "instantiations": { - "count": 8, - "covered": 6, - "percent": 75 - }, - "lines": { - "count": 30, - "covered": 25, - "percent": 83.33333333333334 - }, - "regions": { - "count": 7, - "covered": 5, - "notcovered": 2, - "percent": 71.42857142857143 - } - } - } - ], - "type": "llvm.coverage.json.export", - "version": "2.0.1" -} diff --git a/src/test/run-make-fulldeps/instrument-coverage/filecheck-patterns.txt b/src/test/run-make-fulldeps/instrument-coverage/filecheck-patterns.txt deleted file mode 100644 index 5a7cc9a1882..00000000000 --- a/src/test/run-make-fulldeps/instrument-coverage/filecheck-patterns.txt +++ /dev/null @@ -1,51 +0,0 @@ -# Check for metadata, variables, declarations, and function definitions injected -# into LLVM IR when compiling with -Zinstrument-coverage. - -WIN32: $__llvm_profile_runtime_user = comdat any - -CHECK: @__llvm_coverage_mapping = internal constant -CHECK-SAME: section "[[INSTR_PROF_COVMAP]]", align 8 - -WIN32: @__llvm_profile_runtime = external global i32 - -CHECK: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = [[PRIVATE_GLOBAL]] -CHECK-SAME: section "[[INSTR_PROF_CNTS]]", align 8 - -CHECK: @__profd__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = [[PRIVATE_GLOBAL]] -CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called, -CHECK-SAME: ()* @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called to i8*), -CHECK-SAME: section "[[INSTR_PROF_DATA]]", align 8 - -CHECK: @__profc__R{{[a-zA-Z0-9_]+}}testprog4main = [[PRIVATE_GLOBAL]] -CHECK-SAME: section "[[INSTR_PROF_CNTS]]", align 8 - -CHECK: @__profd__R{{[a-zA-Z0-9_]+}}testprog4main = [[PRIVATE_GLOBAL]] -CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog4main, -CHECK-SAME: ()* @_R{{[a-zA-Z0-9_]+}}testprog4main to i8*), -CHECK-SAME: section "[[INSTR_PROF_DATA]]", align 8 - -CHECK: @__llvm_prf_nm = private constant -CHECK-SAME: section "[[INSTR_PROF_NAME]]", align 1 - -CHECK: @llvm.used = appending global -CHECK-SAME: i8* bitcast ({ {{.*}} }* @__llvm_coverage_mapping to i8*) -WIN32-SAME: i8* bitcast (i32 ()* @__llvm_profile_runtime_user to i8*) -CHECK-SAME: i8* bitcast ({ {{.*}} }* @__profd__R{{[a-zA-Z0-9_]*}}testprog4main to i8*) -CHECK-SAME: i8* getelementptr inbounds ({{.*}}* @__llvm_prf_nm, i32 0, i32 0) -CHECK-SAME: section "llvm.metadata" - -CHECK: define hidden { {{.*}} } @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called() unnamed_addr #{{[0-9]+}} { -CHECK-NEXT: start: -CHECK-NOT: bb{{[0-9]+}}: -CHECK: %pgocount = load i64, i64* getelementptr inbounds -CHECK-SAME: * @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called, - -CHECK: declare void @llvm.instrprof.increment(i8*, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]] - -WIN32: define linkonce_odr hidden i32 @__llvm_profile_runtime_user() #[[LLVM_PROFILE_RUNTIME_USER_ATTR:[0-9]+]] comdat { -WIN32-NEXT: %1 = load i32, i32* @__llvm_profile_runtime -WIN32-NEXT: ret i32 %1 -WIN32-NEXT: } - -CHECK: attributes #[[LLVM_INSTRPROF_INCREMENT_ATTR]] = { nounwind } -WIN32: attributes #[[LLVM_PROFILE_RUNTIME_USER_ATTR]] = { noinline } \ No newline at end of file diff --git a/src/test/run-make-fulldeps/instrument-coverage/typical_show_coverage.txt b/src/test/run-make-fulldeps/instrument-coverage/typical_show_coverage.txt deleted file mode 100644 index ae123afff04..00000000000 --- a/src/test/run-make-fulldeps/instrument-coverage/typical_show_coverage.txt +++ /dev/null @@ -1,55 +0,0 @@ - 1| 2|pub fn will_be_called() -> &'static str { - 2| 2| let val = "called"; - 3| 2| println!("{}", val); - 4| 2| val - 5| 2|} - 6| | - 7| 0|pub fn will_not_be_called() -> bool { - 8| 0| println!("should not have been called"); - 9| 0| false - 10| 0|} - 11| | - 12| |pub fn print<T>(left: &str, value: T, right: &str) - 13| |where - 14| | T: std::fmt::Display, - 15| 1|{ - 16| 1| println!("{}{}{}", left, value, right); - 17| 1|} - 18| | - 19| |pub fn wrap_with<F, T>(inner: T, should_wrap: bool, wrapper: F) - 20| |where - 21| | F: FnOnce(&T) - 22| 2|{ - 23| 2| if should_wrap { - 24| 2| wrapper(&inner) - 25| 2| } - 26| 2|} - ------------------ - | testprog[317d481089b8c8fe]::wrap_with::<testprog[317d481089b8c8fe]::main::{closure#0}, &str>: - | 22| 1|{ - | 23| 1| if should_wrap { - | 24| 1| wrapper(&inner) - | 25| 1| } - | 26| 1|} - ------------------ - | testprog[317d481089b8c8fe]::wrap_with::<testprog[317d481089b8c8fe]::main::{closure#1}, &str>: - | 22| 1|{ - | 23| 1| if should_wrap { - | 24| 1| wrapper(&inner) - | 25| 1| } - | 26| 1|} - ------------------ - 27| | - 28| 1|fn main() { - 29| 1| let less = 1; - 30| 1| let more = 100; - 31| 1| - 32| 1| if less < more { - 33| 1| wrap_with(will_be_called(), less < more, |inner| print(" ***", inner, "*** ")); - 34| 1| wrap_with(will_be_called(), more < less, |inner| print(" ***", inner, "*** ")); - ^0 - 35| 1| } else { - 36| 1| wrap_with(will_not_be_called(), true, |inner| print("wrapped result is: ", inner, "")); - 37| 1| } - 38| 1|} - |
