about summary refs log tree commit diff
path: root/tests/coverage
diff options
context:
space:
mode:
Diffstat (limited to 'tests/coverage')
-rw-r--r--tests/coverage/abort.coverage69
-rw-r--r--tests/coverage/abort.rs66
-rw-r--r--tests/coverage/assert.coverage34
-rw-r--r--tests/coverage/assert.rs32
-rw-r--r--tests/coverage/async.coverage139
-rw-r--r--tests/coverage/async.rs128
-rw-r--r--tests/coverage/async2.coverage104
-rw-r--r--tests/coverage/async2.rs57
-rw-r--r--tests/coverage/auxiliary/inline_always_with_dead_code.rs22
-rw-r--r--tests/coverage/auxiliary/unused_mod_helper.rs4
-rw-r--r--tests/coverage/auxiliary/used_crate.rs103
-rw-r--r--tests/coverage/auxiliary/used_inline_crate.rs85
-rw-r--r--tests/coverage/bad_counter_ids.coverage69
-rw-r--r--tests/coverage/bad_counter_ids.rs66
-rw-r--r--tests/coverage/closure.coverage227
-rw-r--r--tests/coverage/closure.rs220
-rw-r--r--tests/coverage/closure_bug.coverage53
-rw-r--r--tests/coverage/closure_bug.rs44
-rw-r--r--tests/coverage/closure_macro.coverage42
-rw-r--r--tests/coverage/closure_macro.rs40
-rw-r--r--tests/coverage/closure_macro_async.coverage79
-rw-r--r--tests/coverage/closure_macro_async.rs77
-rw-r--r--tests/coverage/conditions.coverage93
-rw-r--r--tests/coverage/conditions.rs86
-rw-r--r--tests/coverage/continue.coverage70
-rw-r--r--tests/coverage/continue.rs69
-rw-r--r--tests/coverage/coroutine.coverage32
-rw-r--r--tests/coverage/coroutine.rs30
-rw-r--r--tests/coverage/dead_code.coverage39
-rw-r--r--tests/coverage/dead_code.rs37
-rw-r--r--tests/coverage/drop_trait.coverage34
-rw-r--r--tests/coverage/drop_trait.rs33
-rw-r--r--tests/coverage/fn_sig_into_try.coverage45
-rw-r--r--tests/coverage/fn_sig_into_try.rs41
-rw-r--r--tests/coverage/generics.coverage67
-rw-r--r--tests/coverage/generics.rs44
-rw-r--r--tests/coverage/if.coverage30
-rw-r--r--tests/coverage/if.rs28
-rw-r--r--tests/coverage/if_else.coverage41
-rw-r--r--tests/coverage/if_else.rs40
-rw-r--r--tests/coverage/inline-dead.coverage28
-rw-r--r--tests/coverage/inline-dead.rs27
-rw-r--r--tests/coverage/inline.coverage54
-rw-r--r--tests/coverage/inline.rs51
-rw-r--r--tests/coverage/inner_items.coverage60
-rw-r--r--tests/coverage/inner_items.rs57
-rw-r--r--tests/coverage/issue-83601.coverage16
-rw-r--r--tests/coverage/issue-83601.rs14
-rw-r--r--tests/coverage/issue-84561.coverage189
-rw-r--r--tests/coverage/issue-84561.rs182
-rw-r--r--tests/coverage/issue-85461.coverage37
-rw-r--r--tests/coverage/issue-85461.rs11
-rw-r--r--tests/coverage/issue-93054.coverage31
-rw-r--r--tests/coverage/issue-93054.rs30
-rw-r--r--tests/coverage/lazy_boolean.coverage64
-rw-r--r--tests/coverage/lazy_boolean.rs61
-rw-r--r--tests/coverage/long_and_wide.coverage151
-rw-r--r--tests/coverage/long_and_wide.rs150
-rw-r--r--tests/coverage/loop_break_value.coverage14
-rw-r--r--tests/coverage/loop_break_value.rs13
-rw-r--r--tests/coverage/loops_branches.coverage67
-rw-r--r--tests/coverage/loops_branches.rs60
-rw-r--r--tests/coverage/match_or_pattern.coverage48
-rw-r--r--tests/coverage/match_or_pattern.rs43
-rw-r--r--tests/coverage/nested_loops.coverage26
-rw-r--r--tests/coverage/nested_loops.rs25
-rw-r--r--tests/coverage/no_cov_crate.coverage89
-rw-r--r--tests/coverage/no_cov_crate.rs88
-rw-r--r--tests/coverage/overflow.coverage65
-rw-r--r--tests/coverage/overflow.rs64
-rw-r--r--tests/coverage/panic_unwind.coverage32
-rw-r--r--tests/coverage/panic_unwind.rs31
-rw-r--r--tests/coverage/partial_eq.coverage48
-rw-r--r--tests/coverage/partial_eq.rs46
-rw-r--r--tests/coverage/simple_loop.coverage37
-rw-r--r--tests/coverage/simple_loop.rs35
-rw-r--r--tests/coverage/simple_match.coverage45
-rw-r--r--tests/coverage/simple_match.rs43
-rw-r--r--tests/coverage/sort_groups.coverage49
-rw-r--r--tests/coverage/sort_groups.rs23
-rw-r--r--tests/coverage/test_harness.coverage11
-rw-r--r--tests/coverage/test_harness.rs10
-rw-r--r--tests/coverage/tight_inf_loop.coverage6
-rw-r--r--tests/coverage/tight_inf_loop.rs5
-rw-r--r--tests/coverage/trivial.coverage4
-rw-r--r--tests/coverage/trivial.rs3
-rw-r--r--tests/coverage/try_error_result.coverage125
-rw-r--r--tests/coverage/try_error_result.rs118
-rw-r--r--tests/coverage/unreachable.coverage38
-rw-r--r--tests/coverage/unreachable.rs37
-rw-r--r--tests/coverage/unused.coverage64
-rw-r--r--tests/coverage/unused.rs41
-rw-r--r--tests/coverage/unused_mod.coverage14
-rw-r--r--tests/coverage/unused_mod.rs6
-rw-r--r--tests/coverage/uses_crate.coverage173
-rw-r--r--tests/coverage/uses_crate.rs19
-rw-r--r--tests/coverage/uses_inline_crate.coverage159
-rw-r--r--tests/coverage/uses_inline_crate.rs22
-rw-r--r--tests/coverage/while.coverage6
-rw-r--r--tests/coverage/while.rs5
-rw-r--r--tests/coverage/while_early_ret.coverage43
-rw-r--r--tests/coverage/while_early_ret.rs42
-rw-r--r--tests/coverage/yield.coverage38
-rw-r--r--tests/coverage/yield.rs37
104 files changed, 5849 insertions, 0 deletions
diff --git a/tests/coverage/abort.coverage b/tests/coverage/abort.coverage
new file mode 100644
index 00000000000..ceef6386780
--- /dev/null
+++ b/tests/coverage/abort.coverage
@@ -0,0 +1,69 @@
+   LL|       |#![feature(c_unwind)]
+   LL|       |#![allow(unused_assignments)]
+   LL|       |
+   LL|     12|extern "C" fn might_abort(should_abort: bool) {
+   LL|     12|    if should_abort {
+   LL|      0|        println!("aborting...");
+   LL|      0|        panic!("panics and aborts");
+   LL|     12|    } else {
+   LL|     12|        println!("Don't Panic");
+   LL|     12|    }
+   LL|     12|}
+   LL|       |
+   LL|      1|fn main() -> Result<(), u8> {
+   LL|      1|    let mut countdown = 10;
+   LL|     11|    while countdown > 0 {
+   LL|     10|        if countdown < 5 {
+   LL|      4|            might_abort(false);
+   LL|      6|        }
+   LL|       |        // See discussion (below the `Notes` section) on coverage results for the closing brace.
+   LL|     10|        if countdown < 5 { might_abort(false); } // Counts for different regions on one line.
+                                       ^4                     ^6
+   LL|       |        // For the following example, the closing brace is the last character on the line.
+   LL|       |        // This shows the character after the closing brace is highlighted, even if that next
+   LL|       |        // character is a newline.
+   LL|     10|        if countdown < 5 { might_abort(false); }
+                                       ^4                     ^6
+   LL|     10|        countdown -= 1;
+   LL|       |    }
+   LL|      1|    Ok(())
+   LL|      1|}
+   LL|       |
+   LL|       |// Notes:
+   LL|       |//   1. Compare this program and its coverage results to those of the similar tests
+   LL|       |//      `panic_unwind.rs` and `try_error_result.rs`.
+   LL|       |//   2. This test confirms the coverage generated when a program includes `UnwindAction::Terminate`.
+   LL|       |//   3. The test does not invoke the abort. By executing to a successful completion, the coverage
+   LL|       |//      results show where the program did and did not execute.
+   LL|       |//   4. If the program actually aborted, the coverage counters would not be saved (which "works as
+   LL|       |//      intended"). Coverage results would show no executed coverage regions.
+   LL|       |//   6. If `should_abort` is `true` and the program aborts, the program exits with a `132` status
+   LL|       |//      (on Linux at least).
+   LL|       |
+   LL|       |/*
+   LL|       |
+   LL|       |Expect the following coverage results:
+   LL|       |
+   LL|       |```text
+   LL|       |    16|     11|    while countdown > 0 {
+   LL|       |    17|     10|        if countdown < 5 {
+   LL|       |    18|      4|            might_abort(false);
+   LL|       |    19|      6|        }
+   LL|       |```
+   LL|       |
+   LL|       |This is actually correct.
+   LL|       |
+   LL|       |The condition `countdown < 5` executed 10 times (10 loop iterations).
+   LL|       |
+   LL|       |It evaluated to `true` 4 times, and executed the `might_abort()` call.
+   LL|       |
+   LL|       |It skipped the body of the `might_abort()` call 6 times. If an `if` does not include an explicit
+   LL|       |`else`, the coverage implementation injects a counter, at the character immediately after the `if`s
+   LL|       |closing brace, to count the "implicit" `else`. This is the only way to capture the coverage of the
+   LL|       |non-true condition.
+   LL|       |
+   LL|       |As another example of why this is important, say the condition was `countdown < 50`, which is always
+   LL|       |`true`. In that case, we wouldn't have a test for what happens if `might_abort()` is not called.
+   LL|       |The closing brace would have a count of `0`, highlighting the missed coverage.
+   LL|       |*/
+
diff --git a/tests/coverage/abort.rs b/tests/coverage/abort.rs
new file mode 100644
index 00000000000..98264bdc1af
--- /dev/null
+++ b/tests/coverage/abort.rs
@@ -0,0 +1,66 @@
+#![feature(c_unwind)]
+#![allow(unused_assignments)]
+
+extern "C" fn might_abort(should_abort: bool) {
+    if should_abort {
+        println!("aborting...");
+        panic!("panics and aborts");
+    } else {
+        println!("Don't Panic");
+    }
+}
+
+fn main() -> Result<(), u8> {
+    let mut countdown = 10;
+    while countdown > 0 {
+        if countdown < 5 {
+            might_abort(false);
+        }
+        // See discussion (below the `Notes` section) on coverage results for the closing brace.
+        if countdown < 5 { might_abort(false); } // Counts for different regions on one line.
+        // For the following example, the closing brace is the last character on the line.
+        // This shows the character after the closing brace is highlighted, even if that next
+        // character is a newline.
+        if countdown < 5 { might_abort(false); }
+        countdown -= 1;
+    }
+    Ok(())
+}
+
+// Notes:
+//   1. Compare this program and its coverage results to those of the similar tests
+//      `panic_unwind.rs` and `try_error_result.rs`.
+//   2. This test confirms the coverage generated when a program includes `UnwindAction::Terminate`.
+//   3. The test does not invoke the abort. By executing to a successful completion, the coverage
+//      results show where the program did and did not execute.
+//   4. If the program actually aborted, the coverage counters would not be saved (which "works as
+//      intended"). Coverage results would show no executed coverage regions.
+//   6. If `should_abort` is `true` and the program aborts, the program exits with a `132` status
+//      (on Linux at least).
+
+/*
+
+Expect the following coverage results:
+
+```text
+    16|     11|    while countdown > 0 {
+    17|     10|        if countdown < 5 {
+    18|      4|            might_abort(false);
+    19|      6|        }
+```
+
+This is actually correct.
+
+The condition `countdown < 5` executed 10 times (10 loop iterations).
+
+It evaluated to `true` 4 times, and executed the `might_abort()` call.
+
+It skipped the body of the `might_abort()` call 6 times. If an `if` does not include an explicit
+`else`, the coverage implementation injects a counter, at the character immediately after the `if`s
+closing brace, to count the "implicit" `else`. This is the only way to capture the coverage of the
+non-true condition.
+
+As another example of why this is important, say the condition was `countdown < 50`, which is always
+`true`. In that case, we wouldn't have a test for what happens if `might_abort()` is not called.
+The closing brace would have a count of `0`, highlighting the missed coverage.
+*/
diff --git a/tests/coverage/assert.coverage b/tests/coverage/assert.coverage
new file mode 100644
index 00000000000..8b997724c4a
--- /dev/null
+++ b/tests/coverage/assert.coverage
@@ -0,0 +1,34 @@
+   LL|       |#![allow(unused_assignments)]
+   LL|       |// failure-status: 101
+   LL|       |
+   LL|      4|fn might_fail_assert(one_plus_one: u32) {
+   LL|      4|    println!("does 1 + 1 = {}?", one_plus_one);
+   LL|      4|    assert_eq!(1 + 1, one_plus_one, "the argument was wrong");
+                                                  ^1
+   LL|      3|}
+   LL|       |
+   LL|      1|fn main() -> Result<(), u8> {
+   LL|      1|    let mut countdown = 10;
+   LL|     11|    while countdown > 0 {
+   LL|     11|        if countdown == 1 {
+   LL|      1|            might_fail_assert(3);
+   LL|     10|        } else if countdown < 5 {
+   LL|      3|            might_fail_assert(2);
+   LL|      6|        }
+   LL|     10|        countdown -= 1;
+   LL|       |    }
+   LL|      0|    Ok(())
+   LL|      0|}
+   LL|       |
+   LL|       |// Notes:
+   LL|       |//   1. Compare this program and its coverage results to those of the very similar test
+   LL|       |//      `panic_unwind.rs`, and similar tests `abort.rs` and `try_error_result.rs`.
+   LL|       |//   2. This test confirms the coverage generated when a program passes or fails an `assert!()` or
+   LL|       |//      related `assert_*!()` macro.
+   LL|       |//   3. Notably, the `assert` macros *do not* generate `TerminatorKind::Assert`. The macros produce
+   LL|       |//      conditional expressions, `TerminatorKind::SwitchInt` branches, and a possible call to
+   LL|       |//      `begin_panic_fmt()` (that begins a panic unwind, if the assertion test fails).
+   LL|       |//   4. `TerminatoKind::Assert` is, however, also present in the MIR generated for this test
+   LL|       |//      (and in many other coverage tests). The `Assert` terminator is typically generated by the
+   LL|       |//      Rust compiler to check for runtime failures, such as numeric overflows.
+
diff --git a/tests/coverage/assert.rs b/tests/coverage/assert.rs
new file mode 100644
index 00000000000..85e6662a6ad
--- /dev/null
+++ b/tests/coverage/assert.rs
@@ -0,0 +1,32 @@
+#![allow(unused_assignments)]
+// failure-status: 101
+
+fn might_fail_assert(one_plus_one: u32) {
+    println!("does 1 + 1 = {}?", one_plus_one);
+    assert_eq!(1 + 1, one_plus_one, "the argument was wrong");
+}
+
+fn main() -> Result<(), u8> {
+    let mut countdown = 10;
+    while countdown > 0 {
+        if countdown == 1 {
+            might_fail_assert(3);
+        } else if countdown < 5 {
+            might_fail_assert(2);
+        }
+        countdown -= 1;
+    }
+    Ok(())
+}
+
+// Notes:
+//   1. Compare this program and its coverage results to those of the very similar test
+//      `panic_unwind.rs`, and similar tests `abort.rs` and `try_error_result.rs`.
+//   2. This test confirms the coverage generated when a program passes or fails an `assert!()` or
+//      related `assert_*!()` macro.
+//   3. Notably, the `assert` macros *do not* generate `TerminatorKind::Assert`. The macros produce
+//      conditional expressions, `TerminatorKind::SwitchInt` branches, and a possible call to
+//      `begin_panic_fmt()` (that begins a panic unwind, if the assertion test fails).
+//   4. `TerminatoKind::Assert` is, however, also present in the MIR generated for this test
+//      (and in many other coverage tests). The `Assert` terminator is typically generated by the
+//      Rust compiler to check for runtime failures, such as numeric overflows.
diff --git a/tests/coverage/async.coverage b/tests/coverage/async.coverage
new file mode 100644
index 00000000000..07bc16c2d92
--- /dev/null
+++ b/tests/coverage/async.coverage
@@ -0,0 +1,139 @@
+   LL|       |#![allow(unused_assignments, dead_code)]
+   LL|       |
+   LL|       |// compile-flags: --edition=2018 -C opt-level=1
+   LL|       |
+   LL|      1|async fn c(x: u8) -> u8 {
+   LL|      1|    if x == 8 {
+   LL|      1|        1
+   LL|       |    } else {
+   LL|      0|        0
+   LL|       |    }
+   LL|      1|}
+   LL|       |
+   LL|      0|async fn d() -> u8 { 1 }
+   LL|       |
+   LL|      0|async fn e() -> u8 { 1 } // unused function; executor does not block on `g()`
+   LL|       |
+   LL|      1|async fn f() -> u8 { 1 }
+   LL|       |
+   LL|      0|async fn foo() -> [bool; 10] { [false; 10] } // unused function; executor does not block on `h()`
+   LL|       |
+   LL|      1|pub async fn g(x: u8) {
+   LL|      0|    match x {
+   LL|      0|        y if e().await == y => (),
+   LL|      0|        y if f().await == y => (),
+   LL|      0|        _ => (),
+   LL|       |    }
+   LL|      0|}
+   LL|       |
+   LL|      1|async fn h(x: usize) { // The function signature is counted when called, but the body is not
+   LL|      0|                       // executed (not awaited) so the open brace has a `0` count (at least when
+   LL|      0|                       // displayed with `llvm-cov show` in color-mode).
+   LL|      0|    match x {
+   LL|      0|        y if foo().await[y] => (),
+   LL|      0|        _ => (),
+   LL|       |    }
+   LL|      0|}
+   LL|       |
+   LL|      1|async fn i(x: u8) { // line coverage is 1, but there are 2 regions:
+   LL|      1|                    // (a) the function signature, counted when the function is called; and
+   LL|      1|                    // (b) the open brace for the function body, counted once when the body is
+   LL|      1|                    // executed asynchronously.
+   LL|      1|    match x {
+   LL|      1|        y if c(x).await == y + 1 => { d().await; }
+                      ^0        ^0                  ^0  ^0
+   LL|      1|        y if f().await == y + 1 => (),
+                      ^0       ^0                ^0
+   LL|      1|        _ => (),
+   LL|       |    }
+   LL|      1|}
+   LL|       |
+   LL|      1|fn j(x: u8) {
+   LL|      1|    // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`.
+   LL|      1|    fn c(x: u8) -> u8 {
+   LL|      1|        if x == 8 {
+   LL|      1|            1 // This line appears covered, but the 1-character expression span covering the `1`
+                          ^0
+   LL|      1|              // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because
+   LL|      1|              // `fn j()` executes the open brace for the function body, followed by the function's
+   LL|      1|              // first executable statement, `match x`. Inner function declarations are not
+   LL|      1|              // "visible" to the MIR for `j()`, so the code region counts all lines between the
+   LL|      1|              // open brace and the first statement as executed, which is, in a sense, true.
+   LL|      1|              // `llvm-cov show` overcomes this kind of situation by showing the actual counts
+   LL|      1|              // of the enclosed coverages, (that is, the `1` expression was not executed, and
+   LL|      1|              // accurately displays a `0`).
+   LL|      1|        } else {
+   LL|      1|            0
+   LL|      1|        }
+   LL|      1|    }
+   LL|      1|    fn d() -> u8 { 1 } // inner function is defined in-line, but the function is not executed
+                  ^0
+   LL|      1|    fn f() -> u8 { 1 }
+   LL|      1|    match x {
+   LL|      1|        y if c(x) == y + 1 => { d(); }
+                      ^0                    ^0
+   LL|      1|        y if f() == y + 1 => (),
+                      ^0                   ^0
+   LL|      1|        _ => (),
+   LL|       |    }
+   LL|      1|}
+   LL|       |
+   LL|      0|fn k(x: u8) { // unused function
+   LL|      0|    match x {
+   LL|      0|        1 => (),
+   LL|      0|        2 => (),
+   LL|      0|        _ => (),
+   LL|       |    }
+   LL|      0|}
+   LL|       |
+   LL|      1|fn l(x: u8) {
+   LL|      1|    match x {
+   LL|      0|        1 => (),
+   LL|      0|        2 => (),
+   LL|      1|        _ => (),
+   LL|       |    }
+   LL|      1|}
+   LL|       |
+   LL|      1|async fn m(x: u8) -> u8 { x - 1 }
+                                      ^0
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let _ = g(10);
+   LL|      1|    let _ = h(9);
+   LL|      1|    let mut future = Box::pin(i(8));
+   LL|      1|    j(7);
+   LL|      1|    l(6);
+   LL|      1|    let _ = m(5);
+   LL|      1|    executor::block_on(future.as_mut());
+   LL|      1|}
+   LL|       |
+   LL|       |mod executor {
+   LL|       |    use core::{
+   LL|       |        future::Future,
+   LL|       |        pin::Pin,
+   LL|       |        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+   LL|       |    };
+   LL|       |
+   LL|      1|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+   LL|      1|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+   LL|      1|        use std::hint::unreachable_unchecked;
+   LL|      1|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+   LL|      1|            |_| unsafe { unreachable_unchecked() }, // clone
+                              ^0
+   LL|      1|            |_| unsafe { unreachable_unchecked() }, // wake
+                              ^0
+   LL|      1|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+                              ^0
+   LL|      1|            |_| (),
+   LL|      1|        );
+   LL|      1|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+   LL|      1|        let mut context = Context::from_waker(&waker);
+   LL|       |
+   LL|       |        loop {
+   LL|      1|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+   LL|      1|                break val;
+   LL|      0|            }
+   LL|       |        }
+   LL|      1|    }
+   LL|       |}
+
diff --git a/tests/coverage/async.rs b/tests/coverage/async.rs
new file mode 100644
index 00000000000..efd9e62d64e
--- /dev/null
+++ b/tests/coverage/async.rs
@@ -0,0 +1,128 @@
+#![allow(unused_assignments, dead_code)]
+
+// compile-flags: --edition=2018 -C opt-level=1
+
+async fn c(x: u8) -> u8 {
+    if x == 8 {
+        1
+    } else {
+        0
+    }
+}
+
+async fn d() -> u8 { 1 }
+
+async fn e() -> u8 { 1 } // unused function; executor does not block on `g()`
+
+async fn f() -> u8 { 1 }
+
+async fn foo() -> [bool; 10] { [false; 10] } // unused function; executor does not block on `h()`
+
+pub async fn g(x: u8) {
+    match x {
+        y if e().await == y => (),
+        y if f().await == y => (),
+        _ => (),
+    }
+}
+
+async fn h(x: usize) { // The function signature is counted when called, but the body is not
+                       // executed (not awaited) so the open brace has a `0` count (at least when
+                       // displayed with `llvm-cov show` in color-mode).
+    match x {
+        y if foo().await[y] => (),
+        _ => (),
+    }
+}
+
+async fn i(x: u8) { // line coverage is 1, but there are 2 regions:
+                    // (a) the function signature, counted when the function is called; and
+                    // (b) the open brace for the function body, counted once when the body is
+                    // executed asynchronously.
+    match x {
+        y if c(x).await == y + 1 => { d().await; }
+        y if f().await == y + 1 => (),
+        _ => (),
+    }
+}
+
+fn j(x: u8) {
+    // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`.
+    fn c(x: u8) -> u8 {
+        if x == 8 {
+            1 // This line appears covered, but the 1-character expression span covering the `1`
+              // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because
+              // `fn j()` executes the open brace for the function body, followed by the function's
+              // first executable statement, `match x`. Inner function declarations are not
+              // "visible" to the MIR for `j()`, so the code region counts all lines between the
+              // open brace and the first statement as executed, which is, in a sense, true.
+              // `llvm-cov show` overcomes this kind of situation by showing the actual counts
+              // of the enclosed coverages, (that is, the `1` expression was not executed, and
+              // accurately displays a `0`).
+        } else {
+            0
+        }
+    }
+    fn d() -> u8 { 1 } // inner function is defined in-line, but the function is not executed
+    fn f() -> u8 { 1 }
+    match x {
+        y if c(x) == y + 1 => { d(); }
+        y if f() == y + 1 => (),
+        _ => (),
+    }
+}
+
+fn k(x: u8) { // unused function
+    match x {
+        1 => (),
+        2 => (),
+        _ => (),
+    }
+}
+
+fn l(x: u8) {
+    match x {
+        1 => (),
+        2 => (),
+        _ => (),
+    }
+}
+
+async fn m(x: u8) -> u8 { x - 1 }
+
+fn main() {
+    let _ = g(10);
+    let _ = h(9);
+    let mut future = Box::pin(i(8));
+    j(7);
+    l(6);
+    let _ = m(5);
+    executor::block_on(future.as_mut());
+}
+
+mod executor {
+    use core::{
+        future::Future,
+        pin::Pin,
+        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+    };
+
+    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+        use std::hint::unreachable_unchecked;
+        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+            |_| unsafe { unreachable_unchecked() }, // clone
+            |_| unsafe { unreachable_unchecked() }, // wake
+            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+            |_| (),
+        );
+        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+        let mut context = Context::from_waker(&waker);
+
+        loop {
+            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+                break val;
+            }
+        }
+    }
+}
diff --git a/tests/coverage/async2.coverage b/tests/coverage/async2.coverage
new file mode 100644
index 00000000000..fcb0a3aed64
--- /dev/null
+++ b/tests/coverage/async2.coverage
@@ -0,0 +1,104 @@
+   LL|       |// compile-flags: --edition=2018
+   LL|       |
+   LL|      1|fn non_async_func() {
+   LL|      1|    println!("non_async_func was covered");
+   LL|      1|    let b = true;
+   LL|      1|    if b {
+   LL|      1|        println!("non_async_func println in block");
+   LL|      1|    }
+                   ^0
+   LL|      1|}
+   LL|       |
+   LL|      1|async fn async_func() {
+   LL|      1|    println!("async_func was covered");
+   LL|      1|    let b = true;
+   LL|      1|    if b {
+   LL|      1|        println!("async_func println in block");
+   LL|      1|    }
+                   ^0
+   LL|      1|}
+   LL|       |
+   LL|      1|async fn async_func_just_println() {
+   LL|      1|    println!("async_func_just_println was covered");
+   LL|      1|}
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    println!("codecovsample::main");
+   LL|      1|
+   LL|      1|    non_async_func();
+   LL|      1|
+   LL|      1|    executor::block_on(async_func());
+   LL|      1|    executor::block_on(async_func_just_println());
+   LL|      1|}
+   LL|       |
+   LL|       |mod executor {
+   LL|       |    use core::{
+   LL|       |        future::Future,
+   LL|       |        pin::Pin,
+   LL|       |        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+   LL|       |    };
+   LL|       |
+   LL|      2|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+   LL|      2|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+   LL|      2|        use std::hint::unreachable_unchecked;
+   LL|      2|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+   LL|      2|            |_| unsafe { unreachable_unchecked() }, // clone
+                              ^0
+   LL|      2|            |_| unsafe { unreachable_unchecked() }, // wake
+                              ^0
+   LL|      2|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+                              ^0
+   LL|      2|            |_| (),
+   LL|      2|        );
+   LL|      2|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+   LL|      2|        let mut context = Context::from_waker(&waker);
+   LL|       |
+   LL|       |        loop {
+   LL|      2|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+   LL|      2|                break val;
+   LL|      0|            }
+   LL|       |        }
+   LL|      2|    }
+  ------------------
+  | async2::executor::block_on::<async2::async_func::{closure#0}>:
+  |   LL|      1|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+  |   LL|      1|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+  |   LL|      1|        use std::hint::unreachable_unchecked;
+  |   LL|      1|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+  |   LL|      1|            |_| unsafe { unreachable_unchecked() }, // clone
+  |   LL|      1|            |_| unsafe { unreachable_unchecked() }, // wake
+  |   LL|      1|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+  |   LL|      1|            |_| (),
+  |   LL|      1|        );
+  |   LL|      1|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+  |   LL|      1|        let mut context = Context::from_waker(&waker);
+  |   LL|       |
+  |   LL|       |        loop {
+  |   LL|      1|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+  |   LL|      1|                break val;
+  |   LL|      0|            }
+  |   LL|       |        }
+  |   LL|      1|    }
+  ------------------
+  | async2::executor::block_on::<async2::async_func_just_println::{closure#0}>:
+  |   LL|      1|    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+  |   LL|      1|        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+  |   LL|      1|        use std::hint::unreachable_unchecked;
+  |   LL|      1|        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+  |   LL|      1|            |_| unsafe { unreachable_unchecked() }, // clone
+  |   LL|      1|            |_| unsafe { unreachable_unchecked() }, // wake
+  |   LL|      1|            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+  |   LL|      1|            |_| (),
+  |   LL|      1|        );
+  |   LL|      1|        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+  |   LL|      1|        let mut context = Context::from_waker(&waker);
+  |   LL|       |
+  |   LL|       |        loop {
+  |   LL|      1|            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+  |   LL|      1|                break val;
+  |   LL|      0|            }
+  |   LL|       |        }
+  |   LL|      1|    }
+  ------------------
+   LL|       |}
+
diff --git a/tests/coverage/async2.rs b/tests/coverage/async2.rs
new file mode 100644
index 00000000000..2884ff297af
--- /dev/null
+++ b/tests/coverage/async2.rs
@@ -0,0 +1,57 @@
+// compile-flags: --edition=2018
+
+fn non_async_func() {
+    println!("non_async_func was covered");
+    let b = true;
+    if b {
+        println!("non_async_func println in block");
+    }
+}
+
+async fn async_func() {
+    println!("async_func was covered");
+    let b = true;
+    if b {
+        println!("async_func println in block");
+    }
+}
+
+async fn async_func_just_println() {
+    println!("async_func_just_println was covered");
+}
+
+fn main() {
+    println!("codecovsample::main");
+
+    non_async_func();
+
+    executor::block_on(async_func());
+    executor::block_on(async_func_just_println());
+}
+
+mod executor {
+    use core::{
+        future::Future,
+        pin::Pin,
+        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+    };
+
+    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+        use std::hint::unreachable_unchecked;
+        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+            |_| unsafe { unreachable_unchecked() }, // clone
+            |_| unsafe { unreachable_unchecked() }, // wake
+            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+            |_| (),
+        );
+        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+        let mut context = Context::from_waker(&waker);
+
+        loop {
+            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+                break val;
+            }
+        }
+    }
+}
diff --git a/tests/coverage/auxiliary/inline_always_with_dead_code.rs b/tests/coverage/auxiliary/inline_always_with_dead_code.rs
new file mode 100644
index 00000000000..9dc50dae25a
--- /dev/null
+++ b/tests/coverage/auxiliary/inline_always_with_dead_code.rs
@@ -0,0 +1,22 @@
+// compile-flags: -Cinstrument-coverage -Ccodegen-units=4 -Copt-level=0
+
+#![allow(dead_code)]
+
+mod foo {
+    #[inline(always)]
+    pub fn called() {}
+
+    fn uncalled() {}
+}
+
+pub mod bar {
+    pub fn call_me() {
+        super::foo::called();
+    }
+}
+
+pub mod baz {
+    pub fn call_me() {
+        super::foo::called();
+    }
+}
diff --git a/tests/coverage/auxiliary/unused_mod_helper.rs b/tests/coverage/auxiliary/unused_mod_helper.rs
new file mode 100644
index 00000000000..88c5dac65cb
--- /dev/null
+++ b/tests/coverage/auxiliary/unused_mod_helper.rs
@@ -0,0 +1,4 @@
+#[allow(dead_code)]
+pub fn never_called_function() {
+    println!("I am never called");
+}
diff --git a/tests/coverage/auxiliary/used_crate.rs b/tests/coverage/auxiliary/used_crate.rs
new file mode 100644
index 00000000000..c086ef21e1a
--- /dev/null
+++ b/tests/coverage/auxiliary/used_crate.rs
@@ -0,0 +1,103 @@
+#![allow(unused_assignments, unused_variables)]
+// Verify that coverage works with optimizations:
+// compile-flags: -C opt-level=3
+
+use std::fmt::Debug;
+
+pub fn used_function() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+    use_this_lib_crate();
+}
+
+pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+}
+// Expect for above function: `Unexecuted instantiation` (see below)
+pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+}
+
+pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+}
+
+pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+}
+
+pub fn unused_generic_function<T: Debug>(arg: T) {
+    println!("unused_generic_function with {:?}", arg);
+}
+
+pub fn unused_function() {
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 2;
+    if !is_true {
+        countdown = 20;
+    }
+}
+
+#[allow(dead_code)]
+fn unused_private_function() {
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 2;
+    if !is_true {
+        countdown = 20;
+    }
+}
+
+fn use_this_lib_crate() {
+    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
+    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
+        "used from library used_crate.rs",
+    );
+    let some_vec = vec![5, 6, 7, 8];
+    used_only_from_this_lib_crate_generic_function(some_vec);
+    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
+}
+
+// FIXME(#79651): "Unexecuted instantiation" errors appear in coverage results,
+// for example:
+//
+// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
+//
+// These notices appear when `llvm-cov` shows instantiations. This may be a
+// default option, but it can be suppressed with:
+//
+// ```shell
+// $ `llvm-cov show --show-instantiations=0 ...`
+// ```
+//
+// The notice is triggered because the function is unused by the library itself,
+// and when the library is compiled, a synthetic function is generated, so
+// unused function coverage can be reported. Coverage can be skipped for unused
+// generic functions with:
+//
+// ```shell
+// $ `rustc -Zunstable-options -C instrument-coverage=except-unused-generics ...`
+// ```
+//
+// Even though this function is used by `uses_crate.rs` (and
+// counted), with substitutions for `T`, those instantiations are only generated
+// when the generic function is actually used (from the binary, not from this
+// library crate). So the test result shows coverage for all instantiated
+// versions and their generic type substitutions, plus the `Unexecuted
+// instantiation` message for the non-substituted version. This is valid, but
+// unfortunately a little confusing.
+//
+// The library crate has its own coverage map, and the only way to show unused
+// coverage of a generic function is to include the generic function in the
+// coverage map, marked as an "unused function". If the library were used by
+// another binary that never used this generic function, then it would be valid
+// to show the unused generic, with unknown substitution (`_`).
+//
+// The alternative is to exclude all generics from being included in the "unused
+// functions" list, which would then omit coverage results for
+// `unused_generic_function<T>()`, below.
diff --git a/tests/coverage/auxiliary/used_inline_crate.rs b/tests/coverage/auxiliary/used_inline_crate.rs
new file mode 100644
index 00000000000..e8929de6b36
--- /dev/null
+++ b/tests/coverage/auxiliary/used_inline_crate.rs
@@ -0,0 +1,85 @@
+#![allow(unused_assignments, unused_variables)]
+// Verify that coverage works with optimizations:
+// compile-flags: -C opt-level=3
+
+use std::fmt::Debug;
+
+pub fn used_function() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+    use_this_lib_crate();
+}
+
+#[inline(always)]
+pub fn used_inline_function() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+    use_this_lib_crate();
+}
+
+#[inline(always)]
+pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+}
+// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
+
+#[inline(always)]
+pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+}
+
+#[inline(always)]
+pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+}
+
+#[inline(always)]
+pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+}
+
+#[inline(always)]
+pub fn unused_generic_function<T: Debug>(arg: T) {
+    println!("unused_generic_function with {:?}", arg);
+}
+
+#[inline(always)]
+pub fn unused_function() {
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 2;
+    if !is_true {
+        countdown = 20;
+    }
+}
+
+#[inline(always)]
+#[allow(dead_code)]
+fn unused_private_function() {
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 2;
+    if !is_true {
+        countdown = 20;
+    }
+}
+
+fn use_this_lib_crate() {
+    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
+    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
+        "used from library used_crate.rs",
+    );
+    let some_vec = vec![5, 6, 7, 8];
+    used_only_from_this_lib_crate_generic_function(some_vec);
+    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
+}
diff --git a/tests/coverage/bad_counter_ids.coverage b/tests/coverage/bad_counter_ids.coverage
new file mode 100644
index 00000000000..d69ebf160ea
--- /dev/null
+++ b/tests/coverage/bad_counter_ids.coverage
@@ -0,0 +1,69 @@
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |// compile-flags: --edition=2021 -Copt-level=0 -Zmir-opt-level=3
+   LL|       |
+   LL|       |// Regression test for <https://github.com/rust-lang/rust/issues/117012>.
+   LL|       |//
+   LL|       |// If some coverage counters were removed by MIR optimizations, we need to take
+   LL|       |// care not to refer to those counter IDs in coverage mappings, and instead
+   LL|       |// replace them with a constant zero value. If we don't, `llvm-cov` might see
+   LL|       |// a too-large counter ID and silently discard the entire function from its
+   LL|       |// coverage reports.
+   LL|       |
+   LL|      8|#[derive(Debug, PartialEq, Eq)]
+   LL|       |struct Foo(u32);
+   LL|       |
+   LL|      1|fn eq_good() {
+   LL|      1|    println!("a");
+   LL|      1|    assert_eq!(Foo(1), Foo(1));
+   LL|      1|}
+   LL|       |
+   LL|      1|fn eq_good_message() {
+   LL|      1|    println!("b");
+   LL|      1|    assert_eq!(Foo(1), Foo(1), "message b");
+                                             ^0
+   LL|      1|}
+   LL|       |
+   LL|      1|fn ne_good() {
+   LL|      1|    println!("c");
+   LL|      1|    assert_ne!(Foo(1), Foo(3));
+   LL|      1|}
+   LL|       |
+   LL|      1|fn ne_good_message() {
+   LL|      1|    println!("d");
+   LL|      1|    assert_ne!(Foo(1), Foo(3), "message d");
+                                             ^0
+   LL|      1|}
+   LL|       |
+   LL|      1|fn eq_bad() {
+   LL|      1|    println!("e");
+   LL|      1|    assert_eq!(Foo(1), Foo(3));
+   LL|      0|}
+   LL|       |
+   LL|      1|fn eq_bad_message() {
+   LL|      1|    println!("f");
+   LL|      1|    assert_eq!(Foo(1), Foo(3), "message f");
+   LL|      0|}
+   LL|       |
+   LL|      1|fn ne_bad() {
+   LL|      1|    println!("g");
+   LL|      1|    assert_ne!(Foo(1), Foo(1));
+   LL|      0|}
+   LL|       |
+   LL|      1|fn ne_bad_message() {
+   LL|      1|    println!("h");
+   LL|      1|    assert_ne!(Foo(1), Foo(1), "message h");
+   LL|      0|}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn main() {
+   LL|       |    eq_good();
+   LL|       |    eq_good_message();
+   LL|       |    ne_good();
+   LL|       |    ne_good_message();
+   LL|       |
+   LL|       |    assert!(std::panic::catch_unwind(eq_bad).is_err());
+   LL|       |    assert!(std::panic::catch_unwind(eq_bad_message).is_err());
+   LL|       |    assert!(std::panic::catch_unwind(ne_bad).is_err());
+   LL|       |    assert!(std::panic::catch_unwind(ne_bad_message).is_err());
+   LL|       |}
+
diff --git a/tests/coverage/bad_counter_ids.rs b/tests/coverage/bad_counter_ids.rs
new file mode 100644
index 00000000000..ef5460102b7
--- /dev/null
+++ b/tests/coverage/bad_counter_ids.rs
@@ -0,0 +1,66 @@
+#![feature(coverage_attribute)]
+// compile-flags: --edition=2021 -Copt-level=0 -Zmir-opt-level=3
+
+// Regression test for <https://github.com/rust-lang/rust/issues/117012>.
+//
+// If some coverage counters were removed by MIR optimizations, we need to take
+// care not to refer to those counter IDs in coverage mappings, and instead
+// replace them with a constant zero value. If we don't, `llvm-cov` might see
+// a too-large counter ID and silently discard the entire function from its
+// coverage reports.
+
+#[derive(Debug, PartialEq, Eq)]
+struct Foo(u32);
+
+fn eq_good() {
+    println!("a");
+    assert_eq!(Foo(1), Foo(1));
+}
+
+fn eq_good_message() {
+    println!("b");
+    assert_eq!(Foo(1), Foo(1), "message b");
+}
+
+fn ne_good() {
+    println!("c");
+    assert_ne!(Foo(1), Foo(3));
+}
+
+fn ne_good_message() {
+    println!("d");
+    assert_ne!(Foo(1), Foo(3), "message d");
+}
+
+fn eq_bad() {
+    println!("e");
+    assert_eq!(Foo(1), Foo(3));
+}
+
+fn eq_bad_message() {
+    println!("f");
+    assert_eq!(Foo(1), Foo(3), "message f");
+}
+
+fn ne_bad() {
+    println!("g");
+    assert_ne!(Foo(1), Foo(1));
+}
+
+fn ne_bad_message() {
+    println!("h");
+    assert_ne!(Foo(1), Foo(1), "message h");
+}
+
+#[coverage(off)]
+fn main() {
+    eq_good();
+    eq_good_message();
+    ne_good();
+    ne_good_message();
+
+    assert!(std::panic::catch_unwind(eq_bad).is_err());
+    assert!(std::panic::catch_unwind(eq_bad_message).is_err());
+    assert!(std::panic::catch_unwind(ne_bad).is_err());
+    assert!(std::panic::catch_unwind(ne_bad_message).is_err());
+}
diff --git a/tests/coverage/closure.coverage b/tests/coverage/closure.coverage
new file mode 100644
index 00000000000..67014f792c8
--- /dev/null
+++ b/tests/coverage/closure.coverage
@@ -0,0 +1,227 @@
+   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |// compile-flags: -C opt-level=2
+   LL|       |
+   LL|       |// This test used to be sensitive to certain coverage-specific hacks in
+   LL|       |// `rustc_middle/mir/mono.rs`, but those hacks were later cleaned up by
+   LL|       |// <https://github.com/rust-lang/rust/pull/83666>.
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      1|    // dependent conditions.
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|    let is_false = !is_true;
+   LL|      1|
+   LL|      1|    let mut some_string = Some(String::from("the string content"));
+   LL|      1|    println!(
+   LL|      1|        "The string or alt: {}"
+   LL|      1|        ,
+   LL|      1|        some_string
+   LL|      1|            .
+   LL|      1|            unwrap_or_else
+   LL|      1|        (
+   LL|      1|            ||
+   LL|      0|            {
+   LL|      0|                let mut countdown = 0;
+   LL|      0|                if is_false {
+   LL|      0|                    countdown = 10;
+   LL|      0|                }
+   LL|      0|                "alt string 1".to_owned()
+   LL|      1|            }
+   LL|      1|        )
+   LL|      1|    );
+   LL|      1|
+   LL|      1|    some_string = Some(String::from("the string content"));
+   LL|      1|    let
+   LL|      1|        a
+   LL|       |    =
+   LL|       |        ||
+   LL|      0|    {
+   LL|      0|        let mut countdown = 0;
+   LL|      0|        if is_false {
+   LL|      0|            countdown = 10;
+   LL|      0|        }
+   LL|      0|        "alt string 2".to_owned()
+   LL|      0|    };
+   LL|      1|    println!(
+   LL|      1|        "The string or alt: {}"
+   LL|      1|        ,
+   LL|      1|        some_string
+   LL|      1|            .
+   LL|      1|            unwrap_or_else
+   LL|      1|        (
+   LL|      1|            a
+   LL|      1|        )
+   LL|      1|    );
+   LL|      1|
+   LL|      1|    some_string = None;
+   LL|      1|    println!(
+   LL|      1|        "The string or alt: {}"
+   LL|      1|        ,
+   LL|      1|        some_string
+   LL|      1|            .
+   LL|      1|            unwrap_or_else
+   LL|      1|        (
+   LL|      1|            ||
+   LL|      1|            {
+   LL|      1|                let mut countdown = 0;
+   LL|      1|                if is_false {
+   LL|      0|                    countdown = 10;
+   LL|      1|                }
+   LL|      1|                "alt string 3".to_owned()
+   LL|      1|            }
+   LL|      1|        )
+   LL|      1|    );
+   LL|      1|
+   LL|      1|    some_string = None;
+   LL|      1|    let
+   LL|      1|        a
+   LL|       |    =
+   LL|       |        ||
+   LL|      1|    {
+   LL|      1|        let mut countdown = 0;
+   LL|      1|        if is_false {
+   LL|      0|            countdown = 10;
+   LL|      1|        }
+   LL|      1|        "alt string 4".to_owned()
+   LL|      1|    };
+   LL|      1|    println!(
+   LL|      1|        "The string or alt: {}"
+   LL|      1|        ,
+   LL|      1|        some_string
+   LL|      1|            .
+   LL|      1|            unwrap_or_else
+   LL|      1|        (
+   LL|      1|            a
+   LL|      1|        )
+   LL|      1|    );
+   LL|      1|
+   LL|      1|    let
+   LL|      1|        quote_closure
+   LL|       |    =
+   LL|       |        |val|
+   LL|      5|    {
+   LL|      5|        let mut countdown = 0;
+   LL|      5|        if is_false {
+   LL|      0|            countdown = 10;
+   LL|      5|        }
+   LL|      5|        format!("'{}'", val)
+   LL|      5|    };
+   LL|      1|    println!(
+   LL|      1|        "Repeated, quoted string: {:?}"
+   LL|      1|        ,
+   LL|      1|        std::iter::repeat("repeat me")
+   LL|      1|            .take(5)
+   LL|      1|            .map
+   LL|      1|        (
+   LL|      1|            quote_closure
+   LL|      1|        )
+   LL|      1|            .collect::<Vec<_>>()
+   LL|      1|    );
+   LL|      1|
+   LL|      1|    let
+   LL|      1|        _unused_closure
+   LL|       |    =
+   LL|       |        |
+   LL|       |            mut countdown
+   LL|       |        |
+   LL|      0|    {
+   LL|      0|        if is_false {
+   LL|      0|            countdown = 10;
+   LL|      0|        }
+   LL|      0|        "closure should be unused".to_owned()
+   LL|      0|    };
+   LL|       |
+   LL|      1|    let mut countdown = 10;
+   LL|      1|    let _short_unused_closure = | _unused_arg: u8 | countdown += 1;
+                                                                  ^0
+   LL|       |
+   LL|       |
+   LL|      1|    let short_used_covered_closure_macro = | used_arg: u8 | println!("called");
+   LL|      1|    let short_used_not_covered_closure_macro = | used_arg: u8 | println!("not called");
+                                                                              ^0
+   LL|      1|    let _short_unused_closure_macro = | _unused_arg: u8 | println!("not called");
+                                                                        ^0
+   LL|       |
+   LL|       |
+   LL|       |
+   LL|       |
+   LL|      1|    let _short_unused_closure_block = | _unused_arg: u8 | { println!("not called") };
+                                                                        ^0
+   LL|       |
+   LL|      1|    let _shortish_unused_closure = | _unused_arg: u8 | {
+   LL|      0|        println!("not called")
+   LL|      0|    };
+   LL|       |
+   LL|      1|    let _as_short_unused_closure = |
+   LL|       |        _unused_arg: u8
+   LL|      0|    | { println!("not called") };
+   LL|       |
+   LL|      1|    let _almost_as_short_unused_closure = |
+   LL|       |        _unused_arg: u8
+   LL|      0|    | { println!("not called") }
+   LL|       |    ;
+   LL|       |
+   LL|       |
+   LL|       |
+   LL|       |
+   LL|       |
+   LL|      1|    let _short_unused_closure_line_break_no_block = | _unused_arg: u8 |
+   LL|      0|println!("not called")
+   LL|       |    ;
+   LL|       |
+   LL|      1|    let _short_unused_closure_line_break_no_block2 =
+   LL|       |        | _unused_arg: u8 |
+   LL|      0|            println!(
+   LL|      0|                "not called"
+   LL|      0|            )
+   LL|       |    ;
+   LL|       |
+   LL|      1|    let short_used_not_covered_closure_line_break_no_block_embedded_branch =
+   LL|       |        | _unused_arg: u8 |
+   LL|      0|            println!(
+   LL|      0|                "not called: {}",
+   LL|      0|                if is_true { "check" } else { "me" }
+   LL|      0|            )
+   LL|       |    ;
+   LL|       |
+   LL|      1|    let short_used_not_covered_closure_line_break_block_embedded_branch =
+   LL|       |        | _unused_arg: u8 |
+   LL|      0|        {
+   LL|      0|            println!(
+   LL|      0|                "not called: {}",
+   LL|      0|                if is_true { "check" } else { "me" }
+   LL|       |            )
+   LL|      0|        }
+   LL|       |    ;
+   LL|       |
+   LL|      1|    let short_used_covered_closure_line_break_no_block_embedded_branch =
+   LL|       |        | _unused_arg: u8 |
+   LL|      1|            println!(
+   LL|      1|                "not called: {}",
+   LL|      1|                if is_true { "check" } else { "me" }
+                                                            ^0
+   LL|      1|            )
+   LL|       |    ;
+   LL|       |
+   LL|      1|    let short_used_covered_closure_line_break_block_embedded_branch =
+   LL|       |        | _unused_arg: u8 |
+   LL|      1|        {
+   LL|      1|            println!(
+   LL|      1|                "not called: {}",
+   LL|      1|                if is_true { "check" } else { "me" }
+                                                            ^0
+   LL|       |            )
+   LL|      1|        }
+   LL|       |    ;
+   LL|       |
+   LL|      1|    if is_false {
+   LL|      0|        short_used_not_covered_closure_macro(0);
+   LL|      0|        short_used_not_covered_closure_line_break_no_block_embedded_branch(0);
+   LL|      0|        short_used_not_covered_closure_line_break_block_embedded_branch(0);
+   LL|      1|    }
+   LL|      1|    short_used_covered_closure_macro(0);
+   LL|      1|    short_used_covered_closure_line_break_no_block_embedded_branch(0);
+   LL|      1|    short_used_covered_closure_line_break_block_embedded_branch(0);
+   LL|      1|}
+
diff --git a/tests/coverage/closure.rs b/tests/coverage/closure.rs
new file mode 100644
index 00000000000..16a2c4e33bd
--- /dev/null
+++ b/tests/coverage/closure.rs
@@ -0,0 +1,220 @@
+#![allow(unused_assignments, unused_variables)]
+// compile-flags: -C opt-level=2
+
+// This test used to be sensitive to certain coverage-specific hacks in
+// `rustc_middle/mir/mono.rs`, but those hacks were later cleaned up by
+// <https://github.com/rust-lang/rust/pull/83666>.
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+    let is_false = !is_true;
+
+    let mut some_string = Some(String::from("the string content"));
+    println!(
+        "The string or alt: {}"
+        ,
+        some_string
+            .
+            unwrap_or_else
+        (
+            ||
+            {
+                let mut countdown = 0;
+                if is_false {
+                    countdown = 10;
+                }
+                "alt string 1".to_owned()
+            }
+        )
+    );
+
+    some_string = Some(String::from("the string content"));
+    let
+        a
+    =
+        ||
+    {
+        let mut countdown = 0;
+        if is_false {
+            countdown = 10;
+        }
+        "alt string 2".to_owned()
+    };
+    println!(
+        "The string or alt: {}"
+        ,
+        some_string
+            .
+            unwrap_or_else
+        (
+            a
+        )
+    );
+
+    some_string = None;
+    println!(
+        "The string or alt: {}"
+        ,
+        some_string
+            .
+            unwrap_or_else
+        (
+            ||
+            {
+                let mut countdown = 0;
+                if is_false {
+                    countdown = 10;
+                }
+                "alt string 3".to_owned()
+            }
+        )
+    );
+
+    some_string = None;
+    let
+        a
+    =
+        ||
+    {
+        let mut countdown = 0;
+        if is_false {
+            countdown = 10;
+        }
+        "alt string 4".to_owned()
+    };
+    println!(
+        "The string or alt: {}"
+        ,
+        some_string
+            .
+            unwrap_or_else
+        (
+            a
+        )
+    );
+
+    let
+        quote_closure
+    =
+        |val|
+    {
+        let mut countdown = 0;
+        if is_false {
+            countdown = 10;
+        }
+        format!("'{}'", val)
+    };
+    println!(
+        "Repeated, quoted string: {:?}"
+        ,
+        std::iter::repeat("repeat me")
+            .take(5)
+            .map
+        (
+            quote_closure
+        )
+            .collect::<Vec<_>>()
+    );
+
+    let
+        _unused_closure
+    =
+        |
+            mut countdown
+        |
+    {
+        if is_false {
+            countdown = 10;
+        }
+        "closure should be unused".to_owned()
+    };
+
+    let mut countdown = 10;
+    let _short_unused_closure = | _unused_arg: u8 | countdown += 1;
+
+
+    let short_used_covered_closure_macro = | used_arg: u8 | println!("called");
+    let short_used_not_covered_closure_macro = | used_arg: u8 | println!("not called");
+    let _short_unused_closure_macro = | _unused_arg: u8 | println!("not called");
+
+
+
+
+    let _short_unused_closure_block = | _unused_arg: u8 | { println!("not called") };
+
+    let _shortish_unused_closure = | _unused_arg: u8 | {
+        println!("not called")
+    };
+
+    let _as_short_unused_closure = |
+        _unused_arg: u8
+    | { println!("not called") };
+
+    let _almost_as_short_unused_closure = |
+        _unused_arg: u8
+    | { println!("not called") }
+    ;
+
+
+
+
+
+    let _short_unused_closure_line_break_no_block = | _unused_arg: u8 |
+println!("not called")
+    ;
+
+    let _short_unused_closure_line_break_no_block2 =
+        | _unused_arg: u8 |
+            println!(
+                "not called"
+            )
+    ;
+
+    let short_used_not_covered_closure_line_break_no_block_embedded_branch =
+        | _unused_arg: u8 |
+            println!(
+                "not called: {}",
+                if is_true { "check" } else { "me" }
+            )
+    ;
+
+    let short_used_not_covered_closure_line_break_block_embedded_branch =
+        | _unused_arg: u8 |
+        {
+            println!(
+                "not called: {}",
+                if is_true { "check" } else { "me" }
+            )
+        }
+    ;
+
+    let short_used_covered_closure_line_break_no_block_embedded_branch =
+        | _unused_arg: u8 |
+            println!(
+                "not called: {}",
+                if is_true { "check" } else { "me" }
+            )
+    ;
+
+    let short_used_covered_closure_line_break_block_embedded_branch =
+        | _unused_arg: u8 |
+        {
+            println!(
+                "not called: {}",
+                if is_true { "check" } else { "me" }
+            )
+        }
+    ;
+
+    if is_false {
+        short_used_not_covered_closure_macro(0);
+        short_used_not_covered_closure_line_break_no_block_embedded_branch(0);
+        short_used_not_covered_closure_line_break_block_embedded_branch(0);
+    }
+    short_used_covered_closure_macro(0);
+    short_used_covered_closure_line_break_no_block_embedded_branch(0);
+    short_used_covered_closure_line_break_block_embedded_branch(0);
+}
diff --git a/tests/coverage/closure_bug.coverage b/tests/coverage/closure_bug.coverage
new file mode 100644
index 00000000000..f3299834bce
--- /dev/null
+++ b/tests/coverage/closure_bug.coverage
@@ -0,0 +1,53 @@
+   LL|       |// Regression test for #115930.
+   LL|       |// All of these closures are identical, and should produce identical output in
+   LL|       |// the coverage report. However, an unstable sort was causing them to be treated
+   LL|       |// inconsistently when preparing coverage spans.
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let truthy = std::env::args().len() == 1;
+   LL|      1|
+   LL|      1|    let a
+   LL|       |        =
+   LL|       |        |
+   LL|       |        |
+   LL|      2|        if truthy { true } else { false };
+                                                ^0
+   LL|       |
+   LL|      1|    a();
+   LL|      1|    if truthy { a(); }
+                                    ^0
+   LL|       |
+   LL|      1|    let b
+   LL|       |        =
+   LL|       |        |
+   LL|       |        |
+   LL|      2|        if truthy { true } else { false };
+                                                ^0
+   LL|       |
+   LL|      1|    b();
+   LL|      1|    if truthy { b(); }
+                                    ^0
+   LL|       |
+   LL|      1|    let c
+   LL|       |        =
+   LL|       |        |
+   LL|       |        |
+   LL|      2|        if truthy { true } else { false };
+                                                ^0
+   LL|       |
+   LL|      1|    c();
+   LL|      1|    if truthy { c(); }
+                                    ^0
+   LL|       |
+   LL|      1|    let d
+   LL|       |        =
+   LL|       |        |
+   LL|       |        |
+   LL|      2|        if truthy { true } else { false };
+                                                ^0
+   LL|       |
+   LL|      1|    d();
+   LL|      1|    if truthy { d(); }
+                                    ^0
+   LL|      1|}
+
diff --git a/tests/coverage/closure_bug.rs b/tests/coverage/closure_bug.rs
new file mode 100644
index 00000000000..739bc5f0b51
--- /dev/null
+++ b/tests/coverage/closure_bug.rs
@@ -0,0 +1,44 @@
+// Regression test for #115930.
+// All of these closures are identical, and should produce identical output in
+// the coverage report. However, an unstable sort was causing them to be treated
+// inconsistently when preparing coverage spans.
+
+fn main() {
+    let truthy = std::env::args().len() == 1;
+
+    let a
+        =
+        |
+        |
+        if truthy { true } else { false };
+
+    a();
+    if truthy { a(); }
+
+    let b
+        =
+        |
+        |
+        if truthy { true } else { false };
+
+    b();
+    if truthy { b(); }
+
+    let c
+        =
+        |
+        |
+        if truthy { true } else { false };
+
+    c();
+    if truthy { c(); }
+
+    let d
+        =
+        |
+        |
+        if truthy { true } else { false };
+
+    d();
+    if truthy { d(); }
+}
diff --git a/tests/coverage/closure_macro.coverage b/tests/coverage/closure_macro.coverage
new file mode 100644
index 00000000000..0f2c917e090
--- /dev/null
+++ b/tests/coverage/closure_macro.coverage
@@ -0,0 +1,42 @@
+   LL|       |// compile-flags: --edition=2018
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |
+   LL|       |macro_rules! bail {
+   LL|       |    ($msg:literal $(,)?) => {
+   LL|       |        if $msg.len() > 0 {
+   LL|       |            println!("no msg");
+   LL|       |        } else {
+   LL|       |            println!($msg);
+   LL|       |        }
+   LL|       |        return Err(String::from($msg));
+   LL|       |    };
+   LL|       |}
+   LL|       |
+   LL|       |macro_rules! on_error {
+   LL|       |    ($value:expr, $error_message:expr) => {
+   LL|       |        $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
+   LL|       |            let message = format!($error_message, e);
+   LL|       |            if message.len() > 0 {
+   LL|       |                println!("{}", message);
+   LL|       |                Ok(String::from("ok"))
+   LL|       |            } else {
+   LL|       |                bail!("error");
+   LL|       |            }
+   LL|       |        })
+   LL|       |    };
+   LL|       |}
+   LL|       |
+   LL|      1|fn load_configuration_files() -> Result<String, String> {
+   LL|      1|    Ok(String::from("config"))
+   LL|      1|}
+   LL|       |
+   LL|      1|pub fn main() -> Result<(), String> {
+   LL|      1|    println!("Starting service");
+   LL|      1|    let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
+                                                                                                 ^0
+   LL|       |
+   LL|      1|    let startup_delay_duration = String::from("arg");
+   LL|      1|    let _ = (config, startup_delay_duration);
+   LL|      1|    Ok(())
+   LL|      1|}
+
diff --git a/tests/coverage/closure_macro.rs b/tests/coverage/closure_macro.rs
new file mode 100644
index 00000000000..9b289141c2e
--- /dev/null
+++ b/tests/coverage/closure_macro.rs
@@ -0,0 +1,40 @@
+// compile-flags: --edition=2018
+#![feature(coverage_attribute)]
+
+macro_rules! bail {
+    ($msg:literal $(,)?) => {
+        if $msg.len() > 0 {
+            println!("no msg");
+        } else {
+            println!($msg);
+        }
+        return Err(String::from($msg));
+    };
+}
+
+macro_rules! on_error {
+    ($value:expr, $error_message:expr) => {
+        $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
+            let message = format!($error_message, e);
+            if message.len() > 0 {
+                println!("{}", message);
+                Ok(String::from("ok"))
+            } else {
+                bail!("error");
+            }
+        })
+    };
+}
+
+fn load_configuration_files() -> Result<String, String> {
+    Ok(String::from("config"))
+}
+
+pub fn main() -> Result<(), String> {
+    println!("Starting service");
+    let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
+
+    let startup_delay_duration = String::from("arg");
+    let _ = (config, startup_delay_duration);
+    Ok(())
+}
diff --git a/tests/coverage/closure_macro_async.coverage b/tests/coverage/closure_macro_async.coverage
new file mode 100644
index 00000000000..74247f1bc6f
--- /dev/null
+++ b/tests/coverage/closure_macro_async.coverage
@@ -0,0 +1,79 @@
+   LL|       |// compile-flags: --edition=2018
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |
+   LL|       |macro_rules! bail {
+   LL|       |    ($msg:literal $(,)?) => {
+   LL|       |        if $msg.len() > 0 {
+   LL|       |            println!("no msg");
+   LL|       |        } else {
+   LL|       |            println!($msg);
+   LL|       |        }
+   LL|       |        return Err(String::from($msg));
+   LL|       |    };
+   LL|       |}
+   LL|       |
+   LL|       |macro_rules! on_error {
+   LL|       |    ($value:expr, $error_message:expr) => {
+   LL|       |        $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
+   LL|       |            let message = format!($error_message, e);
+   LL|       |            if message.len() > 0 {
+   LL|       |                println!("{}", message);
+   LL|       |                Ok(String::from("ok"))
+   LL|       |            } else {
+   LL|       |                bail!("error");
+   LL|       |            }
+   LL|       |        })
+   LL|       |    };
+   LL|       |}
+   LL|       |
+   LL|      1|fn load_configuration_files() -> Result<String, String> {
+   LL|      1|    Ok(String::from("config"))
+   LL|      1|}
+   LL|       |
+   LL|      1|pub async fn test() -> Result<(), String> {
+   LL|      1|    println!("Starting service");
+   LL|      1|    let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
+                                                                                                 ^0
+   LL|       |
+   LL|      1|    let startup_delay_duration = String::from("arg");
+   LL|      1|    let _ = (config, startup_delay_duration);
+   LL|      1|    Ok(())
+   LL|      1|}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn main() {
+   LL|       |    executor::block_on(test()).unwrap();
+   LL|       |}
+   LL|       |
+   LL|       |mod executor {
+   LL|       |    use core::{
+   LL|       |        future::Future,
+   LL|       |        pin::Pin,
+   LL|       |        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+   LL|       |    };
+   LL|       |
+   LL|       |    #[coverage(off)]
+   LL|       |    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+   LL|       |        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+   LL|       |        use std::hint::unreachable_unchecked;
+   LL|       |        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+   LL|       |            #[coverage(off)]
+   LL|       |            |_| unsafe { unreachable_unchecked() }, // clone
+   LL|       |            #[coverage(off)]
+   LL|       |            |_| unsafe { unreachable_unchecked() }, // wake
+   LL|       |            #[coverage(off)]
+   LL|       |            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+   LL|       |            #[coverage(off)]
+   LL|       |            |_| (),
+   LL|       |        );
+   LL|       |        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+   LL|       |        let mut context = Context::from_waker(&waker);
+   LL|       |
+   LL|       |        loop {
+   LL|       |            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+   LL|       |                break val;
+   LL|       |            }
+   LL|       |        }
+   LL|       |    }
+   LL|       |}
+
diff --git a/tests/coverage/closure_macro_async.rs b/tests/coverage/closure_macro_async.rs
new file mode 100644
index 00000000000..b4275599e59
--- /dev/null
+++ b/tests/coverage/closure_macro_async.rs
@@ -0,0 +1,77 @@
+// compile-flags: --edition=2018
+#![feature(coverage_attribute)]
+
+macro_rules! bail {
+    ($msg:literal $(,)?) => {
+        if $msg.len() > 0 {
+            println!("no msg");
+        } else {
+            println!($msg);
+        }
+        return Err(String::from($msg));
+    };
+}
+
+macro_rules! on_error {
+    ($value:expr, $error_message:expr) => {
+        $value.or_else(|e| { // FIXME(85000): no coverage in closure macros
+            let message = format!($error_message, e);
+            if message.len() > 0 {
+                println!("{}", message);
+                Ok(String::from("ok"))
+            } else {
+                bail!("error");
+            }
+        })
+    };
+}
+
+fn load_configuration_files() -> Result<String, String> {
+    Ok(String::from("config"))
+}
+
+pub async fn test() -> Result<(), String> {
+    println!("Starting service");
+    let config = on_error!(load_configuration_files(), "Error loading configs: {}")?;
+
+    let startup_delay_duration = String::from("arg");
+    let _ = (config, startup_delay_duration);
+    Ok(())
+}
+
+#[coverage(off)]
+fn main() {
+    executor::block_on(test()).unwrap();
+}
+
+mod executor {
+    use core::{
+        future::Future,
+        pin::Pin,
+        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+    };
+
+    #[coverage(off)]
+    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+        let mut future = unsafe { Pin::new_unchecked(&mut future) };
+        use std::hint::unreachable_unchecked;
+        static VTABLE: RawWakerVTable = RawWakerVTable::new(
+            #[coverage(off)]
+            |_| unsafe { unreachable_unchecked() }, // clone
+            #[coverage(off)]
+            |_| unsafe { unreachable_unchecked() }, // wake
+            #[coverage(off)]
+            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
+            #[coverage(off)]
+            |_| (),
+        );
+        let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };
+        let mut context = Context::from_waker(&waker);
+
+        loop {
+            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+                break val;
+            }
+        }
+    }
+}
diff --git a/tests/coverage/conditions.coverage b/tests/coverage/conditions.coverage
new file mode 100644
index 00000000000..473335ff641
--- /dev/null
+++ b/tests/coverage/conditions.coverage
@@ -0,0 +1,93 @@
+   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let mut countdown = 0;
+   LL|      1|    if true {
+   LL|      1|        countdown = 10;
+   LL|      1|    }
+                   ^0
+   LL|       |
+   LL|       |    const B: u32 = 100;
+   LL|      1|    let x = if countdown > 7 {
+   LL|      1|        countdown -= 4;
+   LL|      1|        B
+   LL|      0|    } else if countdown > 2 {
+   LL|      0|        if countdown < 1 || countdown > 5 || countdown != 9 {
+   LL|      0|            countdown = 0;
+   LL|      0|        }
+   LL|      0|        countdown -= 5;
+   LL|      0|        countdown
+   LL|       |    } else {
+   LL|      0|        return;
+   LL|       |    };
+   LL|       |
+   LL|      1|    let mut countdown = 0;
+   LL|      1|    if true {
+   LL|      1|        countdown = 10;
+   LL|      1|    }
+                   ^0
+   LL|       |
+   LL|      1|    if countdown > 7 {
+   LL|      1|        countdown -= 4;
+   LL|      1|    } else if countdown > 2 {
+                            ^0
+   LL|      0|        if countdown < 1 || countdown > 5 || countdown != 9 {
+   LL|      0|            countdown = 0;
+   LL|      0|        }
+   LL|      0|        countdown -= 5;
+   LL|       |    } else {
+   LL|      0|        return;
+   LL|       |    }
+   LL|       |
+   LL|      1|    if true {
+   LL|      1|        let mut countdown = 0;
+   LL|      1|        if true {
+   LL|      1|            countdown = 10;
+   LL|      1|        }
+                       ^0
+   LL|       |
+   LL|      1|        if countdown > 7 {
+   LL|      1|            countdown -= 4;
+   LL|      1|        }
+   LL|      0|        else if countdown > 2 {
+   LL|      0|            if countdown < 1 || countdown > 5 || countdown != 9 {
+   LL|      0|                countdown = 0;
+   LL|      0|            }
+   LL|      0|            countdown -= 5;
+   LL|       |        } else {
+   LL|      0|            return;
+   LL|       |        }
+   LL|      0|    }
+   LL|       |
+   LL|      1|    let mut countdown = 0;
+   LL|      1|    if true {
+   LL|      1|        countdown = 1;
+   LL|      1|    }
+                   ^0
+   LL|       |
+   LL|      1|    let z = if countdown > 7 {
+                      ^0
+   LL|      0|        countdown -= 4;
+   LL|      1|    } else if countdown > 2 {
+   LL|      0|        if countdown < 1 || countdown > 5 || countdown != 9 {
+   LL|      0|            countdown = 0;
+   LL|      0|        }
+   LL|      0|        countdown -= 5;
+   LL|       |    } else {
+   LL|      1|        let should_be_reachable = countdown;
+   LL|      1|        println!("reached");
+   LL|      1|        return;
+   LL|       |    };
+   LL|       |
+   LL|      0|    let w = if countdown > 7 {
+   LL|      0|        countdown -= 4;
+   LL|      0|    } else if countdown > 2 {
+   LL|      0|        if countdown < 1 || countdown > 5 || countdown != 9 {
+   LL|      0|            countdown = 0;
+   LL|      0|        }
+   LL|      0|        countdown -= 5;
+   LL|       |    } else {
+   LL|      0|        return;
+   LL|       |    };
+   LL|      1|}
+
diff --git a/tests/coverage/conditions.rs b/tests/coverage/conditions.rs
new file mode 100644
index 00000000000..fa7f2a116c2
--- /dev/null
+++ b/tests/coverage/conditions.rs
@@ -0,0 +1,86 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    let mut countdown = 0;
+    if true {
+        countdown = 10;
+    }
+
+    const B: u32 = 100;
+    let x = if countdown > 7 {
+        countdown -= 4;
+        B
+    } else if countdown > 2 {
+        if countdown < 1 || countdown > 5 || countdown != 9 {
+            countdown = 0;
+        }
+        countdown -= 5;
+        countdown
+    } 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;
+    }
+
+    if true {
+        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 = 1;
+    }
+
+    let z = if countdown > 7 {
+        countdown -= 4;
+    } else if countdown > 2 {
+        if countdown < 1 || countdown > 5 || countdown != 9 {
+            countdown = 0;
+        }
+        countdown -= 5;
+    } else {
+        let should_be_reachable = countdown;
+        println!("reached");
+        return;
+    };
+
+    let w = 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/tests/coverage/continue.coverage b/tests/coverage/continue.coverage
new file mode 100644
index 00000000000..4916cac0038
--- /dev/null
+++ b/tests/coverage/continue.coverage
@@ -0,0 +1,70 @@
+   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|
+   LL|      1|    let mut x = 0;
+   LL|     11|    for _ in 0..10 {
+   LL|     10|        match is_true {
+   LL|       |            true => {
+   LL|     10|                continue;
+   LL|       |            }
+   LL|      0|            _ => {
+   LL|      0|                x = 1;
+   LL|      0|            }
+   LL|      0|        }
+   LL|      0|        x = 3;
+   LL|       |    }
+   LL|     11|    for _ in 0..10 {
+   LL|     10|        match is_true {
+   LL|      0|            false => {
+   LL|      0|                x = 1;
+   LL|      0|            }
+   LL|       |            _ => {
+   LL|     10|                continue;
+   LL|       |            }
+   LL|       |        }
+   LL|      0|        x = 3;
+   LL|       |    }
+   LL|     11|    for _ in 0..10 {
+   LL|     10|        match is_true {
+   LL|     10|            true => {
+   LL|     10|                x = 1;
+   LL|     10|            }
+   LL|       |            _ => {
+   LL|      0|                continue;
+   LL|       |            }
+   LL|       |        }
+   LL|     10|        x = 3;
+   LL|       |    }
+   LL|     11|    for _ in 0..10 {
+   LL|     10|        if is_true {
+   LL|     10|            continue;
+   LL|      0|        }
+   LL|      0|        x = 3;
+   LL|       |    }
+   LL|     11|    for _ in 0..10 {
+   LL|     10|        match is_true {
+   LL|      0|            false => {
+   LL|      0|                x = 1;
+   LL|      0|            }
+   LL|     10|            _ => {
+   LL|     10|                let _ = x;
+   LL|     10|            }
+   LL|       |        }
+   LL|     10|        x = 3;
+   LL|       |    }
+   LL|      1|    for _ in 0..10 {
+   LL|      1|        match is_true {
+   LL|      0|            false => {
+   LL|      0|                x = 1;
+   LL|      0|            }
+   LL|       |            _ => {
+   LL|      1|                break;
+   LL|       |            }
+   LL|       |        }
+   LL|      0|        x = 3;
+   LL|       |    }
+   LL|      1|    let _ = x;
+   LL|      1|}
+
diff --git a/tests/coverage/continue.rs b/tests/coverage/continue.rs
new file mode 100644
index 00000000000..624aa98341b
--- /dev/null
+++ b/tests/coverage/continue.rs
@@ -0,0 +1,69 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    let is_true = std::env::args().len() == 1;
+
+    let mut x = 0;
+    for _ in 0..10 {
+        match is_true {
+            true => {
+                continue;
+            }
+            _ => {
+                x = 1;
+            }
+        }
+        x = 3;
+    }
+    for _ in 0..10 {
+        match is_true {
+            false => {
+                x = 1;
+            }
+            _ => {
+                continue;
+            }
+        }
+        x = 3;
+    }
+    for _ in 0..10 {
+        match is_true {
+            true => {
+                x = 1;
+            }
+            _ => {
+                continue;
+            }
+        }
+        x = 3;
+    }
+    for _ in 0..10 {
+        if is_true {
+            continue;
+        }
+        x = 3;
+    }
+    for _ in 0..10 {
+        match is_true {
+            false => {
+                x = 1;
+            }
+            _ => {
+                let _ = x;
+            }
+        }
+        x = 3;
+    }
+    for _ in 0..10 {
+        match is_true {
+            false => {
+                x = 1;
+            }
+            _ => {
+                break;
+            }
+        }
+        x = 3;
+    }
+    let _ = x;
+}
diff --git a/tests/coverage/coroutine.coverage b/tests/coverage/coroutine.coverage
new file mode 100644
index 00000000000..3a9791a0dbd
--- /dev/null
+++ b/tests/coverage/coroutine.coverage
@@ -0,0 +1,32 @@
+   LL|       |#![feature(coroutines, coroutine_trait)]
+   LL|       |
+   LL|       |use std::ops::{Coroutine, CoroutineState};
+   LL|       |use std::pin::Pin;
+   LL|       |
+   LL|       |// The following implementation of a function called from a `yield` statement
+   LL|       |// (apparently requiring the Result and the `String` type or constructor)
+   LL|       |// creates conditions where the `coroutine::StateTransform` MIR transform will
+   LL|       |// drop all `Counter` `Coverage` statements from a MIR. `simplify.rs` has logic
+   LL|       |// to handle this condition, and still report dead block coverage.
+   LL|      1|fn get_u32(val: bool) -> Result<u32, String> {
+   LL|      1|    if val { Ok(1) } else { Err(String::from("some error")) }
+                                          ^0
+   LL|      1|}
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|    let mut coroutine = || {
+   LL|      1|        yield get_u32(is_true);
+   LL|      1|        return "foo";
+   LL|      1|    };
+   LL|       |
+   LL|      1|    match Pin::new(&mut coroutine).resume(()) {
+   LL|      1|        CoroutineState::Yielded(Ok(1)) => {}
+   LL|      0|        _ => panic!("unexpected return from resume"),
+   LL|       |    }
+   LL|      1|    match Pin::new(&mut coroutine).resume(()) {
+   LL|      1|        CoroutineState::Complete("foo") => {}
+   LL|      0|        _ => panic!("unexpected return from resume"),
+   LL|       |    }
+   LL|      1|}
+
diff --git a/tests/coverage/coroutine.rs b/tests/coverage/coroutine.rs
new file mode 100644
index 00000000000..86d19af6f4f
--- /dev/null
+++ b/tests/coverage/coroutine.rs
@@ -0,0 +1,30 @@
+#![feature(coroutines, coroutine_trait)]
+
+use std::ops::{Coroutine, CoroutineState};
+use std::pin::Pin;
+
+// The following implementation of a function called from a `yield` statement
+// (apparently requiring the Result and the `String` type or constructor)
+// creates conditions where the `coroutine::StateTransform` MIR transform will
+// drop all `Counter` `Coverage` statements from a MIR. `simplify.rs` has logic
+// to handle this condition, and still report dead block coverage.
+fn get_u32(val: bool) -> Result<u32, String> {
+    if val { Ok(1) } else { Err(String::from("some error")) }
+}
+
+fn main() {
+    let is_true = std::env::args().len() == 1;
+    let mut coroutine = || {
+        yield get_u32(is_true);
+        return "foo";
+    };
+
+    match Pin::new(&mut coroutine).resume(()) {
+        CoroutineState::Yielded(Ok(1)) => {}
+        _ => panic!("unexpected return from resume"),
+    }
+    match Pin::new(&mut coroutine).resume(()) {
+        CoroutineState::Complete("foo") => {}
+        _ => panic!("unexpected return from resume"),
+    }
+}
diff --git a/tests/coverage/dead_code.coverage b/tests/coverage/dead_code.coverage
new file mode 100644
index 00000000000..c4ee9f23f08
--- /dev/null
+++ b/tests/coverage/dead_code.coverage
@@ -0,0 +1,39 @@
+   LL|       |#![allow(dead_code, unused_assignments, unused_variables)]
+   LL|       |
+   LL|      0|pub fn unused_pub_fn_not_in_library() {
+   LL|      0|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      0|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      0|    // dependent conditions.
+   LL|      0|    let is_true = std::env::args().len() == 1;
+   LL|      0|
+   LL|      0|    let mut countdown = 0;
+   LL|      0|    if is_true {
+   LL|      0|        countdown = 10;
+   LL|      0|    }
+   LL|      0|}
+   LL|       |
+   LL|      0|fn unused_fn() {
+   LL|      0|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      0|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      0|    // dependent conditions.
+   LL|      0|    let is_true = std::env::args().len() == 1;
+   LL|      0|
+   LL|      0|    let mut countdown = 0;
+   LL|      0|    if is_true {
+   LL|      0|        countdown = 10;
+   LL|      0|    }
+   LL|      0|}
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      1|    // dependent conditions.
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|
+   LL|      1|    let mut countdown = 0;
+   LL|      1|    if is_true {
+   LL|      1|        countdown = 10;
+   LL|      1|    }
+                   ^0
+   LL|      1|}
+
diff --git a/tests/coverage/dead_code.rs b/tests/coverage/dead_code.rs
new file mode 100644
index 00000000000..3492712a6f9
--- /dev/null
+++ b/tests/coverage/dead_code.rs
@@ -0,0 +1,37 @@
+#![allow(dead_code, unused_assignments, unused_variables)]
+
+pub fn unused_pub_fn_not_in_library() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+}
+
+fn unused_fn() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+}
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+}
diff --git a/tests/coverage/drop_trait.coverage b/tests/coverage/drop_trait.coverage
new file mode 100644
index 00000000000..2c9439a93b1
--- /dev/null
+++ b/tests/coverage/drop_trait.coverage
@@ -0,0 +1,34 @@
+   LL|       |#![allow(unused_assignments)]
+   LL|       |// failure-status: 1
+   LL|       |
+   LL|       |struct Firework {
+   LL|       |    strength: i32,
+   LL|       |}
+   LL|       |
+   LL|       |impl Drop for Firework {
+   LL|      2|    fn drop(&mut self) {
+   LL|      2|        println!("BOOM times {}!!!", self.strength);
+   LL|      2|    }
+   LL|       |}
+   LL|       |
+   LL|      1|fn main() -> Result<(), u8> {
+   LL|      1|    let _firecracker = Firework { strength: 1 };
+   LL|      1|
+   LL|      1|    let _tnt = Firework { strength: 100 };
+   LL|      1|
+   LL|      1|    if true {
+   LL|      1|        println!("Exiting with error...");
+   LL|      1|        return Err(1);
+   LL|      0|    }
+   LL|      0|
+   LL|      0|    let _ = Firework { strength: 1000 };
+   LL|      0|
+   LL|      0|    Ok(())
+   LL|      1|}
+   LL|       |
+   LL|       |// Expected program output:
+   LL|       |//   Exiting with error...
+   LL|       |//   BOOM times 100!!!
+   LL|       |//   BOOM times 1!!!
+   LL|       |//   Error: 1
+
diff --git a/tests/coverage/drop_trait.rs b/tests/coverage/drop_trait.rs
new file mode 100644
index 00000000000..7b062719c6b
--- /dev/null
+++ b/tests/coverage/drop_trait.rs
@@ -0,0 +1,33 @@
+#![allow(unused_assignments)]
+// failure-status: 1
+
+struct Firework {
+    strength: i32,
+}
+
+impl Drop for Firework {
+    fn drop(&mut self) {
+        println!("BOOM times {}!!!", self.strength);
+    }
+}
+
+fn main() -> Result<(), u8> {
+    let _firecracker = Firework { strength: 1 };
+
+    let _tnt = Firework { strength: 100 };
+
+    if true {
+        println!("Exiting with error...");
+        return Err(1);
+    }
+
+    let _ = Firework { strength: 1000 };
+
+    Ok(())
+}
+
+// Expected program output:
+//   Exiting with error...
+//   BOOM times 100!!!
+//   BOOM times 1!!!
+//   Error: 1
diff --git a/tests/coverage/fn_sig_into_try.coverage b/tests/coverage/fn_sig_into_try.coverage
new file mode 100644
index 00000000000..f1ddb1da780
--- /dev/null
+++ b/tests/coverage/fn_sig_into_try.coverage
@@ -0,0 +1,45 @@
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |// compile-flags: --edition=2021
+   LL|       |
+   LL|       |// Regression test for inconsistent handling of function signature spans that
+   LL|       |// are followed by code using the `?` operator.
+   LL|       |//
+   LL|       |// For each of these similar functions, the line containing the function
+   LL|       |// signature should be handled in the same way.
+   LL|       |
+   LL|      1|fn a() -> Option<i32>
+   LL|      1|{
+   LL|      1|    Some(7i32);
+   LL|      1|    Some(0)
+   LL|      1|}
+   LL|       |
+   LL|      1|fn b() -> Option<i32>
+   LL|      1|{
+   LL|      1|    Some(7i32)?;
+                            ^0
+   LL|      1|    Some(0)
+   LL|      1|}
+   LL|       |
+   LL|      1|fn c() -> Option<i32>
+   LL|      1|{
+   LL|      1|    let _ = Some(7i32)?;
+                                    ^0
+   LL|      1|    Some(0)
+   LL|      1|}
+   LL|       |
+   LL|      1|fn d() -> Option<i32>
+   LL|      1|{
+   LL|      1|    let _: () = ();
+   LL|      1|    Some(7i32)?;
+                            ^0
+   LL|      1|    Some(0)
+   LL|      1|}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn main() {
+   LL|       |    a();
+   LL|       |    b();
+   LL|       |    c();
+   LL|       |    d();
+   LL|       |}
+
diff --git a/tests/coverage/fn_sig_into_try.rs b/tests/coverage/fn_sig_into_try.rs
new file mode 100644
index 00000000000..92850c8a188
--- /dev/null
+++ b/tests/coverage/fn_sig_into_try.rs
@@ -0,0 +1,41 @@
+#![feature(coverage_attribute)]
+// compile-flags: --edition=2021
+
+// Regression test for inconsistent handling of function signature spans that
+// are followed by code using the `?` operator.
+//
+// For each of these similar functions, the line containing the function
+// signature should be handled in the same way.
+
+fn a() -> Option<i32>
+{
+    Some(7i32);
+    Some(0)
+}
+
+fn b() -> Option<i32>
+{
+    Some(7i32)?;
+    Some(0)
+}
+
+fn c() -> Option<i32>
+{
+    let _ = Some(7i32)?;
+    Some(0)
+}
+
+fn d() -> Option<i32>
+{
+    let _: () = ();
+    Some(7i32)?;
+    Some(0)
+}
+
+#[coverage(off)]
+fn main() {
+    a();
+    b();
+    c();
+    d();
+}
diff --git a/tests/coverage/generics.coverage b/tests/coverage/generics.coverage
new file mode 100644
index 00000000000..09839183566
--- /dev/null
+++ b/tests/coverage/generics.coverage
@@ -0,0 +1,67 @@
+   LL|       |#![allow(unused_assignments)]
+   LL|       |// failure-status: 1
+   LL|       |
+   LL|       |struct Firework<T> where T: Copy + std::fmt::Display {
+   LL|       |    strength: T,
+   LL|       |}
+   LL|       |
+   LL|       |impl<T> Firework<T> where T: Copy + std::fmt::Display {
+   LL|       |    #[inline(always)]
+   LL|      3|    fn set_strength(&mut self, new_strength: T) {
+   LL|      3|        self.strength = new_strength;
+   LL|      3|    }
+  ------------------
+  | <generics::Firework<f64>>::set_strength:
+  |   LL|      2|    fn set_strength(&mut self, new_strength: T) {
+  |   LL|      2|        self.strength = new_strength;
+  |   LL|      2|    }
+  ------------------
+  | <generics::Firework<i32>>::set_strength:
+  |   LL|      1|    fn set_strength(&mut self, new_strength: T) {
+  |   LL|      1|        self.strength = new_strength;
+  |   LL|      1|    }
+  ------------------
+   LL|       |}
+   LL|       |
+   LL|       |impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display {
+   LL|       |    #[inline(always)]
+   LL|      2|    fn drop(&mut self) {
+   LL|      2|        println!("BOOM times {}!!!", self.strength);
+   LL|      2|    }
+  ------------------
+  | <generics::Firework<f64> as core::ops::drop::Drop>::drop:
+  |   LL|      1|    fn drop(&mut self) {
+  |   LL|      1|        println!("BOOM times {}!!!", self.strength);
+  |   LL|      1|    }
+  ------------------
+  | <generics::Firework<i32> as core::ops::drop::Drop>::drop:
+  |   LL|      1|    fn drop(&mut self) {
+  |   LL|      1|        println!("BOOM times {}!!!", self.strength);
+  |   LL|      1|    }
+  ------------------
+   LL|       |}
+   LL|       |
+   LL|      1|fn main() -> Result<(), u8> {
+   LL|      1|    let mut firecracker = Firework { strength: 1 };
+   LL|      1|    firecracker.set_strength(2);
+   LL|      1|
+   LL|      1|    let mut tnt = Firework { strength: 100.1 };
+   LL|      1|    tnt.set_strength(200.1);
+   LL|      1|    tnt.set_strength(300.3);
+   LL|      1|
+   LL|      1|    if true {
+   LL|      1|        println!("Exiting with error...");
+   LL|      1|        return Err(1);
+   LL|      0|    }
+   LL|      0|
+   LL|      0|    let _ = Firework { strength: 1000 };
+   LL|      0|
+   LL|      0|    Ok(())
+   LL|      1|}
+   LL|       |
+   LL|       |// Expected program output:
+   LL|       |//   Exiting with error...
+   LL|       |//   BOOM times 100!!!
+   LL|       |//   BOOM times 1!!!
+   LL|       |//   Error: 1
+
diff --git a/tests/coverage/generics.rs b/tests/coverage/generics.rs
new file mode 100644
index 00000000000..bf4c2d8d685
--- /dev/null
+++ b/tests/coverage/generics.rs
@@ -0,0 +1,44 @@
+#![allow(unused_assignments)]
+// failure-status: 1
+
+struct Firework<T> where T: Copy + std::fmt::Display {
+    strength: T,
+}
+
+impl<T> Firework<T> where T: Copy + std::fmt::Display {
+    #[inline(always)]
+    fn set_strength(&mut self, new_strength: T) {
+        self.strength = new_strength;
+    }
+}
+
+impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display {
+    #[inline(always)]
+    fn drop(&mut self) {
+        println!("BOOM times {}!!!", self.strength);
+    }
+}
+
+fn main() -> Result<(), u8> {
+    let mut firecracker = Firework { strength: 1 };
+    firecracker.set_strength(2);
+
+    let mut tnt = Firework { strength: 100.1 };
+    tnt.set_strength(200.1);
+    tnt.set_strength(300.3);
+
+    if true {
+        println!("Exiting with error...");
+        return Err(1);
+    }
+
+    let _ = Firework { strength: 1000 };
+
+    Ok(())
+}
+
+// Expected program output:
+//   Exiting with error...
+//   BOOM times 100!!!
+//   BOOM times 1!!!
+//   Error: 1
diff --git a/tests/coverage/if.coverage b/tests/coverage/if.coverage
new file mode 100644
index 00000000000..2e6845190aa
--- /dev/null
+++ b/tests/coverage/if.coverage
@@ -0,0 +1,30 @@
+   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      1|    // dependent conditions.
+   LL|      1|    let
+   LL|      1|    is_true
+   LL|      1|    =
+   LL|      1|        std::env::args().len()
+   LL|      1|    ==
+   LL|      1|        1
+   LL|      1|    ;
+   LL|      1|    let
+   LL|      1|        mut
+   LL|      1|    countdown
+   LL|      1|    =
+   LL|      1|        0
+   LL|      1|    ;
+   LL|      1|    if
+   LL|      1|        is_true
+   LL|      1|    {
+   LL|      1|        countdown
+   LL|      1|        =
+   LL|      1|            10
+   LL|      1|        ;
+   LL|      1|    }
+                   ^0
+   LL|      1|}
+
diff --git a/tests/coverage/if.rs b/tests/coverage/if.rs
new file mode 100644
index 00000000000..8ad5042ff7b
--- /dev/null
+++ b/tests/coverage/if.rs
@@ -0,0 +1,28 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let
+    is_true
+    =
+        std::env::args().len()
+    ==
+        1
+    ;
+    let
+        mut
+    countdown
+    =
+        0
+    ;
+    if
+        is_true
+    {
+        countdown
+        =
+            10
+        ;
+    }
+}
diff --git a/tests/coverage/if_else.coverage b/tests/coverage/if_else.coverage
new file mode 100644
index 00000000000..0274401f004
--- /dev/null
+++ b/tests/coverage/if_else.coverage
@@ -0,0 +1,41 @@
+   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      1|    // dependent conditions.
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|
+   LL|      1|    let mut countdown = 0;
+   LL|      1|    if
+   LL|      1|        is_true
+   LL|      1|    {
+   LL|      1|        countdown
+   LL|      1|        =
+   LL|      1|            10
+   LL|      1|        ;
+   LL|      1|    }
+   LL|       |    else // Note coverage region difference without semicolon
+   LL|       |    {
+   LL|      0|        countdown
+   LL|      0|        =
+   LL|      0|            100
+   LL|       |    }
+   LL|       |
+   LL|       |    if
+   LL|      1|        is_true
+   LL|      1|    {
+   LL|      1|        countdown
+   LL|      1|        =
+   LL|      1|            10
+   LL|      1|        ;
+   LL|      1|    }
+   LL|       |    else
+   LL|      0|    {
+   LL|      0|        countdown
+   LL|      0|        =
+   LL|      0|            100
+   LL|      0|        ;
+   LL|      0|    }
+   LL|      1|}
+
diff --git a/tests/coverage/if_else.rs b/tests/coverage/if_else.rs
new file mode 100644
index 00000000000..3244e1e3afd
--- /dev/null
+++ b/tests/coverage/if_else.rs
@@ -0,0 +1,40 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 0;
+    if
+        is_true
+    {
+        countdown
+        =
+            10
+        ;
+    }
+    else // Note coverage region difference without semicolon
+    {
+        countdown
+        =
+            100
+    }
+
+    if
+        is_true
+    {
+        countdown
+        =
+            10
+        ;
+    }
+    else
+    {
+        countdown
+        =
+            100
+        ;
+    }
+}
diff --git a/tests/coverage/inline-dead.coverage b/tests/coverage/inline-dead.coverage
new file mode 100644
index 00000000000..de96aa17acd
--- /dev/null
+++ b/tests/coverage/inline-dead.coverage
@@ -0,0 +1,28 @@
+   LL|       |// Regression test for issue #98833.
+   LL|       |// compile-flags: -Zinline-mir -Cdebug-assertions=off
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    println!("{}", live::<false>());
+   LL|      1|
+   LL|      1|    let f = |x: bool| {
+   LL|       |        debug_assert!(
+   LL|      0|            x
+   LL|       |        );
+   LL|      1|    };
+   LL|      1|    f(false);
+   LL|      1|}
+   LL|       |
+   LL|       |#[inline]
+   LL|      1|fn live<const B: bool>() -> u32 {
+   LL|      1|    if B {
+   LL|      0|        dead()
+   LL|       |    } else {
+   LL|      1|        0
+   LL|       |    }
+   LL|      1|}
+   LL|       |
+   LL|       |#[inline]
+   LL|      0|fn dead() -> u32 {
+   LL|      0|    42
+   LL|      0|}
+
diff --git a/tests/coverage/inline-dead.rs b/tests/coverage/inline-dead.rs
new file mode 100644
index 00000000000..854fa062967
--- /dev/null
+++ b/tests/coverage/inline-dead.rs
@@ -0,0 +1,27 @@
+// Regression test for issue #98833.
+// compile-flags: -Zinline-mir -Cdebug-assertions=off
+
+fn main() {
+    println!("{}", live::<false>());
+
+    let f = |x: bool| {
+        debug_assert!(
+            x
+        );
+    };
+    f(false);
+}
+
+#[inline]
+fn live<const B: bool>() -> u32 {
+    if B {
+        dead()
+    } else {
+        0
+    }
+}
+
+#[inline]
+fn dead() -> u32 {
+    42
+}
diff --git a/tests/coverage/inline.coverage b/tests/coverage/inline.coverage
new file mode 100644
index 00000000000..6efd9a0830b
--- /dev/null
+++ b/tests/coverage/inline.coverage
@@ -0,0 +1,54 @@
+   LL|       |// compile-flags: -Zinline-mir
+   LL|       |
+   LL|       |use std::fmt::Display;
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    permutations(&['a', 'b', 'c']);
+   LL|      1|}
+   LL|       |
+   LL|       |#[inline(always)]
+   LL|      1|fn permutations<T: Copy + Display>(xs: &[T]) {
+   LL|      1|    let mut ys = xs.to_owned();
+   LL|      1|    permutate(&mut ys, 0);
+   LL|      1|}
+   LL|       |
+   LL|     16|fn permutate<T: Copy + Display>(xs: &mut [T], k: usize) {
+   LL|     16|    let n = length(xs);
+   LL|     16|    if k == n {
+   LL|      6|        display(xs);
+   LL|     10|    } else if k < n {
+   LL|     15|        for i in k..n {
+                               ^10
+   LL|     15|            swap(xs, i, k);
+   LL|     15|            permutate(xs, k + 1);
+   LL|     15|            swap(xs, i, k);
+   LL|     15|        }
+   LL|      0|    } else {
+   LL|      0|        error();
+   LL|      0|    }
+   LL|     16|}
+   LL|       |
+   LL|     16|fn length<T>(xs: &[T]) -> usize {
+   LL|     16|    xs.len()
+   LL|     16|}
+   LL|       |
+   LL|       |#[inline]
+   LL|     30|fn swap<T: Copy>(xs: &mut [T], i: usize, j: usize) {
+   LL|     30|    let t = xs[i];
+   LL|     30|    xs[i] = xs[j];
+   LL|     30|    xs[j] = t;
+   LL|     30|}
+   LL|       |
+   LL|      6|fn display<T: Display>(xs: &[T]) {
+   LL|     24|    for x in xs {
+                      ^18
+   LL|     18|        print!("{}", x);
+   LL|     18|    }
+   LL|      6|    println!();
+   LL|      6|}
+   LL|       |
+   LL|       |#[inline(always)]
+   LL|      0|fn error() {
+   LL|      0|    panic!("error");
+   LL|      0|}
+
diff --git a/tests/coverage/inline.rs b/tests/coverage/inline.rs
new file mode 100644
index 00000000000..9cfab9ddbad
--- /dev/null
+++ b/tests/coverage/inline.rs
@@ -0,0 +1,51 @@
+// compile-flags: -Zinline-mir
+
+use std::fmt::Display;
+
+fn main() {
+    permutations(&['a', 'b', 'c']);
+}
+
+#[inline(always)]
+fn permutations<T: Copy + Display>(xs: &[T]) {
+    let mut ys = xs.to_owned();
+    permutate(&mut ys, 0);
+}
+
+fn permutate<T: Copy + Display>(xs: &mut [T], k: usize) {
+    let n = length(xs);
+    if k == n {
+        display(xs);
+    } else if k < n {
+        for i in k..n {
+            swap(xs, i, k);
+            permutate(xs, k + 1);
+            swap(xs, i, k);
+        }
+    } else {
+        error();
+    }
+}
+
+fn length<T>(xs: &[T]) -> usize {
+    xs.len()
+}
+
+#[inline]
+fn swap<T: Copy>(xs: &mut [T], i: usize, j: usize) {
+    let t = xs[i];
+    xs[i] = xs[j];
+    xs[j] = t;
+}
+
+fn display<T: Display>(xs: &[T]) {
+    for x in xs {
+        print!("{}", x);
+    }
+    println!();
+}
+
+#[inline(always)]
+fn error() {
+    panic!("error");
+}
diff --git a/tests/coverage/inner_items.coverage b/tests/coverage/inner_items.coverage
new file mode 100644
index 00000000000..65493bcd9db
--- /dev/null
+++ b/tests/coverage/inner_items.coverage
@@ -0,0 +1,60 @@
+   LL|       |#![allow(unused_assignments, unused_variables, dead_code)]
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      1|    // dependent conditions.
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|
+   LL|      1|    let mut countdown = 0;
+   LL|      1|    if is_true {
+   LL|      1|        countdown = 10;
+   LL|      1|    }
+                   ^0
+   LL|       |
+   LL|       |    mod in_mod {
+   LL|       |        const IN_MOD_CONST: u32 = 1000;
+   LL|       |    }
+   LL|       |
+   LL|      3|    fn in_func(a: u32) {
+   LL|      3|        let b = 1;
+   LL|      3|        let c = a + b;
+   LL|      3|        println!("c = {}", c)
+   LL|      3|    }
+   LL|       |
+   LL|       |    struct InStruct {
+   LL|       |        in_struct_field: u32,
+   LL|       |    }
+   LL|       |
+   LL|       |    const IN_CONST: u32 = 1234;
+   LL|       |
+   LL|       |    trait InTrait {
+   LL|       |        fn trait_func(&mut self, incr: u32);
+   LL|       |
+   LL|      1|        fn default_trait_func(&mut self) {
+   LL|      1|            in_func(IN_CONST);
+   LL|      1|            self.trait_func(IN_CONST);
+   LL|      1|        }
+   LL|       |    }
+   LL|       |
+   LL|       |    impl InTrait for InStruct {
+   LL|      1|        fn trait_func(&mut self, incr: u32) {
+   LL|      1|            self.in_struct_field += incr;
+   LL|      1|            in_func(self.in_struct_field);
+   LL|      1|        }
+   LL|       |    }
+   LL|       |
+   LL|       |    type InType = String;
+   LL|       |
+   LL|      1|    if is_true {
+   LL|      1|        in_func(countdown);
+   LL|      1|    }
+                   ^0
+   LL|       |
+   LL|      1|    let mut val = InStruct {
+   LL|      1|        in_struct_field: 101,
+   LL|      1|    };
+   LL|      1|
+   LL|      1|    val.default_trait_func();
+   LL|      1|}
+
diff --git a/tests/coverage/inner_items.rs b/tests/coverage/inner_items.rs
new file mode 100644
index 00000000000..bcb62b3031c
--- /dev/null
+++ b/tests/coverage/inner_items.rs
@@ -0,0 +1,57 @@
+#![allow(unused_assignments, unused_variables, dead_code)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 0;
+    if is_true {
+        countdown = 10;
+    }
+
+    mod in_mod {
+        const IN_MOD_CONST: u32 = 1000;
+    }
+
+    fn in_func(a: u32) {
+        let b = 1;
+        let c = a + b;
+        println!("c = {}", c)
+    }
+
+    struct InStruct {
+        in_struct_field: u32,
+    }
+
+    const IN_CONST: u32 = 1234;
+
+    trait InTrait {
+        fn trait_func(&mut self, incr: u32);
+
+        fn default_trait_func(&mut self) {
+            in_func(IN_CONST);
+            self.trait_func(IN_CONST);
+        }
+    }
+
+    impl InTrait for InStruct {
+        fn trait_func(&mut self, incr: u32) {
+            self.in_struct_field += incr;
+            in_func(self.in_struct_field);
+        }
+    }
+
+    type InType = String;
+
+    if is_true {
+        in_func(countdown);
+    }
+
+    let mut val = InStruct {
+        in_struct_field: 101,
+    };
+
+    val.default_trait_func();
+}
diff --git a/tests/coverage/issue-83601.coverage b/tests/coverage/issue-83601.coverage
new file mode 100644
index 00000000000..7995332cad3
--- /dev/null
+++ b/tests/coverage/issue-83601.coverage
@@ -0,0 +1,16 @@
+   LL|       |// Shows that rust-lang/rust/83601 is resolved
+   LL|       |
+   LL|      3|#[derive(Debug, PartialEq, Eq)]
+                              ^2
+   LL|       |struct Foo(u32);
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let bar = Foo(1);
+   LL|      1|    assert_eq!(bar, Foo(1));
+   LL|      1|    let baz = Foo(0);
+   LL|      1|    assert_ne!(baz, Foo(1));
+   LL|      1|    println!("{:?}", Foo(1));
+   LL|      1|    println!("{:?}", bar);
+   LL|      1|    println!("{:?}", baz);
+   LL|      1|}
+
diff --git a/tests/coverage/issue-83601.rs b/tests/coverage/issue-83601.rs
new file mode 100644
index 00000000000..0b72a81947c
--- /dev/null
+++ b/tests/coverage/issue-83601.rs
@@ -0,0 +1,14 @@
+// Shows that rust-lang/rust/83601 is resolved
+
+#[derive(Debug, PartialEq, Eq)]
+struct Foo(u32);
+
+fn main() {
+    let bar = Foo(1);
+    assert_eq!(bar, Foo(1));
+    let baz = Foo(0);
+    assert_ne!(baz, Foo(1));
+    println!("{:?}", Foo(1));
+    println!("{:?}", bar);
+    println!("{:?}", baz);
+}
diff --git a/tests/coverage/issue-84561.coverage b/tests/coverage/issue-84561.coverage
new file mode 100644
index 00000000000..e693866e277
--- /dev/null
+++ b/tests/coverage/issue-84561.coverage
@@ -0,0 +1,189 @@
+   LL|       |// This demonstrated Issue #84561: function-like macros produce unintuitive coverage results.
+   LL|       |
+   LL|       |// failure-status: 101
+   LL|     21|#[derive(PartialEq, Eq)]
+   LL|       |struct Foo(u32);
+   LL|      1|fn test3() {
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|    let bar = Foo(1);
+   LL|      1|    assert_eq!(bar, Foo(1));
+   LL|      1|    let baz = Foo(0);
+   LL|      1|    assert_ne!(baz, Foo(1));
+   LL|      1|    println!("{:?}", Foo(1));
+   LL|      1|    println!("{:?}", bar);
+   LL|      1|    println!("{:?}", baz);
+   LL|      1|
+   LL|      1|    assert_eq!(Foo(1), Foo(1));
+   LL|      1|    assert_ne!(Foo(0), Foo(1));
+   LL|      1|    assert_eq!(Foo(2), Foo(2));
+   LL|      1|    let bar = Foo(0);
+   LL|      1|    assert_ne!(bar, Foo(3));
+   LL|      1|    assert_ne!(Foo(0), Foo(4));
+   LL|      1|    assert_eq!(Foo(3), Foo(3), "with a message");
+                                             ^0
+   LL|      1|    println!("{:?}", bar);
+   LL|      1|    println!("{:?}", Foo(1));
+   LL|      1|
+   LL|      1|    assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" });
+                                             ^0                 ^0                      ^0
+   LL|      1|    assert_ne!(
+   LL|       |        Foo(0)
+   LL|       |        ,
+   LL|       |        Foo(5)
+   LL|       |        ,
+   LL|      0|        "{}"
+   LL|      0|        ,
+   LL|      0|        if
+   LL|      0|        is_true
+   LL|       |        {
+   LL|      0|            "true message"
+   LL|       |        } else {
+   LL|      0|            "false message"
+   LL|       |        }
+   LL|       |    );
+   LL|       |
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|
+   LL|      1|    assert_eq!(
+   LL|      1|        Foo(1),
+   LL|      1|        Foo(1)
+   LL|      1|    );
+   LL|      1|    assert_ne!(
+   LL|      1|        Foo(0),
+   LL|      1|        Foo(1)
+   LL|      1|    );
+   LL|      1|    assert_eq!(
+   LL|      1|        Foo(2),
+   LL|      1|        Foo(2)
+   LL|      1|    );
+   LL|      1|    let bar = Foo(1);
+   LL|      1|    assert_ne!(
+   LL|      1|        bar,
+   LL|      1|        Foo(3)
+   LL|      1|    );
+   LL|      1|    if is_true {
+   LL|      1|        assert_ne!(
+   LL|      1|            Foo(0),
+   LL|      1|            Foo(4)
+   LL|      1|        );
+   LL|       |    } else {
+   LL|      0|        assert_eq!(
+   LL|      0|            Foo(3),
+   LL|      0|            Foo(3)
+   LL|      0|        );
+   LL|       |    }
+   LL|      1|    if is_true {
+   LL|      1|        assert_ne!(
+   LL|       |            Foo(0),
+   LL|       |            Foo(4),
+   LL|      0|            "with a message"
+   LL|       |        );
+   LL|       |    } else {
+   LL|      0|        assert_eq!(
+   LL|       |            Foo(3),
+   LL|       |            Foo(3),
+   LL|      0|            "with a message"
+   LL|       |        );
+   LL|       |    }
+   LL|      1|    assert_ne!(
+   LL|      1|        if is_true {
+   LL|      1|            Foo(0)
+   LL|       |        } else {
+   LL|      0|            Foo(1)
+   LL|       |        },
+   LL|       |        Foo(5)
+   LL|       |    );
+   LL|      1|    assert_ne!(
+   LL|      1|        Foo(5),
+   LL|      1|        if is_true {
+   LL|      1|            Foo(0)
+   LL|       |        } else {
+   LL|      0|            Foo(1)
+   LL|       |        }
+   LL|       |    );
+   LL|      1|    assert_ne!(
+   LL|      1|        if is_true {
+   LL|      1|            assert_eq!(
+   LL|      1|                Foo(3),
+   LL|      1|                Foo(3)
+   LL|      1|            );
+   LL|      1|            Foo(0)
+   LL|       |        } else {
+   LL|      0|            assert_ne!(
+   LL|      0|                if is_true {
+   LL|      0|                    Foo(0)
+   LL|       |                } else {
+   LL|      0|                    Foo(1)
+   LL|       |                },
+   LL|       |                Foo(5)
+   LL|       |            );
+   LL|      0|            Foo(1)
+   LL|       |        },
+   LL|       |        Foo(5),
+   LL|      0|        "with a message"
+   LL|       |    );
+   LL|      1|    assert_eq!(
+   LL|       |        Foo(1),
+   LL|       |        Foo(3),
+   LL|      1|        "this assert should fail"
+   LL|       |    );
+   LL|      0|    assert_eq!(
+   LL|       |        Foo(3),
+   LL|       |        Foo(3),
+   LL|      0|        "this assert should not be reached"
+   LL|       |    );
+   LL|      0|}
+   LL|       |
+   LL|       |impl std::fmt::Debug for Foo {
+   LL|      7|    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+   LL|      7|        write!(f, "try and succeed")?;
+                                                  ^0
+   LL|      7|        Ok(())
+   LL|      7|    }
+   LL|       |}
+   LL|       |
+   LL|       |static mut DEBUG_LEVEL_ENABLED: bool = false;
+   LL|       |
+   LL|       |macro_rules! debug {
+   LL|       |    ($($arg:tt)+) => (
+   LL|       |        if unsafe { DEBUG_LEVEL_ENABLED } {
+   LL|       |            println!($($arg)+);
+   LL|       |        }
+   LL|       |    );
+   LL|       |}
+   LL|       |
+   LL|      1|fn test1() {
+   LL|      1|    debug!("debug is enabled");
+                         ^0
+   LL|      1|    debug!("debug is enabled");
+                         ^0
+   LL|      1|    let _ = 0;
+   LL|      1|    debug!("debug is enabled");
+                         ^0
+   LL|      1|    unsafe {
+   LL|      1|        DEBUG_LEVEL_ENABLED = true;
+   LL|      1|    }
+   LL|      1|    debug!("debug is enabled");
+   LL|      1|}
+   LL|       |
+   LL|       |macro_rules! call_debug {
+   LL|       |    ($($arg:tt)+) => (
+   LL|      1|        fn call_print(s: &str) {
+   LL|      1|            print!("{}", s);
+   LL|      1|        }
+   LL|       |
+   LL|       |        call_print("called from call_debug: ");
+   LL|       |        debug!($($arg)+);
+   LL|       |    );
+   LL|       |}
+   LL|       |
+   LL|      1|fn test2() {
+   LL|      1|    call_debug!("debug is enabled");
+   LL|      1|}
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    test1();
+   LL|      1|    test2();
+   LL|      1|    test3();
+   LL|      1|}
+
diff --git a/tests/coverage/issue-84561.rs b/tests/coverage/issue-84561.rs
new file mode 100644
index 00000000000..facf5b5b4cf
--- /dev/null
+++ b/tests/coverage/issue-84561.rs
@@ -0,0 +1,182 @@
+// This demonstrated Issue #84561: function-like macros produce unintuitive coverage results.
+
+// failure-status: 101
+#[derive(PartialEq, Eq)]
+struct Foo(u32);
+fn test3() {
+    let is_true = std::env::args().len() == 1;
+    let bar = Foo(1);
+    assert_eq!(bar, Foo(1));
+    let baz = Foo(0);
+    assert_ne!(baz, Foo(1));
+    println!("{:?}", Foo(1));
+    println!("{:?}", bar);
+    println!("{:?}", baz);
+
+    assert_eq!(Foo(1), Foo(1));
+    assert_ne!(Foo(0), Foo(1));
+    assert_eq!(Foo(2), Foo(2));
+    let bar = Foo(0);
+    assert_ne!(bar, Foo(3));
+    assert_ne!(Foo(0), Foo(4));
+    assert_eq!(Foo(3), Foo(3), "with a message");
+    println!("{:?}", bar);
+    println!("{:?}", Foo(1));
+
+    assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" });
+    assert_ne!(
+        Foo(0)
+        ,
+        Foo(5)
+        ,
+        "{}"
+        ,
+        if
+        is_true
+        {
+            "true message"
+        } else {
+            "false message"
+        }
+    );
+
+    let is_true = std::env::args().len() == 1;
+
+    assert_eq!(
+        Foo(1),
+        Foo(1)
+    );
+    assert_ne!(
+        Foo(0),
+        Foo(1)
+    );
+    assert_eq!(
+        Foo(2),
+        Foo(2)
+    );
+    let bar = Foo(1);
+    assert_ne!(
+        bar,
+        Foo(3)
+    );
+    if is_true {
+        assert_ne!(
+            Foo(0),
+            Foo(4)
+        );
+    } else {
+        assert_eq!(
+            Foo(3),
+            Foo(3)
+        );
+    }
+    if is_true {
+        assert_ne!(
+            Foo(0),
+            Foo(4),
+            "with a message"
+        );
+    } else {
+        assert_eq!(
+            Foo(3),
+            Foo(3),
+            "with a message"
+        );
+    }
+    assert_ne!(
+        if is_true {
+            Foo(0)
+        } else {
+            Foo(1)
+        },
+        Foo(5)
+    );
+    assert_ne!(
+        Foo(5),
+        if is_true {
+            Foo(0)
+        } else {
+            Foo(1)
+        }
+    );
+    assert_ne!(
+        if is_true {
+            assert_eq!(
+                Foo(3),
+                Foo(3)
+            );
+            Foo(0)
+        } else {
+            assert_ne!(
+                if is_true {
+                    Foo(0)
+                } else {
+                    Foo(1)
+                },
+                Foo(5)
+            );
+            Foo(1)
+        },
+        Foo(5),
+        "with a message"
+    );
+    assert_eq!(
+        Foo(1),
+        Foo(3),
+        "this assert should fail"
+    );
+    assert_eq!(
+        Foo(3),
+        Foo(3),
+        "this assert should not be reached"
+    );
+}
+
+impl std::fmt::Debug for Foo {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        write!(f, "try and succeed")?;
+        Ok(())
+    }
+}
+
+static mut DEBUG_LEVEL_ENABLED: bool = false;
+
+macro_rules! debug {
+    ($($arg:tt)+) => (
+        if unsafe { DEBUG_LEVEL_ENABLED } {
+            println!($($arg)+);
+        }
+    );
+}
+
+fn test1() {
+    debug!("debug is enabled");
+    debug!("debug is enabled");
+    let _ = 0;
+    debug!("debug is enabled");
+    unsafe {
+        DEBUG_LEVEL_ENABLED = true;
+    }
+    debug!("debug is enabled");
+}
+
+macro_rules! call_debug {
+    ($($arg:tt)+) => (
+        fn call_print(s: &str) {
+            print!("{}", s);
+        }
+
+        call_print("called from call_debug: ");
+        debug!($($arg)+);
+    );
+}
+
+fn test2() {
+    call_debug!("debug is enabled");
+}
+
+fn main() {
+    test1();
+    test2();
+    test3();
+}
diff --git a/tests/coverage/issue-85461.coverage b/tests/coverage/issue-85461.coverage
new file mode 100644
index 00000000000..cbc910664d0
--- /dev/null
+++ b/tests/coverage/issue-85461.coverage
@@ -0,0 +1,37 @@
+$DIR/auxiliary/inline_always_with_dead_code.rs:
+   LL|       |// compile-flags: -Cinstrument-coverage -Ccodegen-units=4 -Copt-level=0
+   LL|       |
+   LL|       |#![allow(dead_code)]
+   LL|       |
+   LL|       |mod foo {
+   LL|       |    #[inline(always)]
+   LL|      2|    pub fn called() {}
+   LL|       |
+   LL|      0|    fn uncalled() {}
+   LL|       |}
+   LL|       |
+   LL|       |pub mod bar {
+   LL|      1|    pub fn call_me() {
+   LL|      1|        super::foo::called();
+   LL|      1|    }
+   LL|       |}
+   LL|       |
+   LL|       |pub mod baz {
+   LL|      1|    pub fn call_me() {
+   LL|      1|        super::foo::called();
+   LL|      1|    }
+   LL|       |}
+
+$DIR/issue-85461.rs:
+   LL|       |// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
+   LL|       |
+   LL|       |// aux-build:inline_always_with_dead_code.rs
+   LL|       |extern crate inline_always_with_dead_code;
+   LL|       |
+   LL|       |use inline_always_with_dead_code::{bar, baz};
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    bar::call_me();
+   LL|      1|    baz::call_me();
+   LL|      1|}
+
diff --git a/tests/coverage/issue-85461.rs b/tests/coverage/issue-85461.rs
new file mode 100644
index 00000000000..9d4c90a827e
--- /dev/null
+++ b/tests/coverage/issue-85461.rs
@@ -0,0 +1,11 @@
+// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
+
+// aux-build:inline_always_with_dead_code.rs
+extern crate inline_always_with_dead_code;
+
+use inline_always_with_dead_code::{bar, baz};
+
+fn main() {
+    bar::call_me();
+    baz::call_me();
+}
diff --git a/tests/coverage/issue-93054.coverage b/tests/coverage/issue-93054.coverage
new file mode 100644
index 00000000000..15f225326a4
--- /dev/null
+++ b/tests/coverage/issue-93054.coverage
@@ -0,0 +1,31 @@
+   LL|       |#![allow(dead_code, unreachable_code)]
+   LL|       |
+   LL|       |// Regression test for #93054: Functions using uninhabited types often only have a single,
+   LL|       |// unreachable basic block which doesn't get instrumented. This should not cause llvm-cov to fail.
+   LL|       |// Since these kinds functions can't be invoked anyway, it's ok to not have coverage data for them.
+   LL|       |
+   LL|       |// compile-flags: --edition=2021
+   LL|       |
+   LL|       |enum Never {}
+   LL|       |
+   LL|       |impl Never {
+   LL|       |    fn foo(self) {
+   LL|       |        match self {}
+   LL|       |        make().map(|never| match never {});
+   LL|       |    }
+   LL|       |
+   LL|       |    fn bar(&self) {
+   LL|       |        match *self {}
+   LL|       |    }
+   LL|       |}
+   LL|       |
+   LL|      0|async fn foo2(never: Never) {
+   LL|       |    match never {}
+   LL|       |}
+   LL|       |
+   LL|      0|fn make() -> Option<Never> {
+   LL|      0|    None
+   LL|      0|}
+   LL|       |
+   LL|      1|fn main() {}
+
diff --git a/tests/coverage/issue-93054.rs b/tests/coverage/issue-93054.rs
new file mode 100644
index 00000000000..da546cfeef8
--- /dev/null
+++ b/tests/coverage/issue-93054.rs
@@ -0,0 +1,30 @@
+#![allow(dead_code, unreachable_code)]
+
+// Regression test for #93054: Functions using uninhabited types often only have a single,
+// unreachable basic block which doesn't get instrumented. This should not cause llvm-cov to fail.
+// Since these kinds functions can't be invoked anyway, it's ok to not have coverage data for them.
+
+// compile-flags: --edition=2021
+
+enum Never {}
+
+impl Never {
+    fn foo(self) {
+        match self {}
+        make().map(|never| match never {});
+    }
+
+    fn bar(&self) {
+        match *self {}
+    }
+}
+
+async fn foo2(never: Never) {
+    match never {}
+}
+
+fn make() -> Option<Never> {
+    None
+}
+
+fn main() {}
diff --git a/tests/coverage/lazy_boolean.coverage b/tests/coverage/lazy_boolean.coverage
new file mode 100644
index 00000000000..8f14082ef68
--- /dev/null
+++ b/tests/coverage/lazy_boolean.coverage
@@ -0,0 +1,64 @@
+   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      1|    // dependent conditions.
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|
+   LL|      1|    let (mut a, mut b, mut c) = (0, 0, 0);
+   LL|      1|    if is_true {
+   LL|      1|        a = 1;
+   LL|      1|        b = 10;
+   LL|      1|        c = 100;
+   LL|      1|    }
+                   ^0
+   LL|       |    let
+   LL|      1|        somebool
+   LL|       |        =
+   LL|      1|            a < b
+   LL|       |        ||
+   LL|      0|            b < c
+   LL|       |    ;
+   LL|       |    let
+   LL|      1|        somebool
+   LL|       |        =
+   LL|      1|            b < a
+   LL|       |        ||
+   LL|      1|            b < c
+   LL|       |    ;
+   LL|      1|    let somebool = a < b && b < c;
+   LL|      1|    let somebool = b < a && b < c;
+                                          ^0
+   LL|       |
+   LL|       |    if
+   LL|       |        !
+   LL|      1|        is_true
+   LL|      0|    {
+   LL|      0|        a = 2
+   LL|      0|        ;
+   LL|      1|    }
+   LL|       |
+   LL|       |    if
+   LL|      1|        is_true
+   LL|      1|    {
+   LL|      1|        b = 30
+   LL|      1|        ;
+   LL|      1|    }
+   LL|       |    else
+   LL|      0|    {
+   LL|      0|        c = 400
+   LL|      0|        ;
+   LL|      0|    }
+   LL|       |
+   LL|      1|    if !is_true {
+   LL|      0|        a = 2;
+   LL|      1|    }
+   LL|       |
+   LL|      1|    if is_true {
+   LL|      1|        b = 30;
+   LL|      1|    } else {
+   LL|      0|        c = 400;
+   LL|      0|    }
+   LL|      1|}
+
diff --git a/tests/coverage/lazy_boolean.rs b/tests/coverage/lazy_boolean.rs
new file mode 100644
index 00000000000..bb6219e851c
--- /dev/null
+++ b/tests/coverage/lazy_boolean.rs
@@ -0,0 +1,61 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let (mut a, mut b, mut c) = (0, 0, 0);
+    if is_true {
+        a = 1;
+        b = 10;
+        c = 100;
+    }
+    let
+        somebool
+        =
+            a < b
+        ||
+            b < c
+    ;
+    let
+        somebool
+        =
+            b < a
+        ||
+            b < c
+    ;
+    let somebool = a < b && b < c;
+    let somebool = b < a && b < c;
+
+    if
+        !
+        is_true
+    {
+        a = 2
+        ;
+    }
+
+    if
+        is_true
+    {
+        b = 30
+        ;
+    }
+    else
+    {
+        c = 400
+        ;
+    }
+
+    if !is_true {
+        a = 2;
+    }
+
+    if is_true {
+        b = 30;
+    } else {
+        c = 400;
+    }
+}
diff --git a/tests/coverage/long_and_wide.coverage b/tests/coverage/long_and_wide.coverage
new file mode 100644
index 00000000000..d7d29ca40cd
--- /dev/null
+++ b/tests/coverage/long_and_wide.coverage
@@ -0,0 +1,151 @@
+   LL|       |// compile-flags: --edition=2021
+   LL|       |// ignore-tidy-linelength
+   LL|       |
+   LL|       |// This file deliberately contains line and column numbers larger than 127,
+   LL|       |// to verify that `coverage-dump`'s ULEB128 parser can handle them.
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    wide_function();
+   LL|      1|    long_function();
+   LL|      1|    far_function();
+   LL|      1|}
+   LL|       |
+   LL|       |#[rustfmt::skip]
+   LL|      1|fn wide_function() { /*                                                                                                           */ (); }
+   LL|       |
+   LL|      1|fn long_function() {
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|    //
+   LL|      1|}
+   LL|       |
+   LL|      1|fn far_function() {}
+
diff --git a/tests/coverage/long_and_wide.rs b/tests/coverage/long_and_wide.rs
new file mode 100644
index 00000000000..a7cbcd48027
--- /dev/null
+++ b/tests/coverage/long_and_wide.rs
@@ -0,0 +1,150 @@
+// compile-flags: --edition=2021
+// ignore-tidy-linelength
+
+// This file deliberately contains line and column numbers larger than 127,
+// to verify that `coverage-dump`'s ULEB128 parser can handle them.
+
+fn main() {
+    wide_function();
+    long_function();
+    far_function();
+}
+
+#[rustfmt::skip]
+fn wide_function() { /*                                                                                                           */ (); }
+
+fn long_function() {
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+    //
+}
+
+fn far_function() {}
diff --git a/tests/coverage/loop_break_value.coverage b/tests/coverage/loop_break_value.coverage
new file mode 100644
index 00000000000..1f0630636dd
--- /dev/null
+++ b/tests/coverage/loop_break_value.coverage
@@ -0,0 +1,14 @@
+   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let result
+   LL|      1|        =
+   LL|      1|            loop
+   LL|      1|        {
+   LL|      1|            break
+   LL|      1|            10
+   LL|      1|            ;
+   LL|      1|        }
+   LL|      1|    ;
+   LL|      1|}
+
diff --git a/tests/coverage/loop_break_value.rs b/tests/coverage/loop_break_value.rs
new file mode 100644
index 00000000000..dbc4fad7a23
--- /dev/null
+++ b/tests/coverage/loop_break_value.rs
@@ -0,0 +1,13 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    let result
+        =
+            loop
+        {
+            break
+            10
+            ;
+        }
+    ;
+}
diff --git a/tests/coverage/loops_branches.coverage b/tests/coverage/loops_branches.coverage
new file mode 100644
index 00000000000..8cd6f1be3f7
--- /dev/null
+++ b/tests/coverage/loops_branches.coverage
@@ -0,0 +1,67 @@
+   LL|       |#![allow(unused_assignments, unused_variables, while_true)]
+   LL|       |
+   LL|       |// This test confirms that (1) unexecuted infinite loops are handled correctly by the
+   LL|       |// InstrumentCoverage MIR pass; and (2) Counter Expressions that subtract from zero can be dropped.
+   LL|       |
+   LL|       |struct DebugTest;
+   LL|       |
+   LL|       |impl std::fmt::Debug for DebugTest {
+   LL|      1|    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+   LL|      1|        if true {
+   LL|      1|            if false {
+   LL|      0|                while true {}
+   LL|      1|            }
+   LL|      1|            write!(f, "cool")?;
+                                           ^0
+   LL|      0|        } else {
+   LL|      0|        }
+   LL|       |
+   LL|     11|        for i in 0..10 {
+                          ^10
+   LL|     10|            if true {
+   LL|     10|                if false {
+   LL|      0|                    while true {}
+   LL|     10|                }
+   LL|     10|                write!(f, "cool")?;
+                                               ^0
+   LL|      0|            } else {
+   LL|      0|            }
+   LL|       |        }
+   LL|      1|        Ok(())
+   LL|      1|    }
+   LL|       |}
+   LL|       |
+   LL|       |struct DisplayTest;
+   LL|       |
+   LL|       |impl std::fmt::Display for DisplayTest {
+   LL|      1|    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+   LL|      1|        if false {
+   LL|      0|        } else {
+   LL|      1|            if false {
+   LL|      0|                while true {}
+   LL|      1|            }
+   LL|      1|            write!(f, "cool")?;
+                                           ^0
+   LL|       |        }
+   LL|     11|        for i in 0..10 {
+                          ^10
+   LL|     10|            if false {
+   LL|      0|            } else {
+   LL|     10|                if false {
+   LL|      0|                    while true {}
+   LL|     10|                }
+   LL|     10|                write!(f, "cool")?;
+                                               ^0
+   LL|       |            }
+   LL|       |        }
+   LL|      1|        Ok(())
+   LL|      1|    }
+   LL|       |}
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let debug_test = DebugTest;
+   LL|      1|    println!("{:?}", debug_test);
+   LL|      1|    let display_test = DisplayTest;
+   LL|      1|    println!("{}", display_test);
+   LL|      1|}
+
diff --git a/tests/coverage/loops_branches.rs b/tests/coverage/loops_branches.rs
new file mode 100644
index 00000000000..f3a343bcc1f
--- /dev/null
+++ b/tests/coverage/loops_branches.rs
@@ -0,0 +1,60 @@
+#![allow(unused_assignments, unused_variables, while_true)]
+
+// This test confirms that (1) unexecuted infinite loops are handled correctly by the
+// InstrumentCoverage MIR pass; and (2) Counter Expressions that subtract from zero can be dropped.
+
+struct DebugTest;
+
+impl std::fmt::Debug for DebugTest {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        if true {
+            if false {
+                while true {}
+            }
+            write!(f, "cool")?;
+        } else {
+        }
+
+        for i in 0..10 {
+            if true {
+                if false {
+                    while true {}
+                }
+                write!(f, "cool")?;
+            } else {
+            }
+        }
+        Ok(())
+    }
+}
+
+struct DisplayTest;
+
+impl std::fmt::Display for DisplayTest {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        if false {
+        } else {
+            if false {
+                while true {}
+            }
+            write!(f, "cool")?;
+        }
+        for i in 0..10 {
+            if false {
+            } else {
+                if false {
+                    while true {}
+                }
+                write!(f, "cool")?;
+            }
+        }
+        Ok(())
+    }
+}
+
+fn main() {
+    let debug_test = DebugTest;
+    println!("{:?}", debug_test);
+    let display_test = DisplayTest;
+    println!("{}", display_test);
+}
diff --git a/tests/coverage/match_or_pattern.coverage b/tests/coverage/match_or_pattern.coverage
new file mode 100644
index 00000000000..94c7967215c
--- /dev/null
+++ b/tests/coverage/match_or_pattern.coverage
@@ -0,0 +1,48 @@
+   LL|      1|fn main() {
+   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      1|    // dependent conditions.
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|
+   LL|      1|    let mut a: u8 = 0;
+   LL|      1|    let mut b: u8 = 0;
+   LL|      1|    if is_true {
+   LL|      1|        a = 2;
+   LL|      1|        b = 0;
+   LL|      1|    }
+                   ^0
+   LL|      1|    match (a, b) {
+   LL|       |        // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`.
+   LL|       |        // This test confirms a fix for Issue #79569.
+   LL|      0|        (0 | 1, 2 | 3) => {}
+   LL|      1|        _ => {}
+   LL|       |    }
+   LL|      1|    if is_true {
+   LL|      1|        a = 0;
+   LL|      1|        b = 0;
+   LL|      1|    }
+                   ^0
+   LL|      1|    match (a, b) {
+   LL|      0|        (0 | 1, 2 | 3) => {}
+   LL|      1|        _ => {}
+   LL|       |    }
+   LL|      1|    if is_true {
+   LL|      1|        a = 2;
+   LL|      1|        b = 2;
+   LL|      1|    }
+                   ^0
+   LL|      1|    match (a, b) {
+   LL|      0|        (0 | 1, 2 | 3) => {}
+   LL|      1|        _ => {}
+   LL|       |    }
+   LL|      1|    if is_true {
+   LL|      1|        a = 0;
+   LL|      1|        b = 2;
+   LL|      1|    }
+                   ^0
+   LL|      1|    match (a, b) {
+   LL|      1|        (0 | 1, 2 | 3) => {}
+   LL|      0|        _ => {}
+   LL|       |    }
+   LL|      1|}
+
diff --git a/tests/coverage/match_or_pattern.rs b/tests/coverage/match_or_pattern.rs
new file mode 100644
index 00000000000..ab7aee51d1b
--- /dev/null
+++ b/tests/coverage/match_or_pattern.rs
@@ -0,0 +1,43 @@
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut a: u8 = 0;
+    let mut b: u8 = 0;
+    if is_true {
+        a = 2;
+        b = 0;
+    }
+    match (a, b) {
+        // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`.
+        // This test confirms a fix for Issue #79569.
+        (0 | 1, 2 | 3) => {}
+        _ => {}
+    }
+    if is_true {
+        a = 0;
+        b = 0;
+    }
+    match (a, b) {
+        (0 | 1, 2 | 3) => {}
+        _ => {}
+    }
+    if is_true {
+        a = 2;
+        b = 2;
+    }
+    match (a, b) {
+        (0 | 1, 2 | 3) => {}
+        _ => {}
+    }
+    if is_true {
+        a = 0;
+        b = 2;
+    }
+    match (a, b) {
+        (0 | 1, 2 | 3) => {}
+        _ => {}
+    }
+}
diff --git a/tests/coverage/nested_loops.coverage b/tests/coverage/nested_loops.coverage
new file mode 100644
index 00000000000..143d0d26aa7
--- /dev/null
+++ b/tests/coverage/nested_loops.coverage
@@ -0,0 +1,26 @@
+   LL|      1|fn main() {
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|    let mut countdown = 10;
+   LL|       |
+   LL|      1|    'outer: while countdown > 0 {
+   LL|      1|        let mut a = 100;
+   LL|      1|        let mut b = 100;
+   LL|      3|        for _ in 0..50 {
+   LL|      3|            if a < 30 {
+   LL|      0|                break;
+   LL|      3|            }
+   LL|      3|            a -= 5;
+   LL|      3|            b -= 5;
+   LL|      3|            if b < 90 {
+   LL|      1|                a -= 10;
+   LL|      1|                if is_true {
+   LL|      1|                    break 'outer;
+   LL|      0|                } else {
+   LL|      0|                    a -= 2;
+   LL|      0|                }
+   LL|      2|            }
+   LL|       |        }
+   LL|      0|        countdown -= 1;
+   LL|       |    }
+   LL|      1|}
+
diff --git a/tests/coverage/nested_loops.rs b/tests/coverage/nested_loops.rs
new file mode 100644
index 00000000000..4c7c7842796
--- /dev/null
+++ b/tests/coverage/nested_loops.rs
@@ -0,0 +1,25 @@
+fn main() {
+    let is_true = std::env::args().len() == 1;
+    let mut countdown = 10;
+
+    'outer: while countdown > 0 {
+        let mut a = 100;
+        let mut b = 100;
+        for _ in 0..50 {
+            if a < 30 {
+                break;
+            }
+            a -= 5;
+            b -= 5;
+            if b < 90 {
+                a -= 10;
+                if is_true {
+                    break 'outer;
+                } else {
+                    a -= 2;
+                }
+            }
+        }
+        countdown -= 1;
+    }
+}
diff --git a/tests/coverage/no_cov_crate.coverage b/tests/coverage/no_cov_crate.coverage
new file mode 100644
index 00000000000..f5a0322bf3e
--- /dev/null
+++ b/tests/coverage/no_cov_crate.coverage
@@ -0,0 +1,89 @@
+   LL|       |// Enables `coverage(off)` on the entire crate
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn do_not_add_coverage_1() {
+   LL|       |    println!("called but not covered");
+   LL|       |}
+   LL|       |
+   LL|       |fn do_not_add_coverage_2() {
+   LL|       |    #![coverage(off)]
+   LL|       |    println!("called but not covered");
+   LL|       |}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |#[allow(dead_code)]
+   LL|       |fn do_not_add_coverage_not_called() {
+   LL|       |    println!("not called and not covered");
+   LL|       |}
+   LL|       |
+   LL|      1|fn add_coverage_1() {
+   LL|      1|    println!("called and covered");
+   LL|      1|}
+   LL|       |
+   LL|      1|fn add_coverage_2() {
+   LL|      1|    println!("called and covered");
+   LL|      1|}
+   LL|       |
+   LL|       |#[allow(dead_code)]
+   LL|      0|fn add_coverage_not_called() {
+   LL|      0|    println!("not called but covered");
+   LL|      0|}
+   LL|       |
+   LL|       |// FIXME: These test-cases illustrate confusing results of nested functions.
+   LL|       |// See https://github.com/rust-lang/rust/issues/93319
+   LL|       |mod nested_fns {
+   LL|       |    #[coverage(off)]
+   LL|       |    pub fn outer_not_covered(is_true: bool) {
+   LL|      1|        fn inner(is_true: bool) {
+   LL|      1|            if is_true {
+   LL|      1|                println!("called and covered");
+   LL|      1|            } else {
+   LL|      0|                println!("absolutely not covered");
+   LL|      0|            }
+   LL|      1|        }
+   LL|       |        println!("called but not covered");
+   LL|       |        inner(is_true);
+   LL|       |    }
+   LL|       |
+   LL|      1|    pub fn outer(is_true: bool) {
+   LL|      1|        println!("called and covered");
+   LL|      1|        inner_not_covered(is_true);
+   LL|      1|
+   LL|      1|        #[coverage(off)]
+   LL|      1|        fn inner_not_covered(is_true: bool) {
+   LL|      1|            if is_true {
+   LL|      1|                println!("called but not covered");
+   LL|      1|            } else {
+   LL|      1|                println!("absolutely not covered");
+   LL|      1|            }
+   LL|      1|        }
+   LL|      1|    }
+   LL|       |
+   LL|      1|    pub fn outer_both_covered(is_true: bool) {
+   LL|      1|        println!("called and covered");
+   LL|      1|        inner(is_true);
+   LL|      1|
+   LL|      1|        fn inner(is_true: bool) {
+   LL|      1|            if is_true {
+   LL|      1|                println!("called and covered");
+   LL|      1|            } else {
+   LL|      0|                println!("absolutely not covered");
+   LL|      0|            }
+   LL|      1|        }
+   LL|      1|    }
+   LL|       |}
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|
+   LL|      1|    do_not_add_coverage_1();
+   LL|      1|    do_not_add_coverage_2();
+   LL|      1|    add_coverage_1();
+   LL|      1|    add_coverage_2();
+   LL|      1|
+   LL|      1|    nested_fns::outer_not_covered(is_true);
+   LL|      1|    nested_fns::outer(is_true);
+   LL|      1|    nested_fns::outer_both_covered(is_true);
+   LL|      1|}
+
diff --git a/tests/coverage/no_cov_crate.rs b/tests/coverage/no_cov_crate.rs
new file mode 100644
index 00000000000..e12e4bc55e3
--- /dev/null
+++ b/tests/coverage/no_cov_crate.rs
@@ -0,0 +1,88 @@
+// Enables `coverage(off)` on the entire crate
+#![feature(coverage_attribute)]
+
+#[coverage(off)]
+fn do_not_add_coverage_1() {
+    println!("called but not covered");
+}
+
+fn do_not_add_coverage_2() {
+    #![coverage(off)]
+    println!("called but not covered");
+}
+
+#[coverage(off)]
+#[allow(dead_code)]
+fn do_not_add_coverage_not_called() {
+    println!("not called and not covered");
+}
+
+fn add_coverage_1() {
+    println!("called and covered");
+}
+
+fn add_coverage_2() {
+    println!("called and covered");
+}
+
+#[allow(dead_code)]
+fn add_coverage_not_called() {
+    println!("not called but covered");
+}
+
+// FIXME: These test-cases illustrate confusing results of nested functions.
+// See https://github.com/rust-lang/rust/issues/93319
+mod nested_fns {
+    #[coverage(off)]
+    pub fn outer_not_covered(is_true: bool) {
+        fn inner(is_true: bool) {
+            if is_true {
+                println!("called and covered");
+            } else {
+                println!("absolutely not covered");
+            }
+        }
+        println!("called but not covered");
+        inner(is_true);
+    }
+
+    pub fn outer(is_true: bool) {
+        println!("called and covered");
+        inner_not_covered(is_true);
+
+        #[coverage(off)]
+        fn inner_not_covered(is_true: bool) {
+            if is_true {
+                println!("called but not covered");
+            } else {
+                println!("absolutely not covered");
+            }
+        }
+    }
+
+    pub fn outer_both_covered(is_true: bool) {
+        println!("called and covered");
+        inner(is_true);
+
+        fn inner(is_true: bool) {
+            if is_true {
+                println!("called and covered");
+            } else {
+                println!("absolutely not covered");
+            }
+        }
+    }
+}
+
+fn main() {
+    let is_true = std::env::args().len() == 1;
+
+    do_not_add_coverage_1();
+    do_not_add_coverage_2();
+    add_coverage_1();
+    add_coverage_2();
+
+    nested_fns::outer_not_covered(is_true);
+    nested_fns::outer(is_true);
+    nested_fns::outer_both_covered(is_true);
+}
diff --git a/tests/coverage/overflow.coverage b/tests/coverage/overflow.coverage
new file mode 100644
index 00000000000..4f8dffc0c48
--- /dev/null
+++ b/tests/coverage/overflow.coverage
@@ -0,0 +1,65 @@
+   LL|       |#![allow(unused_assignments)]
+   LL|       |// compile-flags: -Coverflow-checks=yes
+   LL|       |// failure-status: 101
+   LL|       |
+   LL|      4|fn might_overflow(to_add: u32) -> u32 {
+   LL|      4|    if to_add > 5 {
+   LL|      1|        println!("this will probably overflow");
+   LL|      3|    }
+   LL|      4|    let add_to = u32::MAX - 5;
+   LL|      4|    println!("does {} + {} overflow?", add_to, to_add);
+   LL|      4|    let result = to_add + add_to;
+   LL|      4|    println!("continuing after overflow check");
+   LL|      4|    result
+   LL|      4|}
+   LL|       |
+   LL|      1|fn main() -> Result<(), u8> {
+   LL|      1|    let mut countdown = 10;
+   LL|     11|    while countdown > 0 {
+   LL|     11|        if countdown == 1 {
+   LL|      1|            let result = might_overflow(10);
+   LL|      1|            println!("Result: {}", result);
+   LL|     10|        } else if countdown < 5 {
+   LL|      3|            let result = might_overflow(1);
+   LL|      3|            println!("Result: {}", result);
+   LL|      6|        }
+   LL|     10|        countdown -= 1;
+   LL|       |    }
+   LL|      0|    Ok(())
+   LL|      0|}
+   LL|       |
+   LL|       |// Notes:
+   LL|       |//   1. Compare this program and its coverage results to those of the very similar test `assert.rs`,
+   LL|       |//      and similar tests `panic_unwind.rs`, abort.rs` and `try_error_result.rs`.
+   LL|       |//   2. This test confirms the coverage generated when a program passes or fails a
+   LL|       |//      compiler-generated `TerminatorKind::Assert` (based on an overflow check, in this case).
+   LL|       |//   3. Similar to how the coverage instrumentation handles `TerminatorKind::Call`,
+   LL|       |//      compiler-generated assertion failures are assumed to be a symptom of a program bug, not
+   LL|       |//      expected behavior. To simplify the coverage graphs and keep instrumented programs as
+   LL|       |//      small and fast as possible, `Assert` terminators are assumed to always succeed, and
+   LL|       |//      therefore are considered "non-branching" terminators. So, an `Assert` terminator does not
+   LL|       |//      get its own coverage counter.
+   LL|       |//   4. After an unhandled panic or failed Assert, coverage results may not always be intuitive.
+   LL|       |//      In this test, the final count for the statements after the `if` block in `might_overflow()`
+   LL|       |//      is 4, even though the lines after `to_add + add_to` were executed only 3 times. Depending
+   LL|       |//      on the MIR graph and the structure of the code, this count could have been 3 (which might
+   LL|       |//      have been valid for the overflowed add `+`, but should have been 4 for the lines before
+   LL|       |//      the overflow. The reason for this potential uncertainty is, a `CounterKind` is incremented
+   LL|       |//      via StatementKind::Counter at the end of the block, but (as in the case in this test),
+   LL|       |//      a CounterKind::Expression is always evaluated. In this case, the expression was based on
+   LL|       |//      a `Counter` incremented as part of the evaluation of the `if` expression, which was
+   LL|       |//      executed, and counted, 4 times, before reaching the overflow add.
+   LL|       |
+   LL|       |// If the program did not overflow, the coverage for `might_overflow()` would look like this:
+   LL|       |//
+   LL|       |//     4|       |fn might_overflow(to_add: u32) -> u32 {
+   LL|       |//     5|      4|    if to_add > 5 {
+   LL|       |//     6|      0|        println!("this will probably overflow");
+   LL|       |//     7|      4|    }
+   LL|       |//     8|      4|    let add_to = u32::MAX - 5;
+   LL|       |//     9|      4|    println!("does {} + {} overflow?", add_to, to_add);
+   LL|       |//    10|      4|    let result = to_add + add_to;
+   LL|       |//    11|      4|    println!("continuing after overflow check");
+   LL|       |//    12|      4|    result
+   LL|       |//    13|      4|}
+
diff --git a/tests/coverage/overflow.rs b/tests/coverage/overflow.rs
new file mode 100644
index 00000000000..1c40771b274
--- /dev/null
+++ b/tests/coverage/overflow.rs
@@ -0,0 +1,64 @@
+#![allow(unused_assignments)]
+// compile-flags: -Coverflow-checks=yes
+// failure-status: 101
+
+fn might_overflow(to_add: u32) -> u32 {
+    if to_add > 5 {
+        println!("this will probably overflow");
+    }
+    let add_to = u32::MAX - 5;
+    println!("does {} + {} overflow?", add_to, to_add);
+    let result = to_add + add_to;
+    println!("continuing after overflow check");
+    result
+}
+
+fn main() -> Result<(), u8> {
+    let mut countdown = 10;
+    while countdown > 0 {
+        if countdown == 1 {
+            let result = might_overflow(10);
+            println!("Result: {}", result);
+        } else if countdown < 5 {
+            let result = might_overflow(1);
+            println!("Result: {}", result);
+        }
+        countdown -= 1;
+    }
+    Ok(())
+}
+
+// Notes:
+//   1. Compare this program and its coverage results to those of the very similar test `assert.rs`,
+//      and similar tests `panic_unwind.rs`, abort.rs` and `try_error_result.rs`.
+//   2. This test confirms the coverage generated when a program passes or fails a
+//      compiler-generated `TerminatorKind::Assert` (based on an overflow check, in this case).
+//   3. Similar to how the coverage instrumentation handles `TerminatorKind::Call`,
+//      compiler-generated assertion failures are assumed to be a symptom of a program bug, not
+//      expected behavior. To simplify the coverage graphs and keep instrumented programs as
+//      small and fast as possible, `Assert` terminators are assumed to always succeed, and
+//      therefore are considered "non-branching" terminators. So, an `Assert` terminator does not
+//      get its own coverage counter.
+//   4. After an unhandled panic or failed Assert, coverage results may not always be intuitive.
+//      In this test, the final count for the statements after the `if` block in `might_overflow()`
+//      is 4, even though the lines after `to_add + add_to` were executed only 3 times. Depending
+//      on the MIR graph and the structure of the code, this count could have been 3 (which might
+//      have been valid for the overflowed add `+`, but should have been 4 for the lines before
+//      the overflow. The reason for this potential uncertainty is, a `CounterKind` is incremented
+//      via StatementKind::Counter at the end of the block, but (as in the case in this test),
+//      a CounterKind::Expression is always evaluated. In this case, the expression was based on
+//      a `Counter` incremented as part of the evaluation of the `if` expression, which was
+//      executed, and counted, 4 times, before reaching the overflow add.
+
+// If the program did not overflow, the coverage for `might_overflow()` would look like this:
+//
+//     4|       |fn might_overflow(to_add: u32) -> u32 {
+//     5|      4|    if to_add > 5 {
+//     6|      0|        println!("this will probably overflow");
+//     7|      4|    }
+//     8|      4|    let add_to = u32::MAX - 5;
+//     9|      4|    println!("does {} + {} overflow?", add_to, to_add);
+//    10|      4|    let result = to_add + add_to;
+//    11|      4|    println!("continuing after overflow check");
+//    12|      4|    result
+//    13|      4|}
diff --git a/tests/coverage/panic_unwind.coverage b/tests/coverage/panic_unwind.coverage
new file mode 100644
index 00000000000..2b0777ef215
--- /dev/null
+++ b/tests/coverage/panic_unwind.coverage
@@ -0,0 +1,32 @@
+   LL|       |#![allow(unused_assignments)]
+   LL|       |// failure-status: 101
+   LL|       |
+   LL|      4|fn might_panic(should_panic: bool) {
+   LL|      4|    if should_panic {
+   LL|      1|        println!("panicking...");
+   LL|      1|        panic!("panics");
+   LL|      3|    } else {
+   LL|      3|        println!("Don't Panic");
+   LL|      3|    }
+   LL|      3|}
+   LL|       |
+   LL|      1|fn main() -> Result<(), u8> {
+   LL|      1|    let mut countdown = 10;
+   LL|     11|    while countdown > 0 {
+   LL|     11|        if countdown == 1 {
+   LL|      1|            might_panic(true);
+   LL|     10|        } else if countdown < 5 {
+   LL|      3|            might_panic(false);
+   LL|      6|        }
+   LL|     10|        countdown -= 1;
+   LL|       |    }
+   LL|      0|    Ok(())
+   LL|      0|}
+   LL|       |
+   LL|       |// Notes:
+   LL|       |//   1. Compare this program and its coverage results to those of the similar tests `abort.rs` and
+   LL|       |//      `try_error_result.rs`.
+   LL|       |//   2. Since the `panic_unwind.rs` test is allowed to unwind, it is also allowed to execute the
+   LL|       |//      normal program exit cleanup, including writing out the current values of the coverage
+   LL|       |//      counters.
+
diff --git a/tests/coverage/panic_unwind.rs b/tests/coverage/panic_unwind.rs
new file mode 100644
index 00000000000..638d2eb6aaa
--- /dev/null
+++ b/tests/coverage/panic_unwind.rs
@@ -0,0 +1,31 @@
+#![allow(unused_assignments)]
+// failure-status: 101
+
+fn might_panic(should_panic: bool) {
+    if should_panic {
+        println!("panicking...");
+        panic!("panics");
+    } else {
+        println!("Don't Panic");
+    }
+}
+
+fn main() -> Result<(), u8> {
+    let mut countdown = 10;
+    while countdown > 0 {
+        if countdown == 1 {
+            might_panic(true);
+        } else if countdown < 5 {
+            might_panic(false);
+        }
+        countdown -= 1;
+    }
+    Ok(())
+}
+
+// Notes:
+//   1. Compare this program and its coverage results to those of the similar tests `abort.rs` and
+//      `try_error_result.rs`.
+//   2. Since the `panic_unwind.rs` test is allowed to unwind, it is also allowed to execute the
+//      normal program exit cleanup, including writing out the current values of the coverage
+//      counters.
diff --git a/tests/coverage/partial_eq.coverage b/tests/coverage/partial_eq.coverage
new file mode 100644
index 00000000000..c6d9ad6cf27
--- /dev/null
+++ b/tests/coverage/partial_eq.coverage
@@ -0,0 +1,48 @@
+   LL|       |// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the
+   LL|       |// structure of this test.
+   LL|       |
+   LL|      2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+                       ^0            ^0      ^0     ^1       ^1 ^0^0
+   LL|       |pub struct Version {
+   LL|       |    major: usize,
+   LL|       |    minor: usize,
+   LL|       |    patch: usize,
+   LL|       |}
+   LL|       |
+   LL|       |impl Version {
+   LL|      2|    pub fn new(major: usize, minor: usize, patch: usize) -> Self {
+   LL|      2|        Self {
+   LL|      2|            major,
+   LL|      2|            minor,
+   LL|      2|            patch,
+   LL|      2|        }
+   LL|      2|    }
+   LL|       |}
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let version_3_2_1 = Version::new(3, 2, 1);
+   LL|      1|    let version_3_3_0 = Version::new(3, 3, 0);
+   LL|      1|
+   LL|      1|    println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0);
+   LL|      1|}
+   LL|       |
+   LL|       |/*
+   LL|       |
+   LL|       |This test verifies a bug was fixed that otherwise generated this error:
+   LL|       |
+   LL|       |thread 'rustc' panicked at 'No counters provided the source_hash for function:
+   LL|       |    Instance {
+   LL|       |        def: Item(WithOptConstParam {
+   LL|       |            did: DefId(0:101 ~ autocfg[c44a]::version::{impl#2}::partial_cmp),
+   LL|       |            const_param_did: None
+   LL|       |        }),
+   LL|       |        args: []
+   LL|       |    }'
+   LL|       |The `PartialOrd` derived by `Version` happened to generate a MIR that generated coverage
+   LL|       |without a code region associated with any `Counter`. Code regions were associated with at least
+   LL|       |one expression, which is allowed, but the `function_source_hash` was only passed to the codegen
+   LL|       |(coverage mapgen) phase from a `Counter`s code region. A new method was added to pass the
+   LL|       |`function_source_hash` without a code region, if necessary.
+   LL|       |
+   LL|       |*/
+
diff --git a/tests/coverage/partial_eq.rs b/tests/coverage/partial_eq.rs
new file mode 100644
index 00000000000..dd8b42c18ce
--- /dev/null
+++ b/tests/coverage/partial_eq.rs
@@ -0,0 +1,46 @@
+// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the
+// structure of this test.
+
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Version {
+    major: usize,
+    minor: usize,
+    patch: usize,
+}
+
+impl Version {
+    pub fn new(major: usize, minor: usize, patch: usize) -> Self {
+        Self {
+            major,
+            minor,
+            patch,
+        }
+    }
+}
+
+fn main() {
+    let version_3_2_1 = Version::new(3, 2, 1);
+    let version_3_3_0 = Version::new(3, 3, 0);
+
+    println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0);
+}
+
+/*
+
+This test verifies a bug was fixed that otherwise generated this error:
+
+thread 'rustc' panicked at 'No counters provided the source_hash for function:
+    Instance {
+        def: Item(WithOptConstParam {
+            did: DefId(0:101 ~ autocfg[c44a]::version::{impl#2}::partial_cmp),
+            const_param_did: None
+        }),
+        args: []
+    }'
+The `PartialOrd` derived by `Version` happened to generate a MIR that generated coverage
+without a code region associated with any `Counter`. Code regions were associated with at least
+one expression, which is allowed, but the `function_source_hash` was only passed to the codegen
+(coverage mapgen) phase from a `Counter`s code region. A new method was added to pass the
+`function_source_hash` without a code region, if necessary.
+
+*/
diff --git a/tests/coverage/simple_loop.coverage b/tests/coverage/simple_loop.coverage
new file mode 100644
index 00000000000..691c6cd1e7d
--- /dev/null
+++ b/tests/coverage/simple_loop.coverage
@@ -0,0 +1,37 @@
+   LL|       |#![allow(unused_assignments)]
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      1|    // dependent conditions.
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|
+   LL|      1|    let mut countdown = 0;
+   LL|      1|
+   LL|      1|    if
+   LL|      1|        is_true
+   LL|      1|    {
+   LL|      1|        countdown
+   LL|      1|        =
+   LL|      1|            10
+   LL|      1|        ;
+   LL|      1|    }
+                   ^0
+   LL|       |
+   LL|       |    loop
+   LL|       |    {
+   LL|       |        if
+   LL|     11|            countdown
+   LL|     11|                ==
+   LL|     11|            0
+   LL|       |        {
+   LL|      1|            break
+   LL|       |            ;
+   LL|     10|        }
+   LL|     10|        countdown
+   LL|     10|        -=
+   LL|     10|        1
+   LL|       |        ;
+   LL|       |    }
+   LL|      1|}
+
diff --git a/tests/coverage/simple_loop.rs b/tests/coverage/simple_loop.rs
new file mode 100644
index 00000000000..6f7f23475b8
--- /dev/null
+++ b/tests/coverage/simple_loop.rs
@@ -0,0 +1,35 @@
+#![allow(unused_assignments)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 0;
+
+    if
+        is_true
+    {
+        countdown
+        =
+            10
+        ;
+    }
+
+    loop
+    {
+        if
+            countdown
+                ==
+            0
+        {
+            break
+            ;
+        }
+        countdown
+        -=
+        1
+        ;
+    }
+}
diff --git a/tests/coverage/simple_match.coverage b/tests/coverage/simple_match.coverage
new file mode 100644
index 00000000000..7f5dd3bb646
--- /dev/null
+++ b/tests/coverage/simple_match.coverage
@@ -0,0 +1,45 @@
+   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      1|    // dependent conditions.
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|
+   LL|      1|    let mut countdown = 1;
+   LL|      1|    if is_true {
+   LL|      1|        countdown = 0;
+   LL|      1|    }
+                   ^0
+   LL|       |
+   LL|       |    for
+   LL|       |        _
+   LL|       |    in
+   LL|      3|        0..2
+   LL|       |    {
+   LL|       |        let z
+   LL|       |        ;
+   LL|       |        match
+   LL|      2|            countdown
+   LL|       |        {
+   LL|      1|            x
+   LL|       |            if
+   LL|      2|                x
+   LL|      2|                    <
+   LL|      2|                1
+   LL|       |            =>
+   LL|      1|            {
+   LL|      1|                z = countdown
+   LL|      1|                ;
+   LL|      1|                let y = countdown
+   LL|      1|                ;
+   LL|      1|                countdown = 10
+   LL|      1|                ;
+   LL|      1|            }
+   LL|       |            _
+   LL|       |            =>
+   LL|      1|            {}
+   LL|       |        }
+   LL|       |    }
+   LL|      1|}
+
diff --git a/tests/coverage/simple_match.rs b/tests/coverage/simple_match.rs
new file mode 100644
index 00000000000..be99e59a826
--- /dev/null
+++ b/tests/coverage/simple_match.rs
@@ -0,0 +1,43 @@
+#![allow(unused_assignments, unused_variables)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut countdown = 1;
+    if is_true {
+        countdown = 0;
+    }
+
+    for
+        _
+    in
+        0..2
+    {
+        let z
+        ;
+        match
+            countdown
+        {
+            x
+            if
+                x
+                    <
+                1
+            =>
+            {
+                z = countdown
+                ;
+                let y = countdown
+                ;
+                countdown = 10
+                ;
+            }
+            _
+            =>
+            {}
+        }
+    }
+}
diff --git a/tests/coverage/sort_groups.coverage b/tests/coverage/sort_groups.coverage
new file mode 100644
index 00000000000..c70d7b3b282
--- /dev/null
+++ b/tests/coverage/sort_groups.coverage
@@ -0,0 +1,49 @@
+   LL|       |// compile-flags: --edition=2021
+   LL|       |
+   LL|       |// Demonstrate that `sort_subviews.py` can sort instantiation groups into a
+   LL|       |// predictable order, while preserving their heterogeneous contents.
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let cond = std::env::args().len() > 1;
+   LL|      1|    generic_fn::<()>(cond);
+   LL|      1|    generic_fn::<&'static str>(!cond);
+   LL|      1|    if std::hint::black_box(false) {
+   LL|      0|        generic_fn::<char>(cond);
+   LL|      1|    }
+   LL|      1|    generic_fn::<i32>(cond);
+   LL|      1|    other_fn();
+   LL|      1|}
+   LL|       |
+   LL|      3|fn generic_fn<T>(cond: bool) {
+   LL|      3|    if cond {
+   LL|      1|        println!("{}", std::any::type_name::<T>());
+   LL|      2|    }
+   LL|      3|}
+  ------------------
+  | Unexecuted instantiation: sort_groups::generic_fn::<char>
+  ------------------
+  | sort_groups::generic_fn::<&str>:
+  |   LL|      1|fn generic_fn<T>(cond: bool) {
+  |   LL|      1|    if cond {
+  |   LL|      1|        println!("{}", std::any::type_name::<T>());
+  |   LL|      1|    }
+  |                   ^0
+  |   LL|      1|}
+  ------------------
+  | sort_groups::generic_fn::<()>:
+  |   LL|      1|fn generic_fn<T>(cond: bool) {
+  |   LL|      1|    if cond {
+  |   LL|      0|        println!("{}", std::any::type_name::<T>());
+  |   LL|      1|    }
+  |   LL|      1|}
+  ------------------
+  | sort_groups::generic_fn::<i32>:
+  |   LL|      1|fn generic_fn<T>(cond: bool) {
+  |   LL|      1|    if cond {
+  |   LL|      0|        println!("{}", std::any::type_name::<T>());
+  |   LL|      1|    }
+  |   LL|      1|}
+  ------------------
+   LL|       |
+   LL|      1|fn other_fn() {}
+
diff --git a/tests/coverage/sort_groups.rs b/tests/coverage/sort_groups.rs
new file mode 100644
index 00000000000..5adbbc6a87d
--- /dev/null
+++ b/tests/coverage/sort_groups.rs
@@ -0,0 +1,23 @@
+// compile-flags: --edition=2021
+
+// Demonstrate that `sort_subviews.py` can sort instantiation groups into a
+// predictable order, while preserving their heterogeneous contents.
+
+fn main() {
+    let cond = std::env::args().len() > 1;
+    generic_fn::<()>(cond);
+    generic_fn::<&'static str>(!cond);
+    if std::hint::black_box(false) {
+        generic_fn::<char>(cond);
+    }
+    generic_fn::<i32>(cond);
+    other_fn();
+}
+
+fn generic_fn<T>(cond: bool) {
+    if cond {
+        println!("{}", std::any::type_name::<T>());
+    }
+}
+
+fn other_fn() {}
diff --git a/tests/coverage/test_harness.coverage b/tests/coverage/test_harness.coverage
new file mode 100644
index 00000000000..ff6009f6fce
--- /dev/null
+++ b/tests/coverage/test_harness.coverage
@@ -0,0 +1,11 @@
+   LL|       |// Verify that the entry point injected by the test harness doesn't cause
+   LL|       |// weird artifacts in the coverage report (e.g. issue #10749).
+   LL|       |
+   LL|       |// compile-flags: --test
+   LL|       |
+   LL|       |#[allow(dead_code)]
+   LL|      0|fn unused() {}
+   LL|       |
+   LL|      1|#[test]
+   LL|      1|fn my_test() {}
+
diff --git a/tests/coverage/test_harness.rs b/tests/coverage/test_harness.rs
new file mode 100644
index 00000000000..12a755734c1
--- /dev/null
+++ b/tests/coverage/test_harness.rs
@@ -0,0 +1,10 @@
+// Verify that the entry point injected by the test harness doesn't cause
+// weird artifacts in the coverage report (e.g. issue #10749).
+
+// compile-flags: --test
+
+#[allow(dead_code)]
+fn unused() {}
+
+#[test]
+fn my_test() {}
diff --git a/tests/coverage/tight_inf_loop.coverage b/tests/coverage/tight_inf_loop.coverage
new file mode 100644
index 00000000000..c15c76b3aba
--- /dev/null
+++ b/tests/coverage/tight_inf_loop.coverage
@@ -0,0 +1,6 @@
+   LL|      1|fn main() {
+   LL|      1|    if false {
+   LL|      0|        loop {}
+   LL|      1|    }
+   LL|      1|}
+
diff --git a/tests/coverage/tight_inf_loop.rs b/tests/coverage/tight_inf_loop.rs
new file mode 100644
index 00000000000..cef99027aaa
--- /dev/null
+++ b/tests/coverage/tight_inf_loop.rs
@@ -0,0 +1,5 @@
+fn main() {
+    if false {
+        loop {}
+    }
+}
diff --git a/tests/coverage/trivial.coverage b/tests/coverage/trivial.coverage
new file mode 100644
index 00000000000..4f417979ef9
--- /dev/null
+++ b/tests/coverage/trivial.coverage
@@ -0,0 +1,4 @@
+   LL|       |// compile-flags: --edition=2021
+   LL|       |
+   LL|      1|fn main() {}
+
diff --git a/tests/coverage/trivial.rs b/tests/coverage/trivial.rs
new file mode 100644
index 00000000000..d0a9b44fb36
--- /dev/null
+++ b/tests/coverage/trivial.rs
@@ -0,0 +1,3 @@
+// compile-flags: --edition=2021
+
+fn main() {}
diff --git a/tests/coverage/try_error_result.coverage b/tests/coverage/try_error_result.coverage
new file mode 100644
index 00000000000..5d48cbd62f2
--- /dev/null
+++ b/tests/coverage/try_error_result.coverage
@@ -0,0 +1,125 @@
+   LL|       |#![allow(unused_assignments)]
+   LL|       |// failure-status: 1
+   LL|       |
+   LL|      6|fn call(return_error: bool) -> Result<(), ()> {
+   LL|      6|    if return_error {
+   LL|      1|        Err(())
+   LL|       |    } else {
+   LL|      5|        Ok(())
+   LL|       |    }
+   LL|      6|}
+   LL|       |
+   LL|      1|fn test1() -> Result<(), ()> {
+   LL|      1|    let mut
+   LL|      1|        countdown = 10
+   LL|       |    ;
+   LL|       |    for
+   LL|       |        _
+   LL|       |    in
+   LL|      6|        0..10
+   LL|       |    {
+   LL|      6|        countdown
+   LL|      6|            -= 1
+   LL|      6|        ;
+   LL|      6|        if
+   LL|      6|            countdown < 5
+   LL|       |        {
+   LL|      1|            call(/*return_error=*/ true)?;
+   LL|      0|            call(/*return_error=*/ false)?;
+   LL|       |        }
+   LL|       |        else
+   LL|       |        {
+   LL|      5|            call(/*return_error=*/ false)?;
+                                                       ^0
+   LL|       |        }
+   LL|       |    }
+   LL|      0|    Ok(())
+   LL|      1|}
+   LL|       |
+   LL|       |struct Thing1;
+   LL|       |impl Thing1 {
+   LL|     18|    fn get_thing_2(&self, return_error: bool) -> Result<Thing2, ()> {
+   LL|     18|        if return_error {
+   LL|      1|            Err(())
+   LL|       |        } else {
+   LL|     17|            Ok(Thing2 {})
+   LL|       |        }
+   LL|     18|    }
+   LL|       |}
+   LL|       |
+   LL|       |struct Thing2;
+   LL|       |impl Thing2 {
+   LL|     17|    fn call(&self, return_error: bool) -> Result<u32, ()> {
+   LL|     17|        if return_error {
+   LL|      2|            Err(())
+   LL|       |        } else {
+   LL|     15|            Ok(57)
+   LL|       |        }
+   LL|     17|    }
+   LL|       |}
+   LL|       |
+   LL|      1|fn test2() -> Result<(), ()> {
+   LL|      1|    let thing1 = Thing1{};
+   LL|      1|    let mut
+   LL|      1|        countdown = 10
+   LL|       |    ;
+   LL|       |    for
+   LL|       |        _
+   LL|       |    in
+   LL|      6|        0..10
+   LL|       |    {
+   LL|      6|        countdown
+   LL|      6|            -= 1
+   LL|      6|        ;
+   LL|      6|        if
+   LL|      6|            countdown < 5
+   LL|       |        {
+   LL|      1|            thing1.get_thing_2(/*err=*/ false)?.call(/*err=*/ true).expect_err("call should fail");
+                                                            ^0
+   LL|      1|            thing1
+   LL|      1|                .
+   LL|      1|                get_thing_2(/*return_error=*/ false)
+   LL|      0|                ?
+   LL|       |                .
+   LL|      1|                call(/*return_error=*/ true)
+   LL|      1|                .
+   LL|      1|                expect_err(
+   LL|      1|                    "call should fail"
+   LL|      1|                );
+   LL|      1|            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ true)?;
+                              ^0                                                ^0                          ^0
+   LL|      0|            assert_eq!(val, 57);
+   LL|      0|            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ false)?;
+   LL|      0|            assert_eq!(val, 57);
+   LL|       |        }
+   LL|       |        else
+   LL|       |        {
+   LL|      5|            let val = thing1.get_thing_2(/*return_error=*/ false)?.call(/*return_error=*/ false)?;
+                                                                               ^0                             ^0
+   LL|      5|            assert_eq!(val, 57);
+   LL|      5|            let val = thing1
+   LL|      5|                .get_thing_2(/*return_error=*/ false)?
+                                                                   ^0
+   LL|      5|                .call(/*return_error=*/ false)?;
+                                                            ^0
+   LL|      5|            assert_eq!(val, 57);
+   LL|      5|            let val = thing1
+   LL|      5|                .get_thing_2(/*return_error=*/ false)
+   LL|      0|                ?
+   LL|      5|                .call(/*return_error=*/ false)
+   LL|      0|                ?
+   LL|       |                ;
+   LL|      5|            assert_eq!(val, 57);
+   LL|       |        }
+   LL|       |    }
+   LL|      0|    Ok(())
+   LL|      1|}
+   LL|       |
+   LL|      1|fn main() -> Result<(), ()> {
+   LL|      1|    test1().expect_err("test1 should fail");
+   LL|      1|    test2()
+   LL|      1|    ?
+   LL|       |    ;
+   LL|      0|    Ok(())
+   LL|      1|}
+
diff --git a/tests/coverage/try_error_result.rs b/tests/coverage/try_error_result.rs
new file mode 100644
index 00000000000..557cbf22bfa
--- /dev/null
+++ b/tests/coverage/try_error_result.rs
@@ -0,0 +1,118 @@
+#![allow(unused_assignments)]
+// failure-status: 1
+
+fn call(return_error: bool) -> Result<(), ()> {
+    if return_error {
+        Err(())
+    } else {
+        Ok(())
+    }
+}
+
+fn test1() -> Result<(), ()> {
+    let mut
+        countdown = 10
+    ;
+    for
+        _
+    in
+        0..10
+    {
+        countdown
+            -= 1
+        ;
+        if
+            countdown < 5
+        {
+            call(/*return_error=*/ true)?;
+            call(/*return_error=*/ false)?;
+        }
+        else
+        {
+            call(/*return_error=*/ false)?;
+        }
+    }
+    Ok(())
+}
+
+struct Thing1;
+impl Thing1 {
+    fn get_thing_2(&self, return_error: bool) -> Result<Thing2, ()> {
+        if return_error {
+            Err(())
+        } else {
+            Ok(Thing2 {})
+        }
+    }
+}
+
+struct Thing2;
+impl Thing2 {
+    fn call(&self, return_error: bool) -> Result<u32, ()> {
+        if return_error {
+            Err(())
+        } else {
+            Ok(57)
+        }
+    }
+}
+
+fn test2() -> Result<(), ()> {
+    let thing1 = Thing1{};
+    let mut
+        countdown = 10
+    ;
+    for
+        _
+    in
+        0..10
+    {
+        countdown
+            -= 1
+        ;
+        if
+            countdown < 5
+        {
+            thing1.get_thing_2(/*err=*/ false)?.call(/*err=*/ true).expect_err("call should fail");
+            thing1
+                .
+                get_thing_2(/*return_error=*/ false)
+                ?
+                .
+                call(/*return_error=*/ true)
+                .
+                expect_err(
+                    "call should fail"
+                );
+            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ true)?;
+            assert_eq!(val, 57);
+            let val = thing1.get_thing_2(/*return_error=*/ true)?.call(/*return_error=*/ false)?;
+            assert_eq!(val, 57);
+        }
+        else
+        {
+            let val = thing1.get_thing_2(/*return_error=*/ false)?.call(/*return_error=*/ false)?;
+            assert_eq!(val, 57);
+            let val = thing1
+                .get_thing_2(/*return_error=*/ false)?
+                .call(/*return_error=*/ false)?;
+            assert_eq!(val, 57);
+            let val = thing1
+                .get_thing_2(/*return_error=*/ false)
+                ?
+                .call(/*return_error=*/ false)
+                ?
+                ;
+            assert_eq!(val, 57);
+        }
+    }
+    Ok(())
+}
+
+fn main() -> Result<(), ()> {
+    test1().expect_err("test1 should fail");
+    test2()
+    ?
+    ;
+    Ok(())
+}
diff --git a/tests/coverage/unreachable.coverage b/tests/coverage/unreachable.coverage
new file mode 100644
index 00000000000..fa0ac9ccfa1
--- /dev/null
+++ b/tests/coverage/unreachable.coverage
@@ -0,0 +1,38 @@
+   LL|       |#![feature(core_intrinsics)]
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |// compile-flags: --edition=2021
+   LL|       |
+   LL|       |// <https://github.com/rust-lang/rust/issues/116171>
+   LL|       |// If we instrument a function for coverage, but all of its counter-increment
+   LL|       |// statements are removed by MIR optimizations, LLVM will think it isn't
+   LL|       |// instrumented and it will disappear from coverage maps and coverage reports.
+   LL|       |// Most MIR opts won't cause this because they tend not to remove statements
+   LL|       |// from bb0, but `UnreachablePropagation` can do so if it sees that bb0 ends
+   LL|       |// with `TerminatorKind::Unreachable`.
+   LL|       |
+   LL|       |use std::hint::{black_box, unreachable_unchecked};
+   LL|       |
+   LL|      0|static UNREACHABLE_CLOSURE: fn() = || unsafe { unreachable_unchecked() };
+   LL|       |
+   LL|      0|fn unreachable_function() {
+   LL|      0|    unsafe { unreachable_unchecked() }
+   LL|      0|}
+   LL|       |
+   LL|       |// Use an intrinsic to more reliably trigger unreachable-propagation.
+   LL|      0|fn unreachable_intrinsic() {
+   LL|      0|    unsafe { std::intrinsics::unreachable() }
+   LL|      0|}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn main() {
+   LL|       |    if black_box(false) {
+   LL|       |        UNREACHABLE_CLOSURE();
+   LL|       |    }
+   LL|       |    if black_box(false) {
+   LL|       |        unreachable_function();
+   LL|       |    }
+   LL|       |    if black_box(false) {
+   LL|       |        unreachable_intrinsic();
+   LL|       |    }
+   LL|       |}
+
diff --git a/tests/coverage/unreachable.rs b/tests/coverage/unreachable.rs
new file mode 100644
index 00000000000..6385bfa160d
--- /dev/null
+++ b/tests/coverage/unreachable.rs
@@ -0,0 +1,37 @@
+#![feature(core_intrinsics)]
+#![feature(coverage_attribute)]
+// compile-flags: --edition=2021
+
+// <https://github.com/rust-lang/rust/issues/116171>
+// If we instrument a function for coverage, but all of its counter-increment
+// statements are removed by MIR optimizations, LLVM will think it isn't
+// instrumented and it will disappear from coverage maps and coverage reports.
+// Most MIR opts won't cause this because they tend not to remove statements
+// from bb0, but `UnreachablePropagation` can do so if it sees that bb0 ends
+// with `TerminatorKind::Unreachable`.
+
+use std::hint::{black_box, unreachable_unchecked};
+
+static UNREACHABLE_CLOSURE: fn() = || unsafe { unreachable_unchecked() };
+
+fn unreachable_function() {
+    unsafe { unreachable_unchecked() }
+}
+
+// Use an intrinsic to more reliably trigger unreachable-propagation.
+fn unreachable_intrinsic() {
+    unsafe { std::intrinsics::unreachable() }
+}
+
+#[coverage(off)]
+fn main() {
+    if black_box(false) {
+        UNREACHABLE_CLOSURE();
+    }
+    if black_box(false) {
+        unreachable_function();
+    }
+    if black_box(false) {
+        unreachable_intrinsic();
+    }
+}
diff --git a/tests/coverage/unused.coverage b/tests/coverage/unused.coverage
new file mode 100644
index 00000000000..056ffeb021a
--- /dev/null
+++ b/tests/coverage/unused.coverage
@@ -0,0 +1,64 @@
+   LL|       |#![allow(dead_code, unused_assignments, unused_must_use, unused_variables)]
+   LL|       |
+   LL|      2|fn foo<T>(x: T) {
+   LL|      2|    let mut i = 0;
+   LL|     22|    while i < 10 {
+   LL|     20|        i != 0 || i != 0;
+                                ^2
+   LL|     20|        i += 1;
+   LL|       |    }
+   LL|      2|}
+  ------------------
+  | unused::foo::<f32>:
+  |   LL|      1|fn foo<T>(x: T) {
+  |   LL|      1|    let mut i = 0;
+  |   LL|     11|    while i < 10 {
+  |   LL|     10|        i != 0 || i != 0;
+  |                                ^1
+  |   LL|     10|        i += 1;
+  |   LL|       |    }
+  |   LL|      1|}
+  ------------------
+  | unused::foo::<u32>:
+  |   LL|      1|fn foo<T>(x: T) {
+  |   LL|      1|    let mut i = 0;
+  |   LL|     11|    while i < 10 {
+  |   LL|     10|        i != 0 || i != 0;
+  |                                ^1
+  |   LL|     10|        i += 1;
+  |   LL|       |    }
+  |   LL|      1|}
+  ------------------
+   LL|       |
+   LL|      0|fn unused_template_func<T>(x: T) {
+   LL|      0|    let mut i = 0;
+   LL|      0|    while i < 10 {
+   LL|      0|        i != 0 || i != 0;
+   LL|      0|        i += 1;
+   LL|       |    }
+   LL|      0|}
+   LL|       |
+   LL|      0|fn unused_func(mut a: u32) {
+   LL|      0|    if a != 0 {
+   LL|      0|        a += 1;
+   LL|      0|    }
+   LL|      0|}
+   LL|       |
+   LL|      0|fn unused_func2(mut a: u32) {
+   LL|      0|    if a != 0 {
+   LL|      0|        a += 1;
+   LL|      0|    }
+   LL|      0|}
+   LL|       |
+   LL|      0|fn unused_func3(mut a: u32) {
+   LL|      0|    if a != 0 {
+   LL|      0|        a += 1;
+   LL|      0|    }
+   LL|      0|}
+   LL|       |
+   LL|      1|fn main() -> Result<(), u8> {
+   LL|      1|    foo::<u32>(0);
+   LL|      1|    foo::<f32>(0.0);
+   LL|      1|    Ok(())
+   LL|      1|}
+
diff --git a/tests/coverage/unused.rs b/tests/coverage/unused.rs
new file mode 100644
index 00000000000..d985af13547
--- /dev/null
+++ b/tests/coverage/unused.rs
@@ -0,0 +1,41 @@
+#![allow(dead_code, unused_assignments, unused_must_use, unused_variables)]
+
+fn foo<T>(x: T) {
+    let mut i = 0;
+    while i < 10 {
+        i != 0 || i != 0;
+        i += 1;
+    }
+}
+
+fn unused_template_func<T>(x: T) {
+    let mut i = 0;
+    while i < 10 {
+        i != 0 || i != 0;
+        i += 1;
+    }
+}
+
+fn unused_func(mut a: u32) {
+    if a != 0 {
+        a += 1;
+    }
+}
+
+fn unused_func2(mut a: u32) {
+    if a != 0 {
+        a += 1;
+    }
+}
+
+fn unused_func3(mut a: u32) {
+    if a != 0 {
+        a += 1;
+    }
+}
+
+fn main() -> Result<(), u8> {
+    foo::<u32>(0);
+    foo::<f32>(0.0);
+    Ok(())
+}
diff --git a/tests/coverage/unused_mod.coverage b/tests/coverage/unused_mod.coverage
new file mode 100644
index 00000000000..a8fa24ac6a7
--- /dev/null
+++ b/tests/coverage/unused_mod.coverage
@@ -0,0 +1,14 @@
+$DIR/auxiliary/unused_mod_helper.rs:
+   LL|       |#[allow(dead_code)]
+   LL|      0|pub fn never_called_function() {
+   LL|      0|    println!("I am never called");
+   LL|      0|}
+
+$DIR/unused_mod.rs:
+   LL|       |#[path = "auxiliary/unused_mod_helper.rs"]
+   LL|       |mod unused_module;
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    println!("hello world!");
+   LL|      1|}
+
diff --git a/tests/coverage/unused_mod.rs b/tests/coverage/unused_mod.rs
new file mode 100644
index 00000000000..6e62839c998
--- /dev/null
+++ b/tests/coverage/unused_mod.rs
@@ -0,0 +1,6 @@
+#[path = "auxiliary/unused_mod_helper.rs"]
+mod unused_module;
+
+fn main() {
+    println!("hello world!");
+}
diff --git a/tests/coverage/uses_crate.coverage b/tests/coverage/uses_crate.coverage
new file mode 100644
index 00000000000..50d92102a10
--- /dev/null
+++ b/tests/coverage/uses_crate.coverage
@@ -0,0 +1,173 @@
+$DIR/auxiliary/used_crate.rs:
+   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |// Verify that coverage works with optimizations:
+   LL|       |// compile-flags: -C opt-level=3
+   LL|       |
+   LL|       |use std::fmt::Debug;
+   LL|       |
+   LL|      1|pub fn used_function() {
+   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      1|    // dependent conditions.
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|    let mut countdown = 0;
+   LL|      1|    if is_true {
+   LL|      1|        countdown = 10;
+   LL|      1|    }
+                   ^0
+   LL|      1|    use_this_lib_crate();
+   LL|      1|}
+   LL|       |
+   LL|      2|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+   LL|      2|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+   LL|      2|}
+  ------------------
+  | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
+  ------------------
+  | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
+  |   LL|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+  |   LL|      1|}
+  ------------------
+  | used_crate::used_only_from_bin_crate_generic_function::<&str>:
+  |   LL|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+  |   LL|      1|}
+  ------------------
+   LL|       |// Expect for above function: `Unexecuted instantiation` (see below)
+   LL|      2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+   LL|      2|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+   LL|      2|}
+  ------------------
+  | used_crate::used_only_from_this_lib_crate_generic_function::<&str>:
+  |   LL|      1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      1|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+  |   LL|      1|}
+  ------------------
+  | used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+  |   LL|      1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      1|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+  |   LL|      1|}
+  ------------------
+   LL|       |
+   LL|      2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+   LL|      2|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+   LL|      2|}
+  ------------------
+  | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
+  |   LL|      1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      1|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   LL|      1|}
+  ------------------
+  | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+  |   LL|      1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      1|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   LL|      1|}
+  ------------------
+   LL|       |
+   LL|      2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+   LL|      2|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+   LL|      2|}
+  ------------------
+  | used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
+  |   LL|      1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      1|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   LL|      1|}
+  ------------------
+  | used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
+  |   LL|      1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      1|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   LL|      1|}
+  ------------------
+   LL|       |
+   LL|      0|pub fn unused_generic_function<T: Debug>(arg: T) {
+   LL|      0|    println!("unused_generic_function with {:?}", arg);
+   LL|      0|}
+   LL|       |
+   LL|      0|pub fn unused_function() {
+   LL|      0|    let is_true = std::env::args().len() == 1;
+   LL|      0|    let mut countdown = 2;
+   LL|      0|    if !is_true {
+   LL|      0|        countdown = 20;
+   LL|      0|    }
+   LL|      0|}
+   LL|       |
+   LL|       |#[allow(dead_code)]
+   LL|      0|fn unused_private_function() {
+   LL|      0|    let is_true = std::env::args().len() == 1;
+   LL|      0|    let mut countdown = 2;
+   LL|      0|    if !is_true {
+   LL|      0|        countdown = 20;
+   LL|      0|    }
+   LL|      0|}
+   LL|       |
+   LL|      1|fn use_this_lib_crate() {
+   LL|      1|    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
+   LL|      1|    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
+   LL|      1|        "used from library used_crate.rs",
+   LL|      1|    );
+   LL|      1|    let some_vec = vec![5, 6, 7, 8];
+   LL|      1|    used_only_from_this_lib_crate_generic_function(some_vec);
+   LL|      1|    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
+   LL|      1|}
+   LL|       |
+   LL|       |// FIXME(#79651): "Unexecuted instantiation" errors appear in coverage results,
+   LL|       |// for example:
+   LL|       |//
+   LL|       |// | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
+   LL|       |//
+   LL|       |// These notices appear when `llvm-cov` shows instantiations. This may be a
+   LL|       |// default option, but it can be suppressed with:
+   LL|       |//
+   LL|       |// ```shell
+   LL|       |// $ `llvm-cov show --show-instantiations=0 ...`
+   LL|       |// ```
+   LL|       |//
+   LL|       |// The notice is triggered because the function is unused by the library itself,
+   LL|       |// and when the library is compiled, a synthetic function is generated, so
+   LL|       |// unused function coverage can be reported. Coverage can be skipped for unused
+   LL|       |// generic functions with:
+   LL|       |//
+   LL|       |// ```shell
+   LL|       |// $ `rustc -Zunstable-options -C instrument-coverage=except-unused-generics ...`
+   LL|       |// ```
+   LL|       |//
+   LL|       |// Even though this function is used by `uses_crate.rs` (and
+   LL|       |// counted), with substitutions for `T`, those instantiations are only generated
+   LL|       |// when the generic function is actually used (from the binary, not from this
+   LL|       |// library crate). So the test result shows coverage for all instantiated
+   LL|       |// versions and their generic type substitutions, plus the `Unexecuted
+   LL|       |// instantiation` message for the non-substituted version. This is valid, but
+   LL|       |// unfortunately a little confusing.
+   LL|       |//
+   LL|       |// The library crate has its own coverage map, and the only way to show unused
+   LL|       |// coverage of a generic function is to include the generic function in the
+   LL|       |// coverage map, marked as an "unused function". If the library were used by
+   LL|       |// another binary that never used this generic function, then it would be valid
+   LL|       |// to show the unused generic, with unknown substitution (`_`).
+   LL|       |//
+   LL|       |// The alternative is to exclude all generics from being included in the "unused
+   LL|       |// functions" list, which would then omit coverage results for
+   LL|       |// `unused_generic_function<T>()`, below.
+
+$DIR/uses_crate.rs:
+   LL|       |// This test was failing on Linux for a while due to #110393 somehow making
+   LL|       |// the unused functions not instrumented, but it seems to be fine now.
+   LL|       |
+   LL|       |// Validates coverage now works with optimizations
+   LL|       |// compile-flags: -C opt-level=3
+   LL|       |
+   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |
+   LL|       |// aux-build:used_crate.rs
+   LL|       |extern crate used_crate;
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    used_crate::used_function();
+   LL|      1|    let some_vec = vec![1, 2, 3, 4];
+   LL|      1|    used_crate::used_only_from_bin_crate_generic_function(&some_vec);
+   LL|      1|    used_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
+   LL|      1|    used_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
+   LL|      1|    used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function("interesting?");
+   LL|      1|}
+
diff --git a/tests/coverage/uses_crate.rs b/tests/coverage/uses_crate.rs
new file mode 100644
index 00000000000..ab203ad781d
--- /dev/null
+++ b/tests/coverage/uses_crate.rs
@@ -0,0 +1,19 @@
+// This test was failing on Linux for a while due to #110393 somehow making
+// the unused functions not instrumented, but it seems to be fine now.
+
+// Validates coverage now works with optimizations
+// compile-flags: -C opt-level=3
+
+#![allow(unused_assignments, unused_variables)]
+
+// aux-build:used_crate.rs
+extern crate used_crate;
+
+fn main() {
+    used_crate::used_function();
+    let some_vec = vec![1, 2, 3, 4];
+    used_crate::used_only_from_bin_crate_generic_function(&some_vec);
+    used_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
+    used_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
+    used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function("interesting?");
+}
diff --git a/tests/coverage/uses_inline_crate.coverage b/tests/coverage/uses_inline_crate.coverage
new file mode 100644
index 00000000000..cc0e01ffde1
--- /dev/null
+++ b/tests/coverage/uses_inline_crate.coverage
@@ -0,0 +1,159 @@
+$DIR/auxiliary/used_inline_crate.rs:
+   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |// Verify that coverage works with optimizations:
+   LL|       |// compile-flags: -C opt-level=3
+   LL|       |
+   LL|       |use std::fmt::Debug;
+   LL|       |
+   LL|      1|pub fn used_function() {
+   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      1|    // dependent conditions.
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|    let mut countdown = 0;
+   LL|      1|    if is_true {
+   LL|      1|        countdown = 10;
+   LL|      1|    }
+                   ^0
+   LL|      1|    use_this_lib_crate();
+   LL|      1|}
+   LL|       |
+   LL|       |#[inline(always)]
+   LL|      1|pub fn used_inline_function() {
+   LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+   LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+   LL|      1|    // dependent conditions.
+   LL|      1|    let is_true = std::env::args().len() == 1;
+   LL|      1|    let mut countdown = 0;
+   LL|      1|    if is_true {
+   LL|      1|        countdown = 10;
+   LL|      1|    }
+                   ^0
+   LL|      1|    use_this_lib_crate();
+   LL|      1|}
+   LL|       |
+   LL|       |#[inline(always)]
+   LL|      2|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+   LL|      2|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+   LL|      2|}
+  ------------------
+  | Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_>
+  ------------------
+  | used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
+  |   LL|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+  |   LL|      1|}
+  ------------------
+  | used_inline_crate::used_only_from_bin_crate_generic_function::<&str>:
+  |   LL|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
+  |   LL|      1|}
+  ------------------
+   LL|       |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
+   LL|       |
+   LL|       |#[inline(always)]
+   LL|      4|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+   LL|      4|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+   LL|      4|}
+  ------------------
+  | used_inline_crate::used_only_from_this_lib_crate_generic_function::<&str>:
+  |   LL|      2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      2|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+  |   LL|      2|}
+  ------------------
+  | used_inline_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+  |   LL|      2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      2|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
+  |   LL|      2|}
+  ------------------
+   LL|       |
+   LL|       |#[inline(always)]
+   LL|      3|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+   LL|      3|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+   LL|      3|}
+  ------------------
+  | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
+  |   LL|      2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      2|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   LL|      2|}
+  ------------------
+  | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+  |   LL|      1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      1|    println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   LL|      1|}
+  ------------------
+   LL|       |
+   LL|       |#[inline(always)]
+   LL|      3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+   LL|      3|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+   LL|      3|}
+  ------------------
+  | used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
+  |   LL|      1|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      1|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   LL|      1|}
+  ------------------
+  | used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>:
+  |   LL|      2|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
+  |   LL|      2|    println!("used_with_same_type_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
+  |   LL|      2|}
+  ------------------
+   LL|       |
+   LL|       |#[inline(always)]
+   LL|      0|pub fn unused_generic_function<T: Debug>(arg: T) {
+   LL|      0|    println!("unused_generic_function with {:?}", arg);
+   LL|      0|}
+   LL|       |
+   LL|       |#[inline(always)]
+   LL|      0|pub fn unused_function() {
+   LL|      0|    let is_true = std::env::args().len() == 1;
+   LL|      0|    let mut countdown = 2;
+   LL|      0|    if !is_true {
+   LL|      0|        countdown = 20;
+   LL|      0|    }
+   LL|      0|}
+   LL|       |
+   LL|       |#[inline(always)]
+   LL|       |#[allow(dead_code)]
+   LL|      0|fn unused_private_function() {
+   LL|      0|    let is_true = std::env::args().len() == 1;
+   LL|      0|    let mut countdown = 2;
+   LL|      0|    if !is_true {
+   LL|      0|        countdown = 20;
+   LL|      0|    }
+   LL|      0|}
+   LL|       |
+   LL|      2|fn use_this_lib_crate() {
+   LL|      2|    used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");
+   LL|      2|    used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
+   LL|      2|        "used from library used_crate.rs",
+   LL|      2|    );
+   LL|      2|    let some_vec = vec![5, 6, 7, 8];
+   LL|      2|    used_only_from_this_lib_crate_generic_function(some_vec);
+   LL|      2|    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
+   LL|      2|}
+
+$DIR/uses_inline_crate.rs:
+   LL|       |// This test was failing on Linux for a while due to #110393 somehow making
+   LL|       |// the unused functions not instrumented, but it seems to be fine now.
+   LL|       |
+   LL|       |// Validates coverage now works with optimizations
+   LL|       |// compile-flags: -C opt-level=3
+   LL|       |
+   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |
+   LL|       |// aux-build:used_inline_crate.rs
+   LL|       |extern crate used_inline_crate;
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    used_inline_crate::used_function();
+   LL|      1|    used_inline_crate::used_inline_function();
+   LL|      1|    let some_vec = vec![1, 2, 3, 4];
+   LL|      1|    used_inline_crate::used_only_from_bin_crate_generic_function(&some_vec);
+   LL|      1|    used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
+   LL|      1|    used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
+   LL|      1|    used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
+   LL|      1|        "interesting?",
+   LL|      1|    );
+   LL|      1|}
+
diff --git a/tests/coverage/uses_inline_crate.rs b/tests/coverage/uses_inline_crate.rs
new file mode 100644
index 00000000000..d7b4c3c057f
--- /dev/null
+++ b/tests/coverage/uses_inline_crate.rs
@@ -0,0 +1,22 @@
+// This test was failing on Linux for a while due to #110393 somehow making
+// the unused functions not instrumented, but it seems to be fine now.
+
+// Validates coverage now works with optimizations
+// compile-flags: -C opt-level=3
+
+#![allow(unused_assignments, unused_variables)]
+
+// aux-build:used_inline_crate.rs
+extern crate used_inline_crate;
+
+fn main() {
+    used_inline_crate::used_function();
+    used_inline_crate::used_inline_function();
+    let some_vec = vec![1, 2, 3, 4];
+    used_inline_crate::used_only_from_bin_crate_generic_function(&some_vec);
+    used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
+    used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
+    used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
+        "interesting?",
+    );
+}
diff --git a/tests/coverage/while.coverage b/tests/coverage/while.coverage
new file mode 100644
index 00000000000..c9d497651c9
--- /dev/null
+++ b/tests/coverage/while.coverage
@@ -0,0 +1,6 @@
+   LL|      1|fn main() {
+   LL|      1|    let num = 9;
+   LL|      1|    while num >= 10 {
+   LL|      0|    }
+   LL|      1|}
+
diff --git a/tests/coverage/while.rs b/tests/coverage/while.rs
new file mode 100644
index 00000000000..781b90b3566
--- /dev/null
+++ b/tests/coverage/while.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let num = 9;
+    while num >= 10 {
+    }
+}
diff --git a/tests/coverage/while_early_ret.coverage b/tests/coverage/while_early_ret.coverage
new file mode 100644
index 00000000000..49d39d36603
--- /dev/null
+++ b/tests/coverage/while_early_ret.coverage
@@ -0,0 +1,43 @@
+   LL|       |#![allow(unused_assignments)]
+   LL|       |// failure-status: 1
+   LL|       |
+   LL|      1|fn main() -> Result<(), u8> {
+   LL|      1|    let mut countdown = 10;
+   LL|       |    while
+   LL|      7|        countdown
+   LL|      7|            >
+   LL|      7|        0
+   LL|       |    {
+   LL|       |        if
+   LL|      7|            countdown
+   LL|      7|                <
+   LL|      7|            5
+   LL|       |        {
+   LL|       |            return
+   LL|       |                if
+   LL|      1|                    countdown
+   LL|      1|                        >
+   LL|      1|                    8
+   LL|       |                {
+   LL|      0|                    Ok(())
+   LL|       |                }
+   LL|       |                else
+   LL|       |                {
+   LL|      1|                    Err(1)
+   LL|       |                }
+   LL|       |                ;
+   LL|      6|        }
+   LL|      6|        countdown
+   LL|      6|            -=
+   LL|      6|        1
+   LL|       |        ;
+   LL|       |    }
+   LL|      0|    Ok(())
+   LL|      1|}
+   LL|       |
+   LL|       |// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and
+   LL|       |// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux
+   LL|       |// and MacOS. But on Windows (MSVC, at least), the call to `std::process::exit()` exits the program
+   LL|       |// without saving the InstrProf coverage counters. The use of `std::process:exit()` is not critical
+   LL|       |// to the coverage test for early returns, but this is a limitation that should be fixed.
+
diff --git a/tests/coverage/while_early_ret.rs b/tests/coverage/while_early_ret.rs
new file mode 100644
index 00000000000..b2f0eee2cc0
--- /dev/null
+++ b/tests/coverage/while_early_ret.rs
@@ -0,0 +1,42 @@
+#![allow(unused_assignments)]
+// failure-status: 1
+
+fn main() -> Result<(), u8> {
+    let mut countdown = 10;
+    while
+        countdown
+            >
+        0
+    {
+        if
+            countdown
+                <
+            5
+        {
+            return
+                if
+                    countdown
+                        >
+                    8
+                {
+                    Ok(())
+                }
+                else
+                {
+                    Err(1)
+                }
+                ;
+        }
+        countdown
+            -=
+        1
+        ;
+    }
+    Ok(())
+}
+
+// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and
+// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux
+// and MacOS. But on Windows (MSVC, at least), the call to `std::process::exit()` exits the program
+// without saving the InstrProf coverage counters. The use of `std::process:exit()` is not critical
+// to the coverage test for early returns, but this is a limitation that should be fixed.
diff --git a/tests/coverage/yield.coverage b/tests/coverage/yield.coverage
new file mode 100644
index 00000000000..d7e455f211e
--- /dev/null
+++ b/tests/coverage/yield.coverage
@@ -0,0 +1,38 @@
+   LL|       |#![feature(coroutines, coroutine_trait)]
+   LL|       |#![allow(unused_assignments)]
+   LL|       |
+   LL|       |use std::ops::{Coroutine, CoroutineState};
+   LL|       |use std::pin::Pin;
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let mut coroutine = || {
+   LL|      1|        yield 1;
+   LL|      1|        return "foo";
+   LL|      1|    };
+   LL|       |
+   LL|      1|    match Pin::new(&mut coroutine).resume(()) {
+   LL|      1|        CoroutineState::Yielded(1) => {}
+   LL|      0|        _ => panic!("unexpected value from resume"),
+   LL|       |    }
+   LL|      1|    match Pin::new(&mut coroutine).resume(()) {
+   LL|      1|        CoroutineState::Complete("foo") => {}
+   LL|      0|        _ => panic!("unexpected value from resume"),
+   LL|       |    }
+   LL|       |
+   LL|      1|    let mut coroutine = || {
+   LL|      1|        yield 1;
+   LL|      1|        yield 2;
+   LL|      0|        yield 3;
+   LL|      0|        return "foo";
+   LL|      0|    };
+   LL|       |
+   LL|      1|    match Pin::new(&mut coroutine).resume(()) {
+   LL|      1|        CoroutineState::Yielded(1) => {}
+   LL|      0|        _ => panic!("unexpected value from resume"),
+   LL|       |    }
+   LL|      1|    match Pin::new(&mut coroutine).resume(()) {
+   LL|      1|        CoroutineState::Yielded(2) => {}
+   LL|      0|        _ => panic!("unexpected value from resume"),
+   LL|       |    }
+   LL|      1|}
+
diff --git a/tests/coverage/yield.rs b/tests/coverage/yield.rs
new file mode 100644
index 00000000000..b7e2ba31b59
--- /dev/null
+++ b/tests/coverage/yield.rs
@@ -0,0 +1,37 @@
+#![feature(coroutines, coroutine_trait)]
+#![allow(unused_assignments)]
+
+use std::ops::{Coroutine, CoroutineState};
+use std::pin::Pin;
+
+fn main() {
+    let mut coroutine = || {
+        yield 1;
+        return "foo";
+    };
+
+    match Pin::new(&mut coroutine).resume(()) {
+        CoroutineState::Yielded(1) => {}
+        _ => panic!("unexpected value from resume"),
+    }
+    match Pin::new(&mut coroutine).resume(()) {
+        CoroutineState::Complete("foo") => {}
+        _ => panic!("unexpected value from resume"),
+    }
+
+    let mut coroutine = || {
+        yield 1;
+        yield 2;
+        yield 3;
+        return "foo";
+    };
+
+    match Pin::new(&mut coroutine).resume(()) {
+        CoroutineState::Yielded(1) => {}
+        _ => panic!("unexpected value from resume"),
+    }
+    match Pin::new(&mut coroutine).resume(()) {
+        CoroutineState::Yielded(2) => {}
+        _ => panic!("unexpected value from resume"),
+    }
+}