Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FileCheck annotations to mir-opt/copy-prop #135099

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion tests/mir-opt/copy-prop/branch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//! Tests that we bail out when there are multiple assignments to the same local.
//@ test-mir-pass: CopyProp
Expand All @@ -12,6 +11,14 @@ fn cond() -> bool {

// EMIT_MIR branch.foo.CopyProp.diff
fn foo() -> i32 {
// CHECK-LABEL: fn foo(
// CHECK: debug x => [[x:_.*]];
// CHECK: debug y => [[y:_.*]];
// CHECK: bb3: {
// CHECK: [[y]] = copy [[x]];
// CHECK: bb5: {
// CHECK: [[y]] = copy [[x]];
// CHECK: _0 = copy [[y]];
let x = val();

let y = if cond() {
Expand Down
13 changes: 12 additions & 1 deletion tests/mir-opt/copy-prop/calls.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// skip-filecheck
// Check that CopyProp does propagate return values of call terminators.
//@ test-mir-pass: CopyProp
//@ needs-unwind
Expand All @@ -13,13 +12,25 @@ fn dummy(x: u8) -> u8 {

// EMIT_MIR calls.nrvo.CopyProp.diff
fn nrvo() -> u8 {
// CHECK-LABEL: fn nrvo(
// CHECK: debug y => _0;
// CHECK-NOT: StorageLive(_1);
// CHECK-NOT: _1 = dummy(const 5_u8)
// CHECK: _0 = dummy(const 5_u8)
// CHECK-NOT: _0 = copy _1;
// CHECK-NOT: StorageDead(_1);
let y = dummy(5); // this should get NRVO
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind adding a CHECK: _0 = dummy(const 5_u8)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 1aeeebc

y
}

// EMIT_MIR calls.multiple_edges.CopyProp.diff
#[custom_mir(dialect = "runtime", phase = "initial")]
fn multiple_edges(t: bool) -> u8 {
// CHECK-LABEL: fn multiple_edges(
// CHECK: bb1: {
// CHECK: _2 = dummy(const 13_u8)
// CHECK: bb2: {
// CHECK: _0 = copy _2;
mir! {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind adding a CHECK: _2 = dummy(const 13_u8)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 1aeeebc

let x: u8;
{
Expand Down
24 changes: 22 additions & 2 deletions tests/mir-opt/copy-prop/copy_propagation_arg.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// Check that CopyProp does not propagate an assignment to a function argument
// (doing so can break usages of the original argument value)
Expand All @@ -9,25 +8,46 @@ fn dummy(x: u8) -> u8 {

// EMIT_MIR copy_propagation_arg.foo.CopyProp.diff
fn foo(mut x: u8) {
// CHECK-LABEL: fn foo(
// CHECK: debug x => [[x:_.*]];
// CHECK: [[three:_.*]] = copy [[x]];
// CHECK: [[two:_.*]] = dummy(move [[three]])
// CHECK: [[x]] = move [[two]];
// calling `dummy` to make a use of `x` that copyprop cannot eliminate
x = dummy(x); // this will assign a local to `x`
}

// EMIT_MIR copy_propagation_arg.bar.CopyProp.diff
fn bar(mut x: u8) {
// CHECK-LABEL: fn bar(
// CHECK: debug x => [[x:_.*]];
// CHECK: [[three:_.*]] = copy [[x]];
// CHECK: dummy(move [[three]])
// CHECK: [[x]] = const 5_u8;
dummy(x);
x = 5;
}

// EMIT_MIR copy_propagation_arg.baz.CopyProp.diff
fn baz(mut x: i32) -> i32 {
// self-assignment to a function argument should be eliminated
// CHECK-LABEL: fn baz(
// CHECK: debug x => [[x:_.*]];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we don't need this function for CopyProp.
I guess this test file originally from dest-prop, and in dest-prop the self-assignment is eliminated. But in copy-prop, it is not eliminated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. Do you mind fixing the comment and adding a CHECK: [[x]] = copy [[x]];?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and adding a CHECK: [[x]] = copy [[x]];?

There is no self-copy instruction in the mir file, but it has _2 = copy _1 and _0 = copy _1 (I already added).
Do you mean that I should add CHECK: _2 = copy [[x]];?

Copy link
Contributor Author

@Shunpoco Shunpoco Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I modified it in 7a64137. Please check if the change matches with your thought 🙏

// CHECK: [[x2:_.*]] = copy [[x]];
// CHECK: [[x]] = move [[x2]];
// CHECK: _0 = copy [[x]];
// In the original case for DestProp, the self-assignment to a function argument is eliminated,
// but in CopyProp it is not eliminated.
x = x;
x
}

// EMIT_MIR copy_propagation_arg.arg_src.CopyProp.diff
fn arg_src(mut x: i32) -> i32 {
// CHECK-LABEL: fn arg_src(
// CHECK: debug x => [[x:_.*]];
// CHECK: debug y => [[y:_.*]];
// CHECK: [[y]] = copy [[x]];
// CHECK: [[x]] = const 123_i32;
let y = x;
x = 123; // Don't propagate this assignment to `y`
y
Expand Down
8 changes: 7 additions & 1 deletion tests/mir-opt/copy-prop/custom_move_arg.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ test-mir-pass: CopyProp

Expand All @@ -12,6 +11,13 @@ struct NotCopy(bool);
// EMIT_MIR custom_move_arg.f.CopyProp.diff
#[custom_mir(dialect = "runtime")]
fn f(_1: NotCopy) {
// CHECK-LABEL: fn f(
// CHECK: bb0: {
// CHECK-NOT: _2 = copy _1;
// CHECK: _0 = opaque::<NotCopy>(copy _1)
// CHECK: bb1: {
// CHECK-NOT: _3 = move _2;
// CHECK: _0 = opaque::<NotCopy>(copy _1)
mir! {
{
let _2 = _1;
Expand Down
13 changes: 12 additions & 1 deletion tests/mir-opt/copy-prop/cycle.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//! Tests that cyclic assignments don't hang CopyProp, and result in reasonable code.
//@ test-mir-pass: CopyProp
Expand All @@ -8,6 +7,18 @@ fn val() -> i32 {

// EMIT_MIR cycle.main.CopyProp.diff
fn main() {
// CHECK-LABEL: fn main(
// CHECK: debug x => [[x:_.*]];
// CHECK: debug y => [[y:_.*]];
// CHECK: debug z => [[y]];
// CHECK-NOT: StorageLive([[y]]);
// CHECK: [[y]] = copy [[x]];
// CHECK-NOT: StorageLive(_3);
// CHECK-NOT: _3 = copy [[y]];
// CHECK-NOT: StorageLive(_4);
// CHECK-NOT: _4 = copy _3;
// CHECK-NOT: _1 = move _4;
// CHECK: [[x]] = copy [[y]];
let mut x = val();
let y = x;
let z = y;
Expand Down
9 changes: 8 additions & 1 deletion tests/mir-opt/copy-prop/dead_stores_79191.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ test-mir-pass: CopyProp

Expand All @@ -8,6 +7,14 @@ fn id<T>(x: T) -> T {

// EMIT_MIR dead_stores_79191.f.CopyProp.after.mir
fn f(mut a: usize) -> usize {
// CHECK-LABEL: fn f(
// CHECK: debug a => [[a:_.*]];
// CHECK: debug b => [[b:_.*]];
// CHECK: [[b]] = copy [[a]];
// CHECK: [[a]] = const 5_usize;
// CHECK: [[a]] = copy [[b]];
// CHECK: [[c:_.*]] = copy [[a]]
// CHECK: id::<usize>(move [[c]])
let b = a;
a = 5;
a = b;
Expand Down
11 changes: 9 additions & 2 deletions tests/mir-opt/copy-prop/dead_stores_better.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// This is a copy of the `dead_stores_79191` test, except that we turn on DSE. This demonstrates
// that that pass enables this one to do more optimizations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The compile-flags are not up-to-date. They should specify DeadStoreElimination-initial

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified in 0d6fa54

//@ test-mir-pass: CopyProp
//@ compile-flags: -Zmir-enable-passes=+DeadStoreElimination
//@ compile-flags: -Zmir-enable-passes=+DeadStoreElimination-initial

fn id<T>(x: T) -> T {
x
}

// EMIT_MIR dead_stores_better.f.CopyProp.after.mir
pub fn f(mut a: usize) -> usize {
// CHECK-LABEL: fn f(
// CHECK: debug a => [[a:_.*]];
// CHECK: debug b => [[b:_.*]];
// CHECK: [[b]] = copy [[a]];
// CHECK: [[a]] = const 5_usize;
// CHECK: [[a]] = copy [[b]];
// CHECK: [[c:_.*]] = copy [[a]]
// CHECK: id::<usize>(move [[c]])
let b = a;
a = 5;
a = b;
Expand Down
5 changes: 4 additions & 1 deletion tests/mir-opt/copy-prop/issue_107511.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ test-mir-pass: CopyProp

// EMIT_MIR issue_107511.main.CopyProp.diff
fn main() {
// CHECK-LABEL: fn main(
// CHECK: debug i => [[i:_.*]];
// CHECK-NOT: StorageLive([[i]]);
// CHECK-NOT: StorageDead([[i]]);
let mut sum = 0;
let a = [0, 10, 20, 30];

Expand Down
5 changes: 4 additions & 1 deletion tests/mir-opt/copy-prop/move_arg.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// Test that we do not move multiple times from the same local.
//@ test-mir-pass: CopyProp

// EMIT_MIR move_arg.f.CopyProp.diff
pub fn f<T: Copy>(a: T) {
// CHECK-LABEL: fn f(
// CHECK: debug a => [[a:_.*]];
// CHECK: debug b => [[a]];
// CHECK: g::<T>(copy [[a]], copy [[a]])
let b = a;
g(a, b);
}
Expand Down
10 changes: 9 additions & 1 deletion tests/mir-opt/copy-prop/move_projection.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ test-mir-pass: CopyProp

Expand All @@ -15,6 +14,15 @@ struct Foo(u8);

#[custom_mir(dialect = "runtime")]
fn f(a: Foo) -> bool {
// CHECK-LABEL: fn f(
// CHECK-SAME: [[a:_.*]]: Foo)
// CHECK: bb0: {
// CHECK-NOT: _2 = copy [[a]];
// CHECK-NOT: _3 = move (_2.0: u8);
// CHECK: [[c:_.*]] = copy ([[a]].0: u8);
// CHECK: _0 = opaque::<Foo>(copy [[a]])
// CHECK: bb1: {
// CHECK: _0 = opaque::<u8>(move [[c]])
mir! {
{
let b = a;
Expand Down
5 changes: 4 additions & 1 deletion tests/mir-opt/copy-prop/mutate_through_pointer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// skip-filecheck
//@ test-mir-pass: CopyProp
//
// This attempts to mutate `a` via a pointer derived from `addr_of!(a)`. That is UB
Expand All @@ -18,6 +17,10 @@ use core::intrinsics::mir::*;

#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
fn f(c: bool) -> bool {
// CHECK-LABEL: fn f(
// CHECK: _2 = copy _1;
// CHECK-NOT: _3 = &raw const _1;
// CHECK: _3 = &raw const _2;
mir! {
{
let a = c;
Expand Down
6 changes: 5 additions & 1 deletion tests/mir-opt/copy-prop/non_dominate.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// skip-filecheck
//@ test-mir-pass: CopyProp

#![feature(custom_mir, core_intrinsics)]
Expand All @@ -8,6 +7,11 @@ use core::intrinsics::mir::*;

#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
fn f(c: bool) -> bool {
// CHECK-LABEL: fn f(
// CHECK: bb2: {
// CHECK: _2 = copy _3;
// CHECK: bb3: {
// CHECK: _0 = copy _2;
mir! {
let a: bool;
let b: bool;
Expand Down
4 changes: 3 additions & 1 deletion tests/mir-opt/copy-prop/partial_init.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// skip-filecheck
//@ test-mir-pass: CopyProp
// Verify that we do not ICE on partial initializations.

Expand All @@ -9,6 +8,9 @@ use core::intrinsics::mir::*;
// EMIT_MIR partial_init.main.CopyProp.diff
#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
pub fn main() {
// CHECK-LABEL: fn main(
// CHECK: let mut [[x:_.*]]: (isize,);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this FileCheck annotations, but actually this test case doesn't need them since it checks if rustc compiles the function with CopyProp.
I'd like to confirm that we should keep skip-filecheck, or go forward with those annotations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The annotations you put are enough.

// CHECK: ([[x]].0: isize) = const 1_isize;
mir! (
let x: (isize, );
{
Expand Down
13 changes: 12 additions & 1 deletion tests/mir-opt/copy-prop/reborrow.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// Check that CopyProp considers reborrows as not mutating the pointer.
//@ test-mir-pass: CopyProp
Expand All @@ -8,6 +7,9 @@ fn opaque(_: impl Sized) {}

// EMIT_MIR reborrow.remut.CopyProp.diff
fn remut(mut x: u8) {
// CHECK-LABEL: fn remut(
// CHECK: debug a => [[a:_.*]];
// CHECK: debug c => [[a]];
let a = &mut x;
let b = &mut *a; //< this cannot mutate a.
let c = a; //< so `c` and `a` can be merged.
Expand All @@ -16,6 +18,9 @@ fn remut(mut x: u8) {

// EMIT_MIR reborrow.reraw.CopyProp.diff
fn reraw(mut x: u8) {
// CHECK-LABEL: fn reraw(
// CHECK: debug a => [[a:_.*]];
// CHECK: debug c => [[a]];
let a = &mut x;
let b = &raw mut *a; //< this cannot mutate a.
let c = a; //< so `c` and `a` can be merged.
Expand All @@ -24,6 +29,9 @@ fn reraw(mut x: u8) {

// EMIT_MIR reborrow.miraw.CopyProp.diff
fn miraw(mut x: u8) {
// CHECK-LABEL: fn miraw(
// CHECK: debug a => [[a:_.*]];
// CHECK: debug c => [[a]];
let a = &raw mut x;
let b = unsafe { &raw mut *a }; //< this cannot mutate a.
let c = a; //< so `c` and `a` can be merged.
Expand All @@ -32,6 +40,9 @@ fn miraw(mut x: u8) {

// EMIT_MIR reborrow.demiraw.CopyProp.diff
fn demiraw(mut x: u8) {
// CHECK-LABEL: fn demiraw(
// CHECK: debug a => [[a:_.*]];
// CHECK: debug c => [[a]];
let a = &raw mut x;
let b = unsafe { &mut *a }; //< this cannot mutate a.
let c = a; //< so `c` and `a` can be merged.
Expand Down
Loading