void iir1(const short *coefs, const short *input, long int *optr,
          long int *state) {
  long int x;
  long int t;
  long int n;
  x = input[0];
  for (n = 0; n < 50; n++) {
    t = x + ((coefs[2] * state[0] + coefs[3] * state[1]) >> 15);
    x = t + ((coefs[0] * state[0] + coefs[1] * state[1]) >> 15);
    state[1] = state[0];
    state[0] = t;
    coefs += 4;
    state += 2;
  }
  *optr++ = x;
}


x86 assembly (clang, -O0):
<iir1>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movswq (%rax),%rax
mov    %rax,-0x28(%rbp)
movq   $0x0,-0x38(%rbp)
cmpq   $0x32,-0x38(%rbp)
jge    11df <iir1+0xdf>
mov    -0x28(%rbp),%rax
mov    -0x8(%rbp),%rcx
movswq 0x4(%rcx),%rcx
mov    -0x20(%rbp),%rdx
imul   (%rdx),%rcx
mov    -0x8(%rbp),%rdx
movswq 0x6(%rdx),%rdx
mov    -0x20(%rbp),%rsi
imul   0x8(%rsi),%rdx
add    %rdx,%rcx
sar    $0xf,%rcx
add    %rcx,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
mov    -0x8(%rbp),%rcx
movswq (%rcx),%rcx
mov    -0x20(%rbp),%rdx
imul   (%rdx),%rcx
mov    -0x8(%rbp),%rdx
movswq 0x2(%rdx),%rdx
mov    -0x20(%rbp),%rsi
imul   0x8(%rsi),%rdx
add    %rdx,%rcx
sar    $0xf,%rcx
add    %rcx,%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,0x8(%rax)
mov    -0x30(%rbp),%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x8(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x8(%rbp)
mov    -0x20(%rbp),%rax
add    $0x10,%rax
mov    %rax,-0x20(%rbp)
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    1128 <iir1+0x28>
mov    -0x28(%rbp),%rcx
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x18(%rbp)
mov    %rcx,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<iir1>:
movswq (%rsi),%rsi
xor    %r11d,%r11d
nopw   0x0(%rax,%rax,1)
movswq 0x4(%rdi,%r11,1),%r8
mov    (%rcx,%r11,2),%r9
mov    0x8(%rcx,%r11,2),%r10
imul   %r9,%r8
movswq 0x6(%rdi,%r11,1),%rax
imul   %r10,%rax
add    %r8,%rax
sar    $0xf,%rax
add    %rsi,%rax
movswq (%rdi,%r11,1),%r8
imul   %r9,%r8
movswq 0x2(%rdi,%r11,1),%rsi
imul   %r10,%rsi
add    %r8,%rsi
sar    $0xf,%rsi
add    %rax,%rsi
mov    %r9,0x8(%rcx,%r11,2)
mov    %rax,(%rcx,%r11,2)
add    $0x8,%r11
cmp    $0x190,%r11
jne    1110 <iir1+0x10>
mov    %rsi,(%rdx)
ret

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

LLVM IR (-O2):
define void @iir1(i16* nocapture %0, i16* nocapture %1, i64* nocapture writeonly %2, i64* nocapture %3) {
%5 = load i16, i16* %1
%6 = sext i16 %5 to i64
br label %7
7: ; preds = %4, %7
%8 = phi i64 [ 0, %4 ], [ %38, %7 ]
%9 = phi i16* [ %0, %4 ], [ %36, %7 ]
%10 = phi i64 [ %6, %4 ], [ %35, %7 ]
%11 = phi i64* [ %3, %4 ], [ %37, %7 ]
%12 = getelementptr inbounds i16, i16* %9, i64 2
%13 = load i16, i16* %12
%14 = sext i16 %13 to i64
%15 = load i64, i64* %11
%16 = mul nsw i64 %15, %14
%17 = getelementptr inbounds i16, i16* %9, i64 3
%18 = load i16, i16* %17
%19 = sext i16 %18 to i64
%20 = getelementptr inbounds i64, i64* %11, i64 1
%21 = load i64, i64* %20
%22 = mul nsw i64 %21, %19
%23 = add nsw i64 %22, %16
%24 = ashr i64 %23, 15
%25 = add nsw i64 %24, %10
%26 = load i16, i16* %9
%27 = sext i16 %26 to i64
%28 = mul nsw i64 %15, %27
%29 = getelementptr inbounds i16, i16* %9, i64 1
%30 = load i16, i16* %29
%31 = sext i16 %30 to i64
%32 = mul nsw i64 %21, %31
%33 = add nsw i64 %32, %28
%34 = ashr i64 %33, 15
%35 = add nsw i64 %34, %25
store i64 %15, i64* %20
store i64 %25, i64* %11
%36 = getelementptr inbounds i16, i16* %9, i64 4
%37 = getelementptr inbounds i64, i64* %11, i64 2
%38 = add nuw nsw i64 %8, 1
%39 = icmp eq i64 %38, 50
br i1 %39, label %40, label %7
40: ; preds = %7
store i64 %35, i64* %2
ret void
}