float interchop(float min, float max, float (*fcn)(float x),
                float (*chop)(float x)) {
  float f, g, h;
  float x, s, y;
  int i, n;
  n = 65536;
  s = (max - min) / n;
  x = min;
  s = chop(s);
  y = 0;
  for (i = 0; i < n; i++) {
    f = fcn(x);
    g = chop(f);
    x = x + s;
    y = y + g;
    x = chop(x);
    y = chop(y);
  }
  return (y);
}


x86 assembly (clang, -O0):
<interchop>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movss  %xmm0,-0x4(%rbp)
movss  %xmm1,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
movl   $0x10000,-0x38(%rbp)
movss  -0x8(%rbp),%xmm0
subss  -0x4(%rbp),%xmm0
cvtsi2ssl -0x38(%rbp),%xmm1
divss  %xmm1,%xmm0
movss  %xmm0,-0x2c(%rbp)
movss  -0x4(%rbp),%xmm0
movss  %xmm0,-0x28(%rbp)
mov    -0x18(%rbp),%rax
movss  -0x2c(%rbp),%xmm0
call   *%rax
movss  %xmm0,-0x2c(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x30(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x38(%rbp),%eax
jge    11da <interchop+0xda>
mov    -0x10(%rbp),%rax
movss  -0x28(%rbp),%xmm0
call   *%rax
movss  %xmm0,-0x1c(%rbp)
mov    -0x18(%rbp),%rax
movss  -0x1c(%rbp),%xmm0
call   *%rax
movss  %xmm0,-0x20(%rbp)
movss  -0x28(%rbp),%xmm0
addss  -0x2c(%rbp),%xmm0
movss  %xmm0,-0x28(%rbp)
movss  -0x30(%rbp),%xmm0
addss  -0x20(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
mov    -0x18(%rbp),%rax
movss  -0x28(%rbp),%xmm0
call   *%rax
movss  %xmm0,-0x28(%rbp)
mov    -0x18(%rbp),%rax
movss  -0x30(%rbp),%xmm0
call   *%rax
movss  %xmm0,-0x30(%rbp)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1162 <interchop+0x62>
movss  -0x30(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<interchop>:
push   %rbp
push   %r14
push   %rbx
sub    $0x10,%rsp
mov    %rsi,%rbx
mov    %rdi,%r14
movss  %xmm0,0x8(%rsp)
subss  %xmm0,%xmm1
mulss  0xee0(%rip),%xmm1
movaps %xmm1,%xmm0
call   *%rsi
movss  %xmm0,0xc(%rsp)
xorps  %xmm0,%xmm0
mov    $0x10000,%ebp
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movss  %xmm0,0x4(%rsp)
movss  0x8(%rsp),%xmm0
call   *%r14
call   *%rbx
movaps %xmm0,%xmm1
movss  0x8(%rsp),%xmm0
addss  0xc(%rsp),%xmm0
addss  0x4(%rsp),%xmm1
movss  %xmm1,0x4(%rsp)
call   *%rbx
movss  %xmm0,0x8(%rsp)
movss  0x4(%rsp),%xmm0
call   *%rbx
add    $0xffffffff,%ebp
jne    1140 <interchop+0x40>
add    $0x10,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define float @interchop(float %0, float %1, float (float)* %2, float (float)* %3) {
%5 = alloca float
%6 = alloca float
%7 = alloca float (float)*
%8 = alloca float (float)*
%9 = alloca float
%10 = alloca float
%11 = alloca float
%12 = alloca float
%13 = alloca float
%14 = alloca float
%15 = alloca i32
%16 = alloca i32
store float %0, float* %5
store float %1, float* %6
store float (float)* %2, float (float)** %7
store float (float)* %3, float (float)** %8
store i32 65536, i32* %16
%17 = load float, float* %6
%18 = load float, float* %5
%19 = fsub float %17, %18
%20 = load i32, i32* %16
%21 = sitofp i32 %20 to float
%22 = fdiv float %19, %21
store float %22, float* %13
%23 = load float, float* %5
store float %23, float* %12
%24 = load float (float)*, float (float)** %8
%25 = load float, float* %13
%26 = call float %24(float %25)
store float %26, float* %13
store float 0.000000e+00, float* %14
store i32 0, i32* %15
br label %27
27: ; preds = %50, %4
%28 = load i32, i32* %15
%29 = load i32, i32* %16
%30 = icmp slt i32 %28, %29
br i1 %30, label %31, label %53
31: ; preds = %27
%32 = load float (float)*, float (float)** %7
%33 = load float, float* %12
%34 = call float %32(float %33)
store float %34, float* %9
%35 = load float (float)*, float (float)** %8
%36 = load float, float* %9
%37 = call float %35(float %36)
store float %37, float* %10
%38 = load float, float* %12
%39 = load float, float* %13
%40 = fadd float %38, %39
store float %40, float* %12
%41 = load float, float* %14
%42 = load float, float* %10
%43 = fadd float %41, %42
store float %43, float* %14
%44 = load float (float)*, float (float)** %8
%45 = load float, float* %12
%46 = call float %44(float %45)
store float %46, float* %12
%47 = load float (float)*, float (float)** %8
%48 = load float, float* %14
%49 = call float %47(float %48)
store float %49, float* %14
br label %50
50: ; preds = %31
%51 = load i32, i32* %15
%52 = add nsw i32 %51, 1
store i32 %52, i32* %15
br label %27
53: ; preds = %27
%54 = load float, float* %14
ret float %54
}

LLVM IR (-O2):
define float @interchop(float %0, float %1, float (float)* nocapture %2, float (float)* nocapture %3) {
%5 = fsub float %1, %0
%6 = fmul float %5, 0x3EF0000000000000
%7 = tail call float %3(float %6)
br label %8
8: ; preds = %4, %8
%9 = phi float [ %0, %4 ], [ %16, %8 ]
%10 = phi i32 [ 0, %4 ], [ %18, %8 ]
%11 = phi float [ 0.000000e+00, %4 ], [ %17, %8 ]
%12 = tail call float %2(float %9)
%13 = tail call float %3(float %12)
%14 = fadd float %7, %9
%15 = fadd float %11, %13
%16 = tail call float %3(float %14)
%17 = tail call float %3(float %15)
%18 = add nuw nsw i32 %10, 1
%19 = icmp eq i32 %18, 65536
br i1 %19, label %20, label %8
20: ; preds = %8
ret float %17
}