Skip to content

DeadStoreElimination can create calls where return and arguments overlap #162997

Description

@saethlin

DeadStoreElimination wants to turn copy arguments into move arguments, but that transformation is not always valid. The pass does not account for this case:

_1 = f(copy _1);

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);
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-mir-optArea: MIR optimizationsC-bugCategory: This is a bug.I-miscompileIssue: Correct Rust code lowers to incorrect machine codeI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions