Skip to content

[x86] suboptimal codegen for isfinite IR #27538

Closed
@rotateright

Description

@rotateright
Bugzilla Link 27164
Version trunk
OS All
CC @hfinkel,@RKSimon

Extended Description

define i1 @is_finite(float %x) {
  %1 = tail call float @llvm.fabs.f32(float %x)
  %2 = fcmp one float %1, 0x7FF0000000000000 ; ordered and not equal
  ret i1 %2
}
declare float @llvm.fabs.f32(float)
$ ./llc -o - isfinite.ll

LCPI0_0:
	.long	2147483647              ## 0x7fffffff
	.long	2147483647              ## 0x7fffffff
	.long	2147483647              ## 0x7fffffff
	.long	2147483647              ## 0x7fffffff
	.section	__TEXT,__literal4,4byte_literals
	.p2align	2
LCPI0_1:
	.long	2139095040              ## float +Inf
	.section	__TEXT,__text,regular,pure_instructions
	.globl _is_finite
	.p2align	4, 0x90
_is_finite:                
	.cfi_startproc
## BB#0:
	andps	LCPI0_0(%rip), %xmm0
	ucomiss	LCPI0_1(%rip), %xmm0
	setne	%al
	retq

Note: 2139095040 = 0x7f800000 (check if the exponent is maxed)

I think this can be reduced to "andnps" with that constant and then ucomiss against zero (save a load).

Alternatively, we could bring the FP value into an int register and do the bitwise comparison there. If we have BMI, it could be something like:

movd %xmm0, %eax
andn (load bitmask), %eax, %eax
setne %al   ## if all exponent bits were not set, the value is finite

This only needs a scalar load and no explicit compare instruction is needed.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions