DeadStoreElimination wants to turn copy arguments into move arguments, but that transformation is not always valid. The pass does not account for this case:
but we also need a callee with codegen that clearly relies on the return place and argument not overlapping. This works, but uses custom_mir for both:
#![feature(custom_mir, core_intrinsics)]
#![allow(internal_features)]
use std::intrinsics::mir::*;
#[repr(C)]
struct Big {
a: u64,
b: u64,
c: u64,
d: u64,
e: u64,
}
#[inline(never)]
#[custom_mir(dialect = "runtime")]
fn f(x: Big) -> Big {
mir! {
type RET = Big;
{
RET.a = 1;
RET.b = x.a;
RET.c = 0;
RET.d = 0;
RET.e = 0;
Return()
}
}
}
#[inline(never)]
#[custom_mir(dialect = "runtime")]
fn caller(x: Big) -> Big {
mir! {
{
Call(x = f(x), ReturnTo(bb1), UnwindUnreachable())
}
bb1 = {
RET = x;
Return()
}
}
}
fn main() {
let x = Big { a: 42, b: 0, c: 0, d: 0, e: 0 };
let y = caller(x);
assert_eq!(y.b, 42);
}
DeadStoreElimination wants to turn copy arguments into move arguments, but that transformation is not always valid. The pass does not account for this case:
but we also need a callee with codegen that clearly relies on the return place and argument not overlapping. This works, but uses custom_mir for both: