The problem I see with that proposal is that it introduces a new type of pointer, the immutable pointer. That seems like equal to a const pointer, but it's not. With a const pointer the callee can not mutate the pointee. But it can still be mutated from the outside. That means that any time you handed out a mutable pointer to something you have to make a copy for handing out an immutable pointer to it. An ABI like this would probably be much more complex to implement for a small gain.
You would end up with hardly predictable behaviour wether the struct gets copied or not. C# structs suffer a lot from this, because methods are mutating by default (https://codeblog.jonskeet.uk/2014/07/16/micro-optimization-t...). The biggest problem is simply that this is not explicit.
Also there is a case where a calling convention like this can make things worse, as you will have to make two copies:
void fn1(A*);
void fn2(A a) {
// Have to make copy here because mutating
fn1(&a);
}
void fn3()
{
A a;
fn1(&a);
// Have to make copy here because reference to a might have escaped.
fn2(a);
}