float __hsail_fract_f32(float a) {
  int exp;
  if (isinf(a))
    return signbit(a) == 0 ? 0.0f : -0.0f;
  if (isnan(a) || a == 0.0f)
    return a;
  else
    return fminf(a - floorf(a), 0x1.fffffep-1f);
}


x86 assembly (clang, -O0):
<__hsail_fract_f32>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movss  %xmm0,-0x8(%rbp)
movss  -0x8(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   1060 <isinf@plt>
cmp    $0x0,%eax
je     11ad <__hsail_fract_f32+0x6d>
movss  -0x8(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   1050 <signbit@plt>
xorps  %xmm0,%xmm0
movss  0xe83(%rip),%xmm1
movss  %xmm1,-0x14(%rbp)
cmp    $0x0,%eax
movss  %xmm0,-0x10(%rbp)
je     119e <__hsail_fract_f32+0x5e>
movss  -0x14(%rbp),%xmm0
movss  %xmm0,-0x10(%rbp)
movss  -0x10(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    121d <__hsail_fract_f32+0xdd>
movss  -0x8(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   1040 <isnan@plt>
cmp    $0x0,%eax
jne    11dd <__hsail_fract_f32+0x9d>
movss  -0x8(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jne    11ec <__hsail_fract_f32+0xac>
jp     11ec <__hsail_fract_f32+0xac>
movss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    121d <__hsail_fract_f32+0xdd>
movss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x18(%rbp)
movss  -0x8(%rbp),%xmm0
call   1030 <floorf@plt>
movaps %xmm0,%xmm1
movss  -0x18(%rbp),%xmm0
subss  %xmm1,%xmm0
movss  0xdec(%rip),%xmm1
minss  %xmm1,%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<__hsail_fract_f32>:
sub    $0x18,%rsp
movss  %xmm0,0xc(%rsp)
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,0x10(%rsp)
mov    $0x1,%al
call   1060 <isinf@plt>
test   %eax,%eax
je     1180 <__hsail_fract_f32+0x40>
movsd  0x10(%rsp),%xmm0
mov    $0x1,%al
call   1050 <signbit@plt>
xorps  %xmm0,%xmm0
test   %eax,%eax
je     11be <__hsail_fract_f32+0x7e>
movss  0xe85(%rip),%xmm0
add    $0x18,%rsp
ret
movsd  0x10(%rsp),%xmm0
mov    $0x1,%al
call   1040 <isnan@plt>
xorps  %xmm0,%xmm0
movss  0xc(%rsp),%xmm1
ucomiss %xmm0,%xmm1
movaps %xmm1,%xmm0
jne    11a0 <__hsail_fract_f32+0x60>
jnp    11be <__hsail_fract_f32+0x7e>
test   %eax,%eax
jne    11be <__hsail_fract_f32+0x7e>
call   1030 <floorf@plt>
movss  0xc(%rsp),%xmm1
subss  %xmm0,%xmm1
minss  0xe49(%rip),%xmm1
movaps %xmm1,%xmm0
add    $0x18,%rsp
ret

LLVM IR (-O0):
define float @__hsail_fract_f32(float %0) {
%2 = alloca float
%3 = alloca float
%4 = alloca i32
store float %0, float* %3
%5 = load float, float* %3
%6 = fpext float %5 to double
%7 = call i32 (double, ...) bitcast (i32 (...)* @isinf to i32 (double, ...)*)(double %6)
%8 = icmp ne i32 %7, 0
br i1 %8, label %9, label %16
9: ; preds = %1
%10 = load float, float* %3
%11 = fpext float %10 to double
%12 = call i32 (double, ...) bitcast (i32 (...)* @signbit to i32 (double, ...)*)(double %11)
%13 = icmp eq i32 %12, 0
%14 = zext i1 %13 to i64
%15 = select i1 %13, float 0.000000e+00, float -0.000000e+00
store float %15, float* %2
br label %32
16: ; preds = %1
%17 = load float, float* %3
%18 = fpext float %17 to double
%19 = call i32 (double, ...) bitcast (i32 (...)* @isnan to i32 (double, ...)*)(double %18)
%20 = icmp ne i32 %19, 0
br i1 %20, label %24, label %21
21: ; preds = %16
%22 = load float, float* %3
%23 = fcmp oeq float %22, 0.000000e+00
br i1 %23, label %24, label %26
24: ; preds = %21, %16
%25 = load float, float* %3
store float %25, float* %2
br label %32
26: ; preds = %21
%27 = load float, float* %3
%28 = load float, float* %3
%29 = call float @llvm.floor.f32(float %28)
%30 = fsub float %27, %29
%31 = call float @llvm.minnum.f32(float %30, float 0x3FEFFFFFE0000000)
store float %31, float* %2
br label %32
32: ; preds = %26, %24, %9
%33 = load float, float* %2
ret float %33
}

LLVM IR (-O2):
define float @__hsail_fract_f32(float %0) {
%2 = fpext float %0 to double
%3 = tail call i32 (double, ...) bitcast (i32 (...)* @isinf to i32 (double, ...)*)(double %2)
%4 = icmp eq i32 %3, 0
br i1 %4, label %9, label %5
5: ; preds = %1
%6 = tail call i32 (double, ...) bitcast (i32 (...)* @signbit to i32 (double, ...)*)(double %2)
%7 = icmp eq i32 %6, 0
%8 = select i1 %7, float 0.000000e+00, float -0.000000e+00
br label %18
9: ; preds = %1
%10 = tail call i32 (double, ...) bitcast (i32 (...)* @isnan to i32 (double, ...)*)(double %2)
%11 = icmp ne i32 %10, 0
%12 = fcmp oeq float %0, 0.000000e+00
%13 = or i1 %12, %11
br i1 %13, label %18, label %14
14: ; preds = %9
%15 = tail call float @llvm.floor.f32(float %0)
%16 = fsub float %0, %15
%17 = tail call float @llvm.minnum.f32(float %16, float 0x3FEFFFFFE0000000)
br label %18
18: ; preds = %9, %14, %5
%19 = phi float [ %8, %5 ], [ %17, %14 ], [ %0, %9 ]
ret float %19
}