Closed
Description
For the following code:
use std::mem;
fn foo<T>(a: &mut T, b: T) -> bool {
let b = Some(mem::replace(a, b));
let ret = b.is_some();
mem::forget(b);
return ret
}
pub fn foo_u32(a: &mut u32, b: u32) -> bool {
foo(a, b)
}
pub fn foo_box(a: &mut Box<u32>, b: Box<u32>) -> bool {
foo(a, b)
}
This compiles down to the IR (optimized)
; Function Attrs: norecurse uwtable
define zeroext i1 @_ZN3foo7foo_u3217h93ddaaeb1c2cc2b2E(i32* nocapture dereferenceable(4), i32) unnamed_addr #0 {
entry-block:
store i32 %1, i32* %0, align 4
ret i1 true
}
; Function Attrs: norecurse uwtable
define zeroext i1 @_ZN3foo7foo_box17hd05578023690d1faE(i32** nocapture dereferenceable(8), i32* noalias dereferenceable(4)) unnamed_addr #0 {
entry-block:
%2 = ptrtoint i32* %1 to i64
%3 = bitcast i32** %0 to i64*
%4 = bitcast i32** %0 to i8**
%5 = load i8*, i8** %4, align 8, !noalias !0
store i64 %2, i64* %3, align 8, !noalias !0
%not.switchtmp.i.i = icmp ne i8* %5, null
ret i1 %not.switchtmp.i.i
}
attributes #0 = { norecurse uwtable }
attributes #1 = { nounwind }
It seems odd that the Box
case is not as optimized as the u32
case? This seems due to the null-pointer optimization of the Option<Box>
itself. I wonder if there's more metadata we can attach to tell LLVM the loads aren't null?
Metadata
Metadata
Assignees
Labels
Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Category: An issue proposing an enhancement or a PR with one.Category: An issue highlighting optimization opportunities or PRs implementing suchCall for participation: An issue has been fixed and does not reproduce, but no test has been added.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.