float trapzd(float (*func)(float, void *), float a, float b, int n, void *p) {
  float x, tnm, sum, del;
  static float s;
  int it, j;
  if (n == 1) {
    s = 0.5 * (b - a) * (((*func)(a, p)) + ((*func)(b, p)));
  } else {
    for (it = 1, j = 1; j < (n - 1); j++)
      it <<= 1;
    tnm = it;
    del = (b - a) / tnm;
    x = a + 0.5 * del;
    for (sum = 0.0, j = 1; j <= it; j++, x += del)
      sum += ((*func)(x, p));
    s = 0.5 * (s + (b - a) * sum / tnm);
  }
  return (s);
}


x86 assembly (clang, -O0):
<trapzd>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
movss  %xmm0,-0xc(%rbp)
movss  %xmm1,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
cmpl   $0x1,-0x14(%rbp)
jne    1193 <trapzd+0x93>
movss  -0x10(%rbp),%xmm0
subss  -0xc(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xec3(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x8(%rbp),%rax
movss  -0xc(%rbp),%xmm0
mov    -0x20(%rbp),%rdi
call   *%rax
movss  %xmm0,-0x44(%rbp)
mov    -0x8(%rbp),%rax
movss  -0x10(%rbp),%xmm0
mov    -0x20(%rbp),%rdi
call   *%rax
movss  -0x44(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x40(%rbp),%xmm0
addss  %xmm2,%xmm1
cvtss2sd %xmm1,%xmm1
mulsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,0x2e96(%rip)
jmp    129f <trapzd+0x19f>
movl   $0x1,-0x34(%rbp)
movl   $0x1,-0x38(%rbp)
mov    -0x38(%rbp),%eax
mov    -0x14(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    11c9 <trapzd+0xc9>
mov    -0x34(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x34(%rbp)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    11a1 <trapzd+0xa1>
cvtsi2ssl -0x34(%rbp),%xmm0
movss  %xmm0,-0x28(%rbp)
movss  -0x10(%rbp),%xmm0
subss  -0xc(%rbp),%xmm0
divss  -0x28(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
movss  -0xc(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movss  -0x30(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xdff(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x24(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x2c(%rbp)
movl   $0x1,-0x38(%rbp)
mov    -0x38(%rbp),%eax
cmp    -0x34(%rbp),%eax
jg     1263 <trapzd+0x163>
mov    -0x8(%rbp),%rax
movss  -0x24(%rbp),%xmm0
mov    -0x20(%rbp),%rdi
call   *%rax
addss  -0x2c(%rbp),%xmm0
movss  %xmm0,-0x2c(%rbp)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
movss  -0x30(%rbp),%xmm0
addss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
jmp    1221 <trapzd+0x121>
movss  0x2db9(%rip),%xmm0
movss  -0x10(%rbp),%xmm1
subss  -0xc(%rbp),%xmm1
mulss  -0x2c(%rbp),%xmm1
divss  -0x28(%rbp),%xmm1
addss  %xmm1,%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xd71(%rip),%xmm0
mulsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,0x2d85(%rip)
movss  0x2d7d(%rip),%xmm0
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<trapzd>:
push   %rbp
push   %r14
push   %rbx
sub    $0x20,%rsp
mov    %rdx,%r14
mov    %rdi,%rbx
cmp    $0x1,%esi
jne    1161 <trapzd+0x61>
movss  %xmm1,0x4(%rsp)
subss  %xmm0,%xmm1
cvtss2sd %xmm1,%xmm1
mulsd  0xedf(%rip),%xmm1
movsd  %xmm1,0x10(%rsp)
mov    %r14,%rdi
call   *%rbx
movss  %xmm0,0xc(%rsp)
movss  0x4(%rsp),%xmm0
mov    %r14,%rdi
call   *%rbx
addss  0xc(%rsp),%xmm0
cvtss2sd %xmm0,%xmm0
mulsd  0x10(%rsp),%xmm0
xorps  %xmm1,%xmm1
cvtsd2ss %xmm0,%xmm1
jmp    1281 <trapzd+0x181>
cmp    $0x3,%esi
jl     117d <trapzd+0x7d>
lea    -0x2(%rsi),%ecx
add    $0xfffffffd,%esi
mov    %ecx,%eax
and    $0x7,%eax
cmp    $0x7,%esi
jae    119c <trapzd+0x9c>
mov    $0x1,%ebp
jmp    11b8 <trapzd+0xb8>
subss  %xmm0,%xmm1
mov    $0x1,%ebp
movss  0xe72(%rip),%xmm2
movss  %xmm2,0x1c(%rsp)
movss  %xmm1,0x4(%rsp)
jmp    11e7 <trapzd+0xe7>
and    $0xfffffff8,%ecx
mov    $0x1,%ebp
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
shl    $0x8,%ebp
add    $0xfffffff8,%ecx
jne    11b0 <trapzd+0xb0>
test   %eax,%eax
je     11c7 <trapzd+0xc7>
nopl   0x0(%rax)
add    %ebp,%ebp
add    $0xffffffff,%eax
jne    11c0 <trapzd+0xc0>
cvtsi2ss %ebp,%xmm2
subss  %xmm0,%xmm1
test   %ebp,%ebp
jle    1266 <trapzd+0x166>
movss  %xmm1,0x4(%rsp)
movss  %xmm2,0x1c(%rsp)
divss  %xmm2,%xmm1
movss  %xmm1,0x8(%rsp)
movss  0x8(%rsp),%xmm1
cvtss2sd %xmm1,%xmm1
cvtss2sd %xmm0,%xmm0
mulsd  0xe05(%rip),%xmm1
addsd  %xmm0,%xmm1
xorps  %xmm0,%xmm0
cvtsd2ss %xmm1,%xmm0
xorps  %xmm3,%xmm3
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movss  %xmm0,0xc(%rsp)
movss  %xmm3,0x10(%rsp)
mov    %r14,%rdi
call   *%rbx
movss  0x10(%rsp),%xmm1
addss  %xmm0,%xmm1
movss  %xmm1,0x10(%rsp)
movss  0xc(%rsp),%xmm0
movss  0x10(%rsp),%xmm3
addss  0x8(%rsp),%xmm0
add    $0xffffffff,%ebp
jne    1220 <trapzd+0x120>
movss  0x4(%rsp),%xmm1
movss  0x1c(%rsp),%xmm2
jmp    1269 <trapzd+0x169>
xorps  %xmm3,%xmm3
mulss  %xmm3,%xmm1
divss  %xmm2,%xmm1
addss  0x2dab(%rip),%xmm1
mulss  0xd83(%rip),%xmm1
movss  %xmm1,0x2d9b(%rip)
movaps %xmm1,%xmm0
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
@trapzd.s = internal global float 0.000000e+00
define float @trapzd(float (float, i8*)* %0, float %1, float %2, i32 %3, i8* %4) {
%6 = alloca float (float, i8*)*
%7 = alloca float
%8 = alloca float
%9 = alloca i32
%10 = alloca i8*
%11 = alloca float
%12 = alloca float
%13 = alloca float
%14 = alloca float
%15 = alloca i32
%16 = alloca i32
store float (float, i8*)* %0, float (float, i8*)** %6
store float %1, float* %7
store float %2, float* %8
store i32 %3, i32* %9
store i8* %4, i8** %10
%17 = load i32, i32* %9
%18 = icmp eq i32 %17, 1
br i1 %18, label %19, label %37
19: ; preds = %5
%20 = load float, float* %8
%21 = load float, float* %7
%22 = fsub float %20, %21
%23 = fpext float %22 to double
%24 = fmul double 5.000000e-01, %23
%25 = load float (float, i8*)*, float (float, i8*)** %6
%26 = load float, float* %7
%27 = load i8*, i8** %10
%28 = call float %25(float %26, i8* %27)
%29 = load float (float, i8*)*, float (float, i8*)** %6
%30 = load float, float* %8
%31 = load i8*, i8** %10
%32 = call float %29(float %30, i8* %31)
%33 = fadd float %28, %32
%34 = fpext float %33 to double
%35 = fmul double %24, %34
%36 = fptrunc double %35 to float
store float %36, float* @trapzd.s
br label %93
37: ; preds = %5
store i32 1, i32* %15
store i32 1, i32* %16
br label %38
38: ; preds = %46, %37
%39 = load i32, i32* %16
%40 = load i32, i32* %9
%41 = sub nsw i32 %40, 1
%42 = icmp slt i32 %39, %41
br i1 %42, label %43, label %49
43: ; preds = %38
%44 = load i32, i32* %15
%45 = shl i32 %44, 1
store i32 %45, i32* %15
br label %46
46: ; preds = %43
%47 = load i32, i32* %16
%48 = add nsw i32 %47, 1
store i32 %48, i32* %16
br label %38
49: ; preds = %38
%50 = load i32, i32* %15
%51 = sitofp i32 %50 to float
store float %51, float* %12
%52 = load float, float* %8
%53 = load float, float* %7
%54 = fsub float %52, %53
%55 = load float, float* %12
%56 = fdiv float %54, %55
store float %56, float* %14
%57 = load float, float* %7
%58 = fpext float %57 to double
%59 = load float, float* %14
%60 = fpext float %59 to double
%61 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %60, double %58)
%62 = fptrunc double %61 to float
store float %62, float* %11
store float 0.000000e+00, float* %13
store i32 1, i32* %16
br label %63
63: ; preds = %74, %49
%64 = load i32, i32* %16
%65 = load i32, i32* %15
%66 = icmp sle i32 %64, %65
br i1 %66, label %67, label %80
67: ; preds = %63
%68 = load float (float, i8*)*, float (float, i8*)** %6
%69 = load float, float* %11
%70 = load i8*, i8** %10
%71 = call float %68(float %69, i8* %70)
%72 = load float, float* %13
%73 = fadd float %72, %71
store float %73, float* %13
br label %74
74: ; preds = %67
%75 = load i32, i32* %16
%76 = add nsw i32 %75, 1
store i32 %76, i32* %16
%77 = load float, float* %14
%78 = load float, float* %11
%79 = fadd float %78, %77
store float %79, float* %11
br label %63
80: ; preds = %63
%81 = load float, float* @trapzd.s
%82 = load float, float* %8
%83 = load float, float* %7
%84 = fsub float %82, %83
%85 = load float, float* %13
%86 = fmul float %84, %85
%87 = load float, float* %12
%88 = fdiv float %86, %87
%89 = fadd float %81, %88
%90 = fpext float %89 to double
%91 = fmul double 5.000000e-01, %90
%92 = fptrunc double %91 to float
store float %92, float* @trapzd.s
br label %93
93: ; preds = %80, %19
%94 = load float, float* @trapzd.s
ret float %94
}

LLVM IR (-O2):
@trapzd.s = internal unnamed_addr global float 0.000000e+00
define float @trapzd(float (float, i8*)* nocapture %0, float %1, float %2, i32 %3, i8* %4) {
%6 = icmp eq i32 %3, 1
br i1 %6, label %18, label %7
7: ; preds = %5
%8 = icmp sgt i32 %3, 2
br i1 %8, label %9, label %16
9: ; preds = %7
%10 = add i32 %3, -2
%11 = add i32 %3, -3
%12 = and i32 %10, 7
%13 = icmp ult i32 %11, 7
br i1 %13, label %34, label %14
14: ; preds = %9
%15 = and i32 %10, -8
br label %28
16: ; preds = %7
%17 = fsub float %2, %1
br label %50
18: ; preds = %5
%19 = fsub float %2, %1
%20 = fpext float %19 to double
%21 = fmul double %20, 5.000000e-01
%22 = tail call float %0(float %1, i8* %4)
%23 = tail call float %0(float %2, i8* %4)
%24 = fadd float %22, %23
%25 = fpext float %24 to double
%26 = fmul double %21, %25
%27 = fptrunc double %26 to float
br label %77
28: ; preds = %28, %14
%29 = phi i32 [ 1, %14 ], [ %31, %28 ]
%30 = phi i32 [ 0, %14 ], [ %32, %28 ]
%31 = shl i32 %29, 8
%32 = add i32 %30, 8
%33 = icmp eq i32 %32, %15
br i1 %33, label %34, label %28
34: ; preds = %28, %9
%35 = phi i32 [ undef, %9 ], [ %31, %28 ]
%36 = phi i32 [ 1, %9 ], [ %31, %28 ]
%37 = icmp eq i32 %12, 0
br i1 %37, label %44, label %38
38: ; preds = %34, %38
%39 = phi i32 [ %41, %38 ], [ %36, %34 ]
%40 = phi i32 [ %42, %38 ], [ 0, %34 ]
%41 = shl i32 %39, 1
%42 = add i32 %40, 1
%43 = icmp eq i32 %42, %12
br i1 %43, label %44, label %38
44: ; preds = %38, %34
%45 = phi i32 [ %35, %34 ], [ %41, %38 ]
%46 = sitofp i32 %45 to float
%47 = fsub float %2, %1
%48 = fdiv float %47, %46
%49 = icmp slt i32 %45, 1
br i1 %49, label %68, label %50
50: ; preds = %16, %44
%51 = phi float [ %17, %16 ], [ %48, %44 ]
%52 = phi float [ %17, %16 ], [ %47, %44 ]
%53 = phi float [ 1.000000e+00, %16 ], [ %46, %44 ]
%54 = phi i32 [ 1, %16 ], [ %45, %44 ]
%55 = fpext float %51 to double
%56 = fpext float %1 to double
%57 = tail call double @llvm.fmuladd.f64(double %55, double 5.000000e-01, double %56)
%58 = fptrunc double %57 to float
br label %59
59: ; preds = %50, %59
%60 = phi i32 [ %65, %59 ], [ 1, %50 ]
%61 = phi float [ %66, %59 ], [ %58, %50 ]
%62 = phi float [ %64, %59 ], [ 0.000000e+00, %50 ]
%63 = tail call float %0(float %61, i8* %4)
%64 = fadd float %62, %63
%65 = add nuw nsw i32 %60, 1
%66 = fadd float %51, %61
%67 = icmp eq i32 %60, %54
br i1 %67, label %68, label %59
68: ; preds = %59, %44
%69 = phi float [ %47, %44 ], [ %52, %59 ]
%70 = phi float [ %46, %44 ], [ %53, %59 ]
%71 = phi float [ 0.000000e+00, %44 ], [ %64, %59 ]
%72 = load float, float* @trapzd.s
%73 = fmul float %69, %71
%74 = fdiv float %73, %70
%75 = fadd float %74, %72
%76 = fmul float %75, 5.000000e-01
br label %77
77: ; preds = %68, %18
%78 = phi float [ %76, %68 ], [ %27, %18 ]
store float %78, float* @trapzd.s
ret float %78
}