float modff(float fx, float *iptr) {
  union {
    unsigned u32;
    float f32;
  } x;
  unsigned hx, s;
  x.f32 = fx;
  hx = x.u32 & ~0x80000000;
  if (hx >= 0x4b000000) {
    *iptr = x.f32;
    if (hx <= 0x7f800000)
      x.u32 &= 0x80000000;
    return x.f32;
  }
  if (hx < 0x3f800000) {
    float ret = x.f32;
    x.u32 &= 0x80000000;
    *iptr = x.f32;
    return ret;
  }
  s = x.u32 & 0x80000000;
  fx = x.f32;
  x.u32 &= ~((1 << (0x96 - (hx >> 23))) - 1);
  *iptr = x.f32;
  x.f32 = fx - *iptr;
  x.u32 = (x.u32 & ~0x80000000) | s;
  return x.f32;
}


x86 assembly (clang, -O0):
<modff>:
push   %rbp
mov    %rsp,%rbp
movss  %xmm0,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
movss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
and    $0x7fffffff,%eax
mov    %eax,-0x1c(%rbp)
cmpl   $0x4b000000,-0x1c(%rbp)
jb     1163 <modff+0x63>
movss  -0x18(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movss  %xmm0,(%rax)
cmpl   $0x7f800000,-0x1c(%rbp)
ja     1154 <modff+0x54>
mov    -0x18(%rbp),%eax
and    $0x80000000,%eax
mov    %eax,-0x18(%rbp)
movss  -0x18(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    120d <modff+0x10d>
cmpl   $0x3f800000,-0x1c(%rbp)
jae    11a1 <modff+0xa1>
movss  -0x18(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x18(%rbp),%eax
and    $0x80000000,%eax
mov    %eax,-0x18(%rbp)
movss  -0x18(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    120d <modff+0x10d>
mov    -0x18(%rbp),%eax
and    $0x80000000,%eax
mov    %eax,-0x20(%rbp)
movss  -0x18(%rbp),%xmm0
movss  %xmm0,-0x8(%rbp)
mov    -0x1c(%rbp),%eax
shr    $0x17,%eax
mov    $0x96,%ecx
sub    %eax,%ecx
mov    $0x1,%eax
shl    %cl,%eax
sub    $0x1,%eax
xor    $0xffffffff,%eax
and    -0x18(%rbp),%eax
mov    %eax,-0x18(%rbp)
movss  -0x18(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
subss  (%rax),%xmm0
movss  %xmm0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
and    $0x7fffffff,%eax
or     -0x20(%rbp),%eax
mov    %eax,-0x18(%rbp)
movss  -0x18(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<modff>:
movd   %xmm0,%eax
mov    %eax,%esi
and    $0x7fffffff,%esi
cmp    $0x4b000000,%esi
jb     112e <modff+0x2e>
movss  %xmm0,(%rdi)
mov    %eax,%ecx
and    $0x80000000,%ecx
cmp    $0x7f800001,%esi
cmovae %eax,%ecx
movd   %ecx,%xmm0
ret
mov    %eax,%edx
and    $0x80000000,%edx
cmp    $0x3f7fffff,%esi
ja     1141 <modff+0x41>
mov    %edx,(%rdi)
ret
shr    $0x17,%esi
mov    $0x96,%cl
sub    %sil,%cl
shr    %cl,%eax
shl    %cl,%eax
movd   %eax,%xmm1
mov    %eax,(%rdi)
subss  %xmm1,%xmm0
movd   %xmm0,%eax
and    $0x7fffffff,%eax
or     %edx,%eax
movd   %eax,%xmm0
ret

LLVM IR (-O0):
%union.anon = type { i32 }
define float @modff(float %0, float* %1) {
%3 = alloca float
%4 = alloca float
%5 = alloca float*
%6 = alloca %union.anon
%7 = alloca i32
%8 = alloca i32
%9 = alloca float
store float %0, float* %4
store float* %1, float** %5
%10 = load float, float* %4
%11 = bitcast %union.anon* %6 to float*
store float %10, float* %11
%12 = bitcast %union.anon* %6 to i32*
%13 = load i32, i32* %12
%14 = and i32 %13, 2147483647
store i32 %14, i32* %7
%15 = load i32, i32* %7
%16 = icmp uge i32 %15, 1258291200
br i1 %16, label %17, label %30
17: ; preds = %2
%18 = bitcast %union.anon* %6 to float*
%19 = load float, float* %18
%20 = load float*, float** %5
store float %19, float* %20
%21 = load i32, i32* %7
%22 = icmp ule i32 %21, 2139095040
br i1 %22, label %23, label %27
23: ; preds = %17
%24 = bitcast %union.anon* %6 to i32*
%25 = load i32, i32* %24
%26 = and i32 %25, -2147483648
store i32 %26, i32* %24
br label %27
27: ; preds = %23, %17
%28 = bitcast %union.anon* %6 to float*
%29 = load float, float* %28
store float %29, float* %3
br label %74
30: ; preds = %2
%31 = load i32, i32* %7
%32 = icmp ult i32 %31, 1065353216
br i1 %32, label %33, label %43
33: ; preds = %30
%34 = bitcast %union.anon* %6 to float*
%35 = load float, float* %34
store float %35, float* %9
%36 = bitcast %union.anon* %6 to i32*
%37 = load i32, i32* %36
%38 = and i32 %37, -2147483648
store i32 %38, i32* %36
%39 = bitcast %union.anon* %6 to float*
%40 = load float, float* %39
%41 = load float*, float** %5
store float %40, float* %41
%42 = load float, float* %9
store float %42, float* %3
br label %74
43: ; preds = %30
%44 = bitcast %union.anon* %6 to i32*
%45 = load i32, i32* %44
%46 = and i32 %45, -2147483648
store i32 %46, i32* %8
%47 = bitcast %union.anon* %6 to float*
%48 = load float, float* %47
store float %48, float* %4
%49 = load i32, i32* %7
%50 = lshr i32 %49, 23
%51 = sub i32 150, %50
%52 = shl i32 1, %51
%53 = sub nsw i32 %52, 1
%54 = xor i32 %53, -1
%55 = bitcast %union.anon* %6 to i32*
%56 = load i32, i32* %55
%57 = and i32 %56, %54
store i32 %57, i32* %55
%58 = bitcast %union.anon* %6 to float*
%59 = load float, float* %58
%60 = load float*, float** %5
store float %59, float* %60
%61 = load float, float* %4
%62 = load float*, float** %5
%63 = load float, float* %62
%64 = fsub float %61, %63
%65 = bitcast %union.anon* %6 to float*
store float %64, float* %65
%66 = bitcast %union.anon* %6 to i32*
%67 = load i32, i32* %66
%68 = and i32 %67, 2147483647
%69 = load i32, i32* %8
%70 = or i32 %68, %69
%71 = bitcast %union.anon* %6 to i32*
store i32 %70, i32* %71
%72 = bitcast %union.anon* %6 to float*
%73 = load float, float* %72
store float %73, float* %3
br label %74
74: ; preds = %43, %33, %27
%75 = load float, float* %3
ret float %75
}

LLVM IR (-O2):
define float @modff(float %0, float* nocapture writeonly %1) {
%3 = bitcast float %0 to i32
%4 = and i32 %3, 2147483647
%5 = icmp ugt i32 %4, 1258291199
br i1 %5, label %6, label %11
6: ; preds = %2
store float %0, float* %1
%7 = icmp ult i32 %4, 2139095041
%8 = and i32 %3, -2147483648
%9 = select i1 %7, i32 %8, i32 %3
%10 = bitcast i32 %9 to float
br label %28
11: ; preds = %2
%12 = icmp ult i32 %4, 1065353216
%13 = and i32 %3, -2147483648
br i1 %12, label %14, label %16
14: ; preds = %11
%15 = bitcast float* %1 to i32*
store i32 %13, i32* %15
br label %28
16: ; preds = %11
%17 = lshr i32 %4, 23
%18 = sub nuw nsw i32 150, %17
%19 = shl nsw i32 -1, %18
%20 = and i32 %19, %3
%21 = bitcast i32 %20 to float
%22 = bitcast float* %1 to i32*
store i32 %20, i32* %22
%23 = fsub float %0, %21
%24 = bitcast float %23 to i32
%25 = and i32 %24, 2147483647
%26 = or i32 %25, %13
%27 = bitcast i32 %26 to float
br label %28
28: ; preds = %16, %14, %6
%29 = phi float [ %10, %6 ], [ %0, %14 ], [ %27, %16 ]
ret float %29
}