Files
rust/tests/mir-opt/dead-store-elimination/call_arg_copy.rs
T
Amanieu d'Antras b15544d52f Handle index projections in call destinations in DSE
Since call destinations are evaluated after call arguments, we can't
turn copy arguments into moves if the same local is later used as an
index projection in the call destination.
2026-04-23 11:17:22 +01:00

71 lines
1.7 KiB
Rust

// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ test-mir-pass: DeadStoreElimination-final
//@ compile-flags: -Zmir-enable-passes=+CopyProp
#![feature(core_intrinsics)]
#![feature(custom_mir)]
#![allow(internal_features)]
use std::intrinsics::mir::*;
#[inline(never)]
fn use_both(_: i32, _: i32) {}
// EMIT_MIR call_arg_copy.move_simple.DeadStoreElimination-final.diff
fn move_simple(x: i32) {
// CHECK-LABEL: fn move_simple(
// CHECK: = use_both(copy _1, move _1)
use_both(x, x);
}
#[repr(packed)]
struct Packed {
x: u8,
y: i32,
}
// EMIT_MIR call_arg_copy.move_packed.DeadStoreElimination-final.diff
#[custom_mir(dialect = "analysis")]
fn move_packed(packed: Packed) {
// CHECK-LABEL: fn move_packed(
// CHECK: = use_both(const 0_i32, copy (_1.1: i32))
mir! {
{
// We have a packed struct, verify that the copy is not turned into a move.
Call(RET = use_both(0, packed.y), ReturnTo(ret), UnwindContinue())
}
ret = {
Return()
}
}
}
#[inline(never)]
fn passthrough_usize(a: usize) -> usize {
a
}
// EMIT_MIR call_arg_copy.move_index.DeadStoreElimination-final.diff
#[custom_mir(dialect = "analysis")]
fn move_index(a: [usize; 10], b: usize) {
// CHECK-LABEL: fn move_index(
// CHECK: = passthrough_usize(copy _2)
mir! {
{
// The index is used again after the operand is evaluated to
// evaluate the destionation place, so the argument cannot be turned
// into a move.
Call(a[b] = passthrough_usize(b), ReturnTo(ret), UnwindContinue())
}
ret = {
Return()
}
}
}
fn main() {
move_simple(1);
move_packed(Packed { x: 0, y: 1 });
move_index([0; _], 1);
}