Skip to content

[x86] suboptimal codegen for isfinite IR #27538

@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