float __addsf3(float a_fp, float b_fp) {
  unsigned long a, b, c;
  unsigned long as, bs, cs;
  long ae, af, be, bf, ce, cf;
  a = (*(unsigned long *)&(a_fp));
  b = (*(unsigned long *)&(b_fp));
  as = a >> 31;
  ae = (a >> 23) & 0xff;
  af = 0x00800000 | (a & 0x007fffff);
  bs = b >> 31;
  be = (b >> 23) & 0xff;
  bf = 0x00800000 | (b & 0x007fffff);
  if (ae > be) {
    if (ae - be < 30)
      bf >>= ae - be;
    else
      bf = 0;
    ce = ae;
  } else {
    if (be - ae < 30)
      af >>= be - ae;
    else
      af = 0;
    ce = be;
  }
  cf = (as ? -af : af) + (bs ? -bf : bf);
  cs = cf < 0;
  cf = cf >= 0 ? cf : -cf;
  if (cf == 0)
    return (*(float *)&(cf));
  while (cf & 0xff000000) {
    ++ce;
    cf >>= 1;
  }
  while ((cf & 0xff800000) == 0) {
    --ce;
    cf <<= 1;
  }
  c = (cs << 31) | (ce << 23) | (cf & 0x007fffff);
  if (ce < 1)
    c = 0;
  return (*(float *)&(c));
}


