Closed
Description
Returning a newly created struct from a function causes an unnecessary memcpy even if the function is inlined:
use std::mem::uninitialized;
#[repr(C)]
pub struct SomeStruct(u64, u32, u16, u8, usize, u64, u64, u32, usize, u16, u32, usize, isize);
extern {
pub fn SomeExternFun(val: *mut SomeStruct);
}
#[inline(always)]
unsafe fn ret_val() -> SomeStruct {
let mut val: SomeStruct = uninitialized();
SomeExternFun(&mut val);
val
}
#[inline(always)]
unsafe fn by_ref(val: &mut SomeStruct) {
SomeExternFun(val);
}
pub unsafe fn call_ret_val() {
let val = ret_val();
println!("{}", val.0);
}
pub unsafe fn call_by_ref() {
let mut val: SomeStruct = uninitialized();
by_ref(&mut val);
println!("{}", val.0);
}
playground::call_ret_val: # @playground::call_ret_val
# %bb.0:
sub rsp, 184
lea rdi, [rsp + 16]
call qword ptr [rip + SomeExternFun@GOTPCREL]
movups xmm0, xmmword ptr [rsp + 80]
movaps xmmword ptr [rsp + 160], xmm0
movups xmm0, xmmword ptr [rsp + 16]
movups xmm1, xmmword ptr [rsp + 32]
movups xmm2, xmmword ptr [rsp + 48]
movups xmm3, xmmword ptr [rsp + 64]
movaps xmmword ptr [rsp + 144], xmm3
movaps xmmword ptr [rsp + 128], xmm2
movaps xmmword ptr [rsp + 112], xmm1
movaps xmmword ptr [rsp + 96], xmm0
lea rax, [rsp + 96]
mov qword ptr [rsp], rax
mov rax, qword ptr [rip + core::fmt::num::<impl core::fmt::Display for u64>::fmt@GOTPCREL]
mov qword ptr [rsp + 8], rax
lea rax, [rip + .Lanon.865785a9e3ffc8ff7f56f0b35003ddee.2]
mov qword ptr [rsp + 16], rax
mov qword ptr [rsp + 24], 2
lea rax, [rip + .Lanon.865785a9e3ffc8ff7f56f0b35003ddee.3]
mov qword ptr [rsp + 32], rax
mov qword ptr [rsp + 40], 1
mov rax, rsp
mov qword ptr [rsp + 48], rax
mov qword ptr [rsp + 56], 1
lea rdi, [rsp + 16]
call qword ptr [rip + std::io::stdio::_print@GOTPCREL]
add rsp, 184
ret
# -- End function
playground::call_by_ref: # @playground::call_by_ref
# %bb.0:
push rbx
sub rsp, 144
lea rbx, [rsp + 64]
mov rdi, rbx
call qword ptr [rip + SomeExternFun@GOTPCREL]
mov qword ptr [rsp], rbx
mov rax, qword ptr [rip + core::fmt::num::<impl core::fmt::Display for u64>::fmt@GOTPCREL]
mov qword ptr [rsp + 8], rax
lea rax, [rip + .Lanon.865785a9e3ffc8ff7f56f0b35003ddee.2]
mov qword ptr [rsp + 16], rax
mov qword ptr [rsp + 24], 2
lea rax, [rip + .Lanon.865785a9e3ffc8ff7f56f0b35003ddee.3]
mov qword ptr [rsp + 32], rax
mov qword ptr [rsp + 40], 1
mov rax, rsp
mov qword ptr [rsp + 48], rax
mov qword ptr [rsp + 56], 1
lea rdi, [rsp + 16]
call qword ptr [rip + std::io::stdio::_print@GOTPCREL]
add rsp, 144
pop rbx
ret
# -- End function
Metadata
Metadata
Assignees
Labels
Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: MIR optimizationsArea: MIR inliningFixed by the Named Return Value Opt. (NRVO)Issue: Problems and improvements with respect to performance of generated code.Relevant to the compiler team, which will review and decide on the PR/issue.