Open
Description
Compare:
#![feature(nonzero)]
use std::num::NonZeroU32;
pub fn f(a: Option<NonZeroU32>, b: Option<NonZeroU32>) -> bool {
a < b
}
pub fn g(a: u32, b: u32) -> bool {
a < b
}
The functions f
and g
have equivalent effect, and should compile to the same code. However, the translated f
is much more complex, involving needless comparison of the discriminant.
LLVM IR and ASM (in release mode)
; playground::f
; Function Attrs: norecurse nounwind readnone uwtable
define zeroext i1 @_ZN10playground1f17hd628eff49d2ff60dE(i32, i32) unnamed_addr #0 {
start:
%2 = icmp ne i32 %0, 0
%3 = icmp ne i32 %1, 0
%4 = xor i1 %2, %3
br i1 %4, label %bb7.i, label %bb6.i
bb6.i: ; preds = %start
%5 = icmp ult i32 %0, %1
%spec.select = and i1 %2, %5
ret i1 %spec.select
bb7.i: ; preds = %start
%6 = xor i1 %2, true
%7 = and i1 %3, %6
ret i1 %7
}
; playground::g
; Function Attrs: norecurse nounwind readnone uwtable
define zeroext i1 @_ZN10playground1g17hea1c394facd055aeE(i32 %a, i32 %b) unnamed_addr #0 {
start:
%0 = icmp ult i32 %a, %b
ret i1 %0
}
playground::f:
test edi, edi
setne al
test esi, esi
setne cl
xor cl, al
je .LBB0_1
test esi, esi
setne cl
test edi, edi
sete al
and al, cl
ret
.LBB0_1:
test edi, edi
setne cl
cmp edi, esi
setb al
and al, cl
ret
playground::g:
cmp edi, esi
setb al
ret
Note that specializing PartialOrd
etc for Option<NonZero*>
is not a valid solution, since custom wrapper types of NonZero* will still have the same problem.
#[derive(PartialOrd, PartialEq)]
pub struct S(NonZeroU32);
pub fn f(a: Option<S>, b: Option<S>) -> bool {
a < b
}
cc #49137.
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 suchIssue: Problems and improvements with respect to performance of generated code.Relevant to the compiler team, which will review and decide on the PR/issue.Working group: LLVM backend code generation