Skip to content

Stacked Borrows: Raw pointers inhibit optimizations? #263

Closed
@chorman0773

Description

@chorman0773

On #181 when discussing whether or not provenance destroying operations can be elided, I brought this code up

extern"C"{
pub fn does_something(param: *mut usize);
}
#[repr(C)]
struct Interesting{
    array: [usize;1], // prevents *pointer-interconvertibility* trick under lccc's model
    exclusive_access: *mut ()
};

pub fn do_interesting_things(ptr: &mut Interesting){
    let x = ptr.exclusive_access;
    does_something(&mut ptr.array[0]);
    ptr.exclusive_access =x;
}

For which the corresponding rust code would seem to rule out load-store elimination on ptr.exclusive_access

pub unsafe extern"C" fn does_something(ptr: *mut usize){
     let ptr = std::transmute(std::transmute<usize>(ptr)) as *mut Interesting;
     (*ptr).exclusive_access = ptr as *mut ();
}

While I was told that this code doesn't, replacing the first function with

pub fn do_interesting_things(ptr: &mut Interesting) {
    let x = ptr.exclusive_access;
    let y = &mut ptr.exclusive_access as *mut _;
    does_something(&mut ptr.array[0]);
    ptr.exclusive_access = x;
}

This seems odd to me. The fact that y is created by do_interesting_things inhibits optimizations accross the black-box does_something, even though does_something never recieves it, seems quite a bit off to me. In contrast, this is not permitted by C or C++, at all (if we replace the &mut in ptr with either Interesting* restrict in C, or an analogous compiler-specific extension in C++, to exclude aliasing access on entry to do_interesting_things).

In my head, pointers are pointers, reguardless of form (noting that references are pointers). It shouldn't be possible to use a pointer that was never recieved by a particular function to validate an operation in that function. This is particularily annoying because its clear through simple data-flow analysis that y never reaches does_something, yet it's mere existance is what invalidates the reasoning that ptr.exclusive_access is not modified.

If this is the case, this is a serious concern of mine, the pointer model in lccc would not permit this, and it is desired that this be the case, but it is intended to permit a superset of operations that Stacked Borrows does (A superset, because some operations that are permitted by C and C++ aren't by stacked borrows presently, one such operation is actually discussed in #256).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions