Closed
Description
Consider following functions
pub fn unwrap_combinators(a: Option<i32>, b: i32) -> bool {
a.map(|t| t >= b)
.unwrap_or(false)
}
pub fn unwrap_manual(a: Option<i32>, b: i32) -> bool {
match a {
Some(t) => t >= b,
None => false
}
}
The first pattern is what we often write and the second one is the most efficient manually unrolled version. Surprisingly rustc fails to optimize the former one into the latter as you can see in godbolt listing:
example::unwrap_combinators:
xor eax, eax
cmp edx, esi
setle al
test edi, edi
mov ecx, 2
cmovne ecx, eax
cmp cl, 2
setne al
and al, cl
ret
example::unwrap_manual:
test edi, edi
setne cl
cmp esi, edx
setge al
and al, cl
ret
P.S. Yes, I'm aware of map_or
Metadata
Metadata
Assignees
Labels
Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Memory layout of typesArea: MIR optimizationsArea: MIR inliningCategory: This is a bug.Call 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.