x86 assembly (clang, -O0):
<__addsf3>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
movss  %xmm0,-0x8(%rbp)
movss  %xmm1,-0xc(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0xc(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x18(%rbp),%rax
shr    $0x1f,%rax
mov    %rax,-0x30(%rbp)
mov    -0x18(%rbp),%rax
shr    $0x17,%rax
and    $0xff,%rax
mov    %rax,-0x48(%rbp)
mov    -0x18(%rbp),%rax
and    $0x7fffff,%rax
or     $0x800000,%rax
mov    %rax,-0x50(%rbp)
mov    -0x20(%rbp),%rax
shr    $0x1f,%rax
mov    %rax,-0x38(%rbp)
mov    -0x20(%rbp),%rax
shr    $0x17,%rax
and    $0xff,%rax
mov    %rax,-0x58(%rbp)
mov    -0x20(%rbp),%rax
and    $0x7fffff,%rax
or     $0x800000,%rax
mov    %rax,-0x60(%rbp)
mov    -0x48(%rbp),%rax
cmp    -0x58(%rbp),%rax
jle    11d3 <__addsf3+0xd3>
mov    -0x48(%rbp),%rax
sub    -0x58(%rbp),%rax
cmp    $0x1e,%rax
jge    11be <__addsf3+0xbe>
mov    -0x48(%rbp),%rcx
sub    -0x58(%rbp),%rcx
mov    -0x60(%rbp),%rax
sar    %cl,%rax
mov    %rax,-0x60(%rbp)
jmp    11c6 <__addsf3+0xc6>
movq   $0x0,-0x60(%rbp)
mov    -0x48(%rbp),%rax
mov    %rax,-0x68(%rbp)
jmp    120d <__addsf3+0x10d>
mov    -0x58(%rbp),%rax
sub    -0x48(%rbp),%rax
cmp    $0x1e,%rax
jge    11fd <__addsf3+0xfd>
mov    -0x58(%rbp),%rcx
sub    -0x48(%rbp),%rcx
mov    -0x50(%rbp),%rax
sar    %cl,%rax
mov    %rax,-0x50(%rbp)
jmp    1205 <__addsf3+0x105>
movq   $0x0,-0x50(%rbp)
mov    -0x58(%rbp),%rax
mov    %rax,-0x68(%rbp)
cmpq   $0x0,-0x30(%rbp)
je     1227 <__addsf3+0x127>
xor    %eax,%eax
sub    -0x50(%rbp),%rax
mov    %rax,-0x78(%rbp)
jmp    122f <__addsf3+0x12f>
mov    -0x50(%rbp),%rax
mov    %rax,-0x78(%rbp)
mov    -0x78(%rbp),%rax
mov    %rax,-0x80(%rbp)
cmpq   $0x0,-0x38(%rbp)
je     1254 <__addsf3+0x154>
xor    %eax,%eax
sub    -0x60(%rbp),%rax
mov    %rax,-0x88(%rbp)
jmp    125f <__addsf3+0x15f>
mov    -0x60(%rbp),%rax
mov    %rax,-0x88(%rbp)
mov    -0x80(%rbp),%rax
mov    -0x88(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x70(%rbp)
cmpq   $0x0,-0x70(%rbp)
setl   %al
and    $0x1,%al
movzbl %al,%eax
cltq
mov    %rax,-0x40(%rbp)
cmpq   $0x0,-0x70(%rbp)
jl     129f <__addsf3+0x19f>
mov    -0x70(%rbp),%rax
mov    %rax,-0x90(%rbp)
jmp    12ac <__addsf3+0x1ac>
xor    %eax,%eax
sub    -0x70(%rbp),%rax
mov    %rax,-0x90(%rbp)
mov    -0x90(%rbp),%rax
mov    %rax,-0x70(%rbp)
cmpq   $0x0,-0x70(%rbp)
jne    12d1 <__addsf3+0x1d1>
movss  -0x70(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    1387 <__addsf3+0x287>
jmp    12d6 <__addsf3+0x1d6>
movabs $0xff000000,%rax
and    -0x70(%rbp),%rax
cmp    $0x0,%rax
je     130b <__addsf3+0x20b>
mov    -0x68(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x68(%rbp)
mov    -0x70(%rbp),%rax
sar    $0x1,%rax
mov    %rax,-0x70(%rbp)
jmp    12d6 <__addsf3+0x1d6>
jmp    1310 <__addsf3+0x210>
movabs $0xff800000,%rax
and    -0x70(%rbp),%rax
cmp    $0x0,%rax
jne    1345 <__addsf3+0x245>
mov    -0x68(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x68(%rbp)
mov    -0x70(%rbp),%rax
shl    $0x1,%rax
mov    %rax,-0x70(%rbp)
jmp    1310 <__addsf3+0x210>
mov    -0x40(%rbp),%rax
shl    $0x1f,%rax
mov    -0x68(%rbp),%rcx
shl    $0x17,%rcx
or     %rcx,%rax
mov    -0x70(%rbp),%rcx
and    $0x7fffff,%rcx
or     %rcx,%rax
mov    %rax,-0x28(%rbp)
cmpq   $0x1,-0x68(%rbp)
jge    137d <__addsf3+0x27d>
movq   $0x0,-0x28(%rbp)
movss  -0x28(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<__addsf3>:
movss  %xmm0,-0x8(%rsp)
movss  %xmm1,-0x10(%rsp)
mov    -0x8(%rsp),%r9
mov    -0x10(%rsp),%r8
mov    %r9d,%eax
shr    $0x17,%eax
movzbl %al,%eax
mov    %r9d,%edi
and    $0x7fffff,%edi
or     $0x800000,%rdi
mov    %r8d,%ecx
shr    $0x17,%ecx
movzbl %cl,%esi
mov    %r8d,%edx
and    $0x7fffff,%edx
or     $0x800000,%rdx
mov    %rax,%rcx
sub    %rsi,%rcx
jbe    115f <__addsf3+0x5f>
shr    %cl,%rdx
xor    %esi,%esi
cmp    $0x1e,%rcx
cmovge %rsi,%rdx
jmp    1175 <__addsf3+0x75>
mov    %rsi,%rcx
sub    %rax,%rcx
shr    %cl,%rdi
xor    %eax,%eax
cmp    $0x1e,%rcx
cmovge %rax,%rdi
mov    %rsi,%rax
mov    %rdi,%rsi
neg    %rsi
test   $0xffffffff80000000,%r9
cmove  %rdi,%rsi
mov    %rdx,%rcx
neg    %rcx
test   $0xffffffff80000000,%r8
cmove  %rdx,%rcx
add    %rsi,%rcx
mov    %rcx,%rdx
neg    %rdx
cmovs  %rcx,%rdx
jae    11fe <__addsf3+0xfe>
test   $0xff000000,%edx
je     11cf <__addsf3+0xcf>
movabs $0x1fe000000,%rsi
nopl   0x0(%rax,%rax,1)
mov    %rdx,%rdi
add    $0x1,%rax
shr    %rdx
test   %rsi,%rdi
jne    11c0 <__addsf3+0xc0>
mov    %edx,%esi
test   $0xff800000,%esi
jne    11f5 <__addsf3+0xf5>
nopl   0x0(%rax)
add    $0xffffffffffffffff,%rax
lea    (%rsi,%rsi,1),%rdx
mov    %edx,%edi
test   $0x7fc00000,%esi
mov    %rdi,%rsi
je     11e0 <__addsf3+0xe0>
test   %rax,%rax
jg     1203 <__addsf3+0x103>
xorps  %xmm0,%xmm0
ret
movd   %edx,%xmm0
ret
shr    $0x20,%rcx
and    $0x80000000,%ecx
shl    $0x17,%eax
or     %ecx,%eax
and    $0x7fffff,%edx
or     %eax,%edx
movd   %edx,%xmm0
ret

LLVM IR (-O0):
define float @__addsf3(float %0, float %1) {
%3 = alloca float
%4 = alloca float
%5 = alloca float
%6 = alloca i64
%7 = alloca i64
%8 = alloca i64
%9 = alloca i64
%10 = alloca i64
%11 = alloca i64
%12 = alloca i64
%13 = alloca i64
%14 = alloca i64
%15 = alloca i64
%16 = alloca i64
%17 = alloca i64
store float %0, float* %4
store float %1, float* %5
%18 = bitcast float* %4 to i64*
%19 = load i64, i64* %18
store i64 %19, i64* %6
%20 = bitcast float* %5 to i64*
%21 = load i64, i64* %20
store i64 %21, i64* %7
%22 = load i64, i64* %6
%23 = lshr i64 %22, 31
store i64 %23, i64* %9
%24 = load i64, i64* %6
%25 = lshr i64 %24, 23
%26 = and i64 %25, 255
store i64 %26, i64* %12
%27 = load i64, i64* %6
%28 = and i64 %27, 8388607
%29 = or i64 8388608, %28
store i64 %29, i64* %13
%30 = load i64, i64* %7
%31 = lshr i64 %30, 31
store i64 %31, i64* %10
%32 = load i64, i64* %7
%33 = lshr i64 %32, 23
%34 = and i64 %33, 255
store i64 %34, i64* %14
%35 = load i64, i64* %7
%36 = and i64 %35, 8388607
%37 = or i64 8388608, %36
store i64 %37, i64* %15
%38 = load i64, i64* %12
%39 = load i64, i64* %14
%40 = icmp sgt i64 %38, %39
br i1 %40, label %41, label %55
41: ; preds = %2
%42 = load i64, i64* %12
%43 = load i64, i64* %14
%44 = sub nsw i64 %42, %43
%45 = icmp slt i64 %44, 30
br i1 %45, label %46, label %52
46: ; preds = %41
%47 = load i64, i64* %12
%48 = load i64, i64* %14
%49 = sub nsw i64 %47, %48
%50 = load i64, i64* %15
%51 = ashr i64 %50, %49
store i64 %51, i64* %15
br label %53
52: ; preds = %41
store i64 0, i64* %15
br label %53
53: ; preds = %52, %46
%54 = load i64, i64* %12
store i64 %54, i64* %16
br label %69
55: ; preds = %2
%56 = load i64, i64* %14
%57 = load i64, i64* %12
%58 = sub nsw i64 %56, %57
%59 = icmp slt i64 %58, 30
br i1 %59, label %60, label %66
60: ; preds = %55
%61 = load i64, i64* %14
%62 = load i64, i64* %12
%63 = sub nsw i64 %61, %62
%64 = load i64, i64* %13
%65 = ashr i64 %64, %63
store i64 %65, i64* %13
br label %67
66: ; preds = %55
store i64 0, i64* %13
br label %67
67: ; preds = %66, %60
%68 = load i64, i64* %14
store i64 %68, i64* %16
br label %69
69: ; preds = %67, %53
%70 = load i64, i64* %9
%71 = icmp ne i64 %70, 0
br i1 %71, label %72, label %75
72: ; preds = %69
%73 = load i64, i64* %13
%74 = sub nsw i64 0, %73
br label %77
75: ; preds = %69
%76 = load i64, i64* %13
br label %77
77: ; preds = %75, %72
%78 = phi i64 [ %74, %72 ], [ %76, %75 ]
%79 = load i64, i64* %10
%80 = icmp ne i64 %79, 0
br i1 %80, label %81, label %84
81: ; preds = %77
%82 = load i64, i64* %15
%83 = sub nsw i64 0, %82
br label %86
84: ; preds = %77
%85 = load i64, i64* %15
br label %86
86: ; preds = %84, %81
%87 = phi i64 [ %83, %81 ], [ %85, %84 ]
%88 = add nsw i64 %78, %87
store i64 %88, i64* %17
%89 = load i64, i64* %17
%90 = icmp slt i64 %89, 0
%91 = zext i1 %90 to i32
%92 = sext i32 %91 to i64
store i64 %92, i64* %11
%93 = load i64, i64* %17
%94 = icmp sge i64 %93, 0
br i1 %94, label %95, label %97
95: ; preds = %86
%96 = load i64, i64* %17
br label %100
97: ; preds = %86
%98 = load i64, i64* %17
%99 = sub nsw i64 0, %98
br label %100
100: ; preds = %97, %95
%101 = phi i64 [ %96, %95 ], [ %99, %97 ]
store i64 %101, i64* %17
%102 = load i64, i64* %17
%103 = icmp eq i64 %102, 0
br i1 %103, label %104, label %107
104: ; preds = %100
%105 = bitcast i64* %17 to float*
%106 = load float, float* %105
store float %106, float* %3
br label %142
107: ; preds = %100
br label %108
108: ; preds = %112, %107
%109 = load i64, i64* %17
%110 = and i64 %109, 4278190080
%111 = icmp ne i64 %110, 0
br i1 %111, label %112, label %117
112: ; preds = %108
%113 = load i64, i64* %16
%114 = add nsw i64 %113, 1
store i64 %114, i64* %16
%115 = load i64, i64* %17
%116 = ashr i64 %115, 1
store i64 %116, i64* %17
br label %108
117: ; preds = %108
br label %118
118: ; preds = %122, %117
%119 = load i64, i64* %17
%120 = and i64 %119, 4286578688
%121 = icmp eq i64 %120, 0
br i1 %121, label %122, label %127
122: ; preds = %118
%123 = load i64, i64* %16
%124 = add nsw i64 %123, -1
store i64 %124, i64* %16
%125 = load i64, i64* %17
%126 = shl i64 %125, 1
store i64 %126, i64* %17
br label %118
127: ; preds = %118
%128 = load i64, i64* %11
%129 = shl i64 %128, 31
%130 = load i64, i64* %16
%131 = shl i64 %130, 23
%132 = or i64 %129, %131
%133 = load i64, i64* %17
%134 = and i64 %133, 8388607
%135 = or i64 %132, %134
store i64 %135, i64* %8
%136 = load i64, i64* %16
%137 = icmp slt i64 %136, 1
br i1 %137, label %138, label %139
138: ; preds = %127
store i64 0, i64* %8
br label %139
139: ; preds = %138, %127
%140 = bitcast i64* %8 to float*
%141 = load float, float* %140
store float %141, float* %3
br label %142
142: ; preds = %139, %104
%143 = load float, float* %3
ret float %143
}

LLVM IR (-O2):
define float @__addsf3(float %0, float %1) {
%3 = alloca float
%4 = alloca float
store float %0, float* %3
store float %1, float* %4
%5 = bitcast float* %3 to i64*
%6 = load i64, i64* %5
%7 = bitcast float* %4 to i64*
%8 = load i64, i64* %7
%9 = lshr i64 %6, 23
%10 = and i64 %9, 255
%11 = and i64 %6, 8388607
%12 = or i64 %11, 8388608
%13 = lshr i64 %8, 23
%14 = and i64 %13, 255
%15 = and i64 %8, 8388607
%16 = or i64 %15, 8388608
%17 = icmp ugt i64 %10, %14
br i1 %17, label %18, label %23
18: ; preds = %2
%19 = sub nsw i64 %10, %14
%20 = icmp slt i64 %19, 30
%21 = lshr i64 %16, %19
%22 = select i1 %20, i64 %21, i64 0
br label %28
23: ; preds = %2
%24 = sub nsw i64 %14, %10
%25 = icmp slt i64 %24, 30
%26 = lshr i64 %12, %24
%27 = select i1 %25, i64 %26, i64 0
br label %28
28: ; preds = %23, %18
%29 = phi i64 [ %12, %18 ], [ %27, %23 ]
%30 = phi i64 [ %22, %18 ], [ %16, %23 ]
%31 = phi i64 [ %10, %18 ], [ %14, %23 ]
%32 = icmp ult i64 %6, 2147483648
%33 = sub nsw i64 0, %29
%34 = select i1 %32, i64 %29, i64 %33
%35 = icmp ult i64 %8, 2147483648
%36 = sub nsw i64 0, %30
%37 = select i1 %35, i64 %30, i64 %36
%38 = add nsw i64 %37, %34
%39 = tail call i64 @llvm.abs.i64(i64 %38, i1 true)
%40 = trunc i64 %39 to i32
%41 = icmp eq i64 %38, 0
br i1 %41, label %45, label %42
42: ; preds = %28
%43 = and i64 %39, 4278190080
%44 = icmp eq i64 %43, 0
br i1 %44, label %49, label %55
45: ; preds = %28
%46 = bitcast i32 %40 to float
br label %85
47: ; preds = %55
%48 = trunc i64 %59 to i32
br label %49
49: ; preds = %47, %42
%50 = phi i64 [ %58, %47 ], [ %31, %42 ]
%51 = phi i32 [ %48, %47 ], [ %40, %42 ]
%52 = zext i32 %51 to i64
%53 = and i64 %52, 4286578688
%54 = icmp eq i64 %53, 0
br i1 %54, label %62, label %72
55: ; preds = %42, %55
%56 = phi i64 [ %59, %55 ], [ %39, %42 ]
%57 = phi i64 [ %58, %55 ], [ %31, %42 ]
%58 = add nuw nsw i64 %57, 1
%59 = lshr i64 %56, 1
%60 = and i64 %56, 8556380160
%61 = icmp eq i64 %60, 0
br i1 %61, label %47, label %55
62: ; preds = %49, %62
%63 = phi i64 [ %67, %62 ], [ %52, %49 ]
%64 = phi i64 [ %65, %62 ], [ %50, %49 ]
%65 = add nsw i64 %64, -1
%66 = shl nuw nsw i64 %63, 1
%67 = and i64 %66, 4294967294
%68 = and i64 %63, 2143289344
%69 = icmp eq i64 %68, 0
br i1 %69, label %62, label %70
70: ; preds = %62
%71 = trunc i64 %66 to i32
br label %72
72: ; preds = %70, %49
%73 = phi i32 [ %71, %70 ], [ %51, %49 ]
%74 = phi i64 [ %65, %70 ], [ %50, %49 ]
%75 = lshr i64 %38, 32
%76 = and i64 %75, 2147483648
%77 = shl i64 %74, 23
%78 = or i64 %77, %76
%79 = and i32 %73, 8388607
%80 = icmp sgt i64 %74, 0
%81 = trunc i64 %78 to i32
%82 = or i32 %79, %81
%83 = bitcast i32 %82 to float
%84 = select i1 %80, float %83, float 0.000000e+00
br label %85
85: ; preds = %72, %45
%86 = phi float [ %46, %45 ], [ %84, %72 ]
ret float %86
}