void iir_mem2(float *x, float *den, float *y, int N, int ord, float *mem) {
  int i, j;
  for (i = 0; i < N; i++) {
    y[i] = x[i] + mem[0];
    for (j = 0; j < ord - 1; j++) {
      mem[j] = mem[j + 1] - den[j + 1] * y[i];
    }
    mem[ord - 1] = -den[ord] * y[i];
  }
}


x86 assembly (clang, -O0):
<iir_mem2>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    %r8d,-0x20(%rbp)
mov    %r9,-0x28(%rbp)
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1210 <iir_mem2+0x110>
mov    -0x8(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x28(%rbp),%rax
addss  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
mov    -0x20(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    11c9 <iir_mem2+0xc9>
mov    -0x28(%rbp),%rax
mov    -0x30(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x30(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x28(%rbp),%rax
movslq -0x30(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    1157 <iir_mem2+0x57>
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mulss  (%rax,%rcx,4),%xmm0
mov    -0x28(%rbp),%rax
mov    -0x20(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1122 <iir_mem2+0x22>
pop    %rbp
ret

x86 assembly (clang, -O2):
<iir_mem2>:
push   %r15
push   %r14
push   %r12
push   %rbx
test   %ecx,%ecx
jle    11f0 <iir_mem2+0xf0>
lea    -0x1(%r8),%r15d
movslq %r8d,%r10
movslq %r15d,%r11
mov    %ecx,%r14d
mov    %r15d,%r12d
and    $0xfffffffe,%r12d
xor    %ecx,%ecx
movaps 0xed4(%rip),%xmm0
jmp    1150 <iir_mem2+0x50>
xchg   %ax,%ax
movss  (%rsi,%r10,4),%xmm2
xorps  %xmm0,%xmm2
mulss  %xmm1,%xmm2
movss  %xmm2,(%r9,%r11,4)
add    $0x1,%rcx
cmp    %r14,%rcx
je     11f0 <iir_mem2+0xf0>
movss  (%rdi,%rcx,4),%xmm1
addss  (%r9),%xmm1
movss  %xmm1,(%rdx,%rcx,4)
cmp    $0x2,%r8d
jl     1130 <iir_mem2+0x30>
cmp    $0x1,%r15d
jne    1170 <iir_mem2+0x70>
xor    %ebx,%ebx
jmp    11c5 <iir_mem2+0xc5>
nop
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mulss  0x4(%rsi,%rax,4),%xmm1
movss  0x4(%r9,%rax,4),%xmm2
subss  %xmm1,%xmm2
movss  0x8(%r9,%rax,4),%xmm1
movss  %xmm2,(%r9,%rax,4)
lea    0x2(%rax),%rbx
movss  0x8(%rsi,%rax,4),%xmm2
mulss  (%rdx,%rcx,4),%xmm2
subss  %xmm2,%xmm1
movss  %xmm1,0x4(%r9,%rax,4)
movss  (%rdx,%rcx,4),%xmm1
mov    %rbx,%rax
cmp    %rbx,%r12
jne    1180 <iir_mem2+0x80>
test   $0x1,%r15b
je     1130 <iir_mem2+0x30>
mulss  0x4(%rsi,%rbx,4),%xmm1
movss  0x4(%r9,%rbx,4),%xmm2
subss  %xmm1,%xmm2
movss  %xmm2,(%r9,%rbx,4)
movss  (%rdx,%rcx,4),%xmm1
jmp    1130 <iir_mem2+0x30>
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

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

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