float iir_filter(float input, float *coef, int n, float *history) {
  int i;
  float *hist1_ptr, *hist2_ptr, *coef_ptr;
  float output, new_hist, history1, history2;
  coef_ptr = coef;
  hist1_ptr = history;
  hist2_ptr = hist1_ptr + 1;
  output = input * (*coef_ptr++);
  for (i = 0; i < n; i++) {
    history1 = *hist1_ptr;
    history2 = *hist2_ptr;
    output = output - history1 * (*coef_ptr++);
    new_hist = output - history2 * (*coef_ptr++);
    output = new_hist + history1 * (*coef_ptr++);
    output = output + history2 * (*coef_ptr++);
    *hist2_ptr++ = *hist1_ptr;
    *hist1_ptr++ = new_hist;
    hist1_ptr++;
    hist2_ptr++;
  }
  return (output);
}


x86 assembly (clang, -O0):
<iir_filter>:
push   %rbp
mov    %rsp,%rbp
movss  %xmm0,-0x4(%rbp)
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x38(%rbp)
movss  -0x4(%rbp),%xmm0
mov    -0x40(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x40(%rbp)
mulss  (%rax),%xmm0
movss  %xmm0,-0x44(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    1295 <iir_filter+0x195>
mov    -0x30(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x4c(%rbp)
mov    -0x38(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x50(%rbp)
movss  -0x44(%rbp),%xmm1
movss  -0x4c(%rbp),%xmm0
mov    -0x40(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x40(%rbp)
movss  (%rax),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x44(%rbp)
movss  -0x44(%rbp),%xmm1
movss  -0x50(%rbp),%xmm0
mov    -0x40(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x40(%rbp)
movss  (%rax),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x48(%rbp)
movss  -0x48(%rbp),%xmm1
movss  -0x4c(%rbp),%xmm0
mov    -0x40(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x40(%rbp)
movss  (%rax),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x44(%rbp)
movss  -0x44(%rbp),%xmm1
movss  -0x50(%rbp),%xmm0
mov    -0x40(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x40(%rbp)
movss  (%rax),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x44(%rbp)
mov    -0x30(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x38(%rbp)
movss  %xmm0,(%rax)
movss  -0x48(%rbp),%xmm0
mov    -0x30(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x30(%rbp)
movss  %xmm0,(%rax)
mov    -0x30(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x30(%rbp)
mov    -0x38(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x38(%rbp)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    1154 <iir_filter+0x54>
movss  -0x44(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<iir_filter>:
mulss  (%rdi),%xmm0
test   %esi,%esi
jle    1167 <iir_filter+0x67>
add    $0x4,%rdi
mov    %esi,%eax
xor    %ecx,%ecx
movss  (%rdx,%rcx,8),%xmm2
movss  0x4(%rdx,%rcx,8),%xmm1
movss  (%rdi),%xmm3
mulss  %xmm2,%xmm3
subss  %xmm3,%xmm0
movss  0x4(%rdi),%xmm3
mulss  %xmm1,%xmm3
subss  %xmm3,%xmm0
movss  0x8(%rdi),%xmm3
mulss  %xmm2,%xmm3
addss  %xmm0,%xmm3
mulss  0xc(%rdi),%xmm1
addss  %xmm3,%xmm1
movss  %xmm2,0x4(%rdx,%rcx,8)
movss  %xmm0,(%rdx,%rcx,8)
add    $0x1,%rcx
add    $0x10,%rdi
movaps %xmm1,%xmm0
cmp    %ecx,%eax
jne    1110 <iir_filter+0x10>
movaps %xmm1,%xmm0
ret

LLVM IR (-O0):
define float @iir_filter(float %0, float* %1, i32 %2, float* %3) {
%5 = alloca float
%6 = alloca float*
%7 = alloca i32
%8 = alloca float*
%9 = alloca i32
%10 = alloca float*
%11 = alloca float*
%12 = alloca float*
%13 = alloca float
%14 = alloca float
%15 = alloca float
%16 = alloca float
store float %0, float* %5
store float* %1, float** %6
store i32 %2, i32* %7
store float* %3, float** %8
%17 = load float*, float** %6
store float* %17, float** %12
%18 = load float*, float** %8
store float* %18, float** %10
%19 = load float*, float** %10
%20 = getelementptr inbounds float, float* %19, i64 1
store float* %20, float** %11
%21 = load float, float* %5
%22 = load float*, float** %12
%23 = getelementptr inbounds float, float* %22, i32 1
store float* %23, float** %12
%24 = load float, float* %22
%25 = fmul float %21, %24
store float %25, float* %13
store i32 0, i32* %9
br label %26
26: ; preds = %72, %4
%27 = load i32, i32* %9
%28 = load i32, i32* %7
%29 = icmp slt i32 %27, %28
br i1 %29, label %30, label %75
30: ; preds = %26
%31 = load float*, float** %10
%32 = load float, float* %31
store float %32, float* %15
%33 = load float*, float** %11
%34 = load float, float* %33
store float %34, float* %16
%35 = load float, float* %13
%36 = load float, float* %15
%37 = load float*, float** %12
%38 = getelementptr inbounds float, float* %37, i32 1
store float* %38, float** %12
%39 = load float, float* %37
%40 = fneg float %36
%41 = call float @llvm.fmuladd.f32(float %40, float %39, float %35)
store float %41, float* %13
%42 = load float, float* %13
%43 = load float, float* %16
%44 = load float*, float** %12
%45 = getelementptr inbounds float, float* %44, i32 1
store float* %45, float** %12
%46 = load float, float* %44
%47 = fneg float %43
%48 = call float @llvm.fmuladd.f32(float %47, float %46, float %42)
store float %48, float* %14
%49 = load float, float* %14
%50 = load float, float* %15
%51 = load float*, float** %12
%52 = getelementptr inbounds float, float* %51, i32 1
store float* %52, float** %12
%53 = load float, float* %51
%54 = call float @llvm.fmuladd.f32(float %50, float %53, float %49)
store float %54, float* %13
%55 = load float, float* %13
%56 = load float, float* %16
%57 = load float*, float** %12
%58 = getelementptr inbounds float, float* %57, i32 1
store float* %58, float** %12
%59 = load float, float* %57
%60 = call float @llvm.fmuladd.f32(float %56, float %59, float %55)
store float %60, float* %13
%61 = load float*, float** %10
%62 = load float, float* %61
%63 = load float*, float** %11
%64 = getelementptr inbounds float, float* %63, i32 1
store float* %64, float** %11
store float %62, float* %63
%65 = load float, float* %14
%66 = load float*, float** %10
%67 = getelementptr inbounds float, float* %66, i32 1
store float* %67, float** %10
store float %65, float* %66
%68 = load float*, float** %10
%69 = getelementptr inbounds float, float* %68, i32 1
store float* %69, float** %10
%70 = load float*, float** %11
%71 = getelementptr inbounds float, float* %70, i32 1
store float* %71, float** %11
br label %72
72: ; preds = %30
%73 = load i32, i32* %9
%74 = add nsw i32 %73, 1
store i32 %74, i32* %9
br label %26
75: ; preds = %26
%76 = load float, float* %13
ret float %76
}

LLVM IR (-O2):
define float @iir_filter(float %0, float* nocapture %1, i32 %2, float* nocapture %3) {
%5 = load float, float* %1
%6 = fmul float %5, %0
%7 = icmp sgt i32 %2, 0
br i1 %7, label %8, label %37
8: ; preds = %4
%9 = getelementptr inbounds float, float* %1, i64 1
%10 = getelementptr inbounds float, float* %3, i64 1
br label %11
11: ; preds = %8, %11
%12 = phi i32 [ %35, %11 ], [ 0, %8 ]
%13 = phi float* [ %33, %11 ], [ %3, %8 ]
%14 = phi float* [ %34, %11 ], [ %10, %8 ]
%15 = phi float [ %32, %11 ], [ %6, %8 ]
%16 = phi float* [ %30, %11 ], [ %9, %8 ]
%17 = load float, float* %13
%18 = load float, float* %14
%19 = getelementptr inbounds float, float* %16, i64 1
%20 = load float, float* %16
%21 = fneg float %17
%22 = tail call float @llvm.fmuladd.f32(float %21, float %20, float %15)
%23 = getelementptr inbounds float, float* %16, i64 2
%24 = load float, float* %19
%25 = fneg float %18
%26 = tail call float @llvm.fmuladd.f32(float %25, float %24, float %22)
%27 = getelementptr inbounds float, float* %16, i64 3
%28 = load float, float* %23
%29 = tail call float @llvm.fmuladd.f32(float %17, float %28, float %26)
%30 = getelementptr inbounds float, float* %16, i64 4
%31 = load float, float* %27
%32 = tail call float @llvm.fmuladd.f32(float %18, float %31, float %29)
store float %17, float* %14
store float %26, float* %13
%33 = getelementptr inbounds float, float* %13, i64 2
%34 = getelementptr inbounds float, float* %14, i64 2
%35 = add nuw nsw i32 %12, 1
%36 = icmp eq i32 %35, %2
br i1 %36, label %37, label %11
37: ; preds = %11, %4
%38 = phi float [ %6, %4 ], [ %32, %11 ]
ret float %38
}