Skip to content

Comparison of Option<NonZeroU*> is not fully optimized #49892

Open
@kennytm

Description

@kennytm

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

Labels

A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-enhancementCategory: An issue proposing an enhancement or a PR with one.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-slowIssue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.WG-llvmWorking group: LLVM backend code generation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions