Open
Description
#[repr(C)]
pub struct UrlpPattern(pub *mut c_void);
#[unsafe(no_mangle)]
pub unsafe extern "C" fn square(num: UrlpPattern) -> *mut c_void {
num.0
}
generates
define noundef ptr @square(ptr noalias nocapture noundef readonly byval([4 x i8]) align 4 dereferenceable(4) %num) unnamed_addr {
start:
%_0 = load ptr, ptr %num, align 4
ret ptr %_0
}
but
struct wrapper {
void *p;
};
void *square(wrapper p) {
return p.p;
}
generates
define dso_local i8* @square(wrapper)(i8* readnone returned %p.0) local_unnamed_addr {
entry:
ret i8* %p.0
}
It seems like this mostly works because it compiles to the same thing x86-32 code:
square(wrapper): # @square(wrapper)
mov eax, dword ptr [esp + 4]
ret
However, if the rust code is inlined into C++ with LTO we end up with an extra dereference.
We ran into this in Firefox here: https://bugzilla.mozilla.org/show_bug.cgi?id=1973805
rustc --version --verbose
:
rustc 1.88.0 (6b00bc388 2025-06-23)
Metadata
Metadata
Assignees
Labels
Area: Concerning the application binary interface (ABI)Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Link-time optimization (LTO)Category: This is a bug.Target: x86 processors, 32 bit (like i686-*) (also known as IA-32, i386, i586, i686)This issue may need triage. Remove it if it has been sufficiently triaged.