Skip to content

Redundant branches with ctlz and cttz #47467

Closed
@Diggsey

Description

@Diggsey
Bugzilla Link 48123
Version trunk
OS Windows NT
CC @topperc,@RKSimon,@phoebewang,@rotateright

Extended Description

Rust code:

pub fn can_represent_as_f64(x: u64) -> bool {
    x.leading_zeros() + x.trailing_zeros() >= 11
}

LLVM IR:

define zeroext i1 @_ZN10playground20can_represent_as_f6417h8c9d47bab619cb5fE(i64 %x) {
start:
  %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
  %1 = trunc i64 %0 to i32
  %2 = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
  %3 = trunc i64 %2 to i32
  %_2 = add nuw nsw i32 %1, %3
  %4 = icmp ugt i32 %_2, 10
  ret i1 %4
}

Assembly:

playground::can_represent_as_f64:
	mov	eax, 64
	mov	ecx, 64
	test	rdi, rdi    ; Initial test for zero and branch
	je	.LBB0_2
	bsr	rcx, rdi
	xor	rcx, 63

.LBB0_2:
	test	rdi, rdi    ; Second test for zero and branch
	je	.LBB0_4
	bsf	rax, rdi

.LBB0_4:
	add	ecx, eax
	cmp	ecx, 10
	seta	al
	ret

Instead of performing the comparison twice, the code should immediately branch to LBB0_4.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions