double lmafir(double x, double *c, const int m, double *d, const int m1,
              const int m2) {
  int i;
  for (i = m - 1; i >= 1; i--)
    d[i] = d[i - 1];
  d[0] = x;
  for (x = 0.0, i = m1; i <= m2; i++)
    x += c[i] * d[i - 1];
  return (x);
}


x86 assembly (clang, -O0):
<lmafir>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %ecx,-0x24(%rbp)
mov    %r8d,-0x28(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x2c(%rbp)
cmpl   $0x1,-0x2c(%rbp)
jl     115b <lmafir+0x5b>
mov    -0x20(%rbp),%rax
mov    -0x2c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x2c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x2c(%rbp)
jmp    1124 <lmafir+0x24>
movsd  -0x8(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,(%rax)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
mov    -0x24(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x28(%rbp),%eax
jg     11c1 <lmafir+0xc1>
mov    -0x10(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x2c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x8(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1176 <lmafir+0x76>
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<lmafir>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
cmp    $0x2,%esi
jl     1164 <lmafir+0x64>
mov    $0xfffffffe,%r9d
mov    %esi,%ebp
xor    %r15d,%r15d
mov    %rbp,%rax
sub    $0x2,%rax
mov    $0x0,%r10d
cmovae %rax,%r10
add    $0x1,%r10
cmp    $0x4,%r10
jae    11ff <lmafir+0xff>
add    %rbp,%r9
add    $0xffffffffffffffff,%rbp
xchg   %ax,%ax
mov    %r9d,%eax
movsd  (%rdx,%rax,8),%xmm1
mov    %ebp,%eax
movsd  %xmm1,(%rdx,%rax,8)
add    $0xffffffffffffffff,%r9
lea    -0x1(%rbp),%rax
add    $0x1,%rbp
cmp    $0x2,%rbp
mov    %rax,%rbp
ja     1140 <lmafir+0x40>
movsd  %xmm0,(%rdx)
xorpd  %xmm0,%xmm0
mov    %r8d,%esi
sub    %ecx,%esi
jl     11f6 <lmafir+0xf6>
movslq %ecx,%rax
add    $0x1,%r8d
mov    %r8d,%ebx
sub    %ecx,%ebx
xorpd  %xmm0,%xmm0
and    $0x3,%ebx
je     11a8 <lmafir+0xa8>
nopl   0x0(%rax)
movsd  (%rdi,%rax,8),%xmm1
mulsd  -0x8(%rdx,%rax,8),%xmm1
addsd  %xmm1,%xmm0
add    $0x1,%rax
add    $0xffffffff,%ebx
jne    1190 <lmafir+0x90>
cmp    $0x3,%esi
jb     11f6 <lmafir+0xf6>
mov    %r8d,%ecx
movsd  (%rdi,%rax,8),%xmm1
movsd  0x8(%rdi,%rax,8),%xmm2
mulsd  -0x8(%rdx,%rax,8),%xmm1
mulsd  (%rdx,%rax,8),%xmm2
addsd  %xmm0,%xmm1
movsd  0x10(%rdi,%rax,8),%xmm3
mulsd  0x8(%rdx,%rax,8),%xmm3
addsd  %xmm1,%xmm2
movsd  0x18(%rdi,%rax,8),%xmm0
mulsd  0x10(%rdx,%rax,8),%xmm0
addsd  %xmm2,%xmm3
addsd  %xmm3,%xmm0
add    $0x4,%rax
cmp    %eax,%ecx
jne    11b0 <lmafir+0xb0>
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret
mov    %ebp,%ebx
sub    $0x2,%ebx
cmovb  %r15d,%ebx
mov    %rbp,%rax
sub    $0x2,%rax
cmovae %rax,%r15
lea    -0x1(%rsi),%r11d
cmp    %ebx,%r11d
jb     1137 <lmafir+0x37>
mov    %r15,%r14
shr    $0x20,%r14
jne    1137 <lmafir+0x37>
add    $0xfffffffe,%esi
cmp    %ebx,%esi
jb     1137 <lmafir+0x37>
test   %r14,%r14
jne    1137 <lmafir+0x37>
lea    (%rdx,%r11,8),%rax
shl    $0x3,%r15
mov    %rax,%rbx
sub    %r15,%rbx
cmp    %rax,%rbx
ja     1137 <lmafir+0x37>
xor    %eax,%eax
test   %al,%al
jne    1137 <lmafir+0x37>
lea    (%rdx,%rsi,8),%rax
mov    %rax,%rbx
sub    %r15,%rbx
cmp    %rax,%rbx
ja     1137 <lmafir+0x37>
xor    %eax,%eax
test   %al,%al
jne    1137 <lmafir+0x37>
cmp    $0x2,%rbp
mov    $0x2,%ebx
cmovb  %rbp,%rbx
lea    (%rbx,%r11,1),%rax
sub    %rbp,%rax
lea    (%rdx,%rax,8),%r14
lea    (%rdx,%rsi,8),%rax
add    $0x8,%rax
cmp    %rax,%r14
jae    12bf <lmafir+0x1bf>
lea    (%rdx,%r11,8),%rax
add    $0x8,%rax
add    %rsi,%rbx
sub    %rbp,%rbx
lea    (%rdx,%rbx,8),%rsi
cmp    %rax,%rsi
jb     1137 <lmafir+0x37>
mov    %r10,%r11
and    $0xfffffffffffffffc,%r11
lea    -0x4(%r11),%rax
mov    %rax,%r14
shr    $0x2,%r14
add    $0x1,%r14
test   %rax,%rax
je     1373 <lmafir+0x273>
mov    %r14,%r12
and    $0xfffffffffffffffe,%r12
lea    (%r9,%rbp,1),%rbx
add    $0xfffffffffffffffc,%rbx
xor    %r15d,%r15d
lea    0x5(%rbx),%eax
lea    0x4(%rbx),%esi
movups -0x18(%rdx,%rsi,8),%xmm1
movups -0x8(%rdx,%rsi,8),%xmm2
movups %xmm2,-0x8(%rdx,%rax,8)
movups %xmm1,-0x18(%rdx,%rax,8)
mov    %ebx,%eax
lea    0x1(%rbx),%esi
movupd -0x18(%rdx,%rax,8),%xmm1
movupd -0x8(%rdx,%rax,8),%xmm2
movupd %xmm2,-0x8(%rdx,%rsi,8)
movupd %xmm1,-0x18(%rdx,%rsi,8)
add    $0x8,%r15
add    $0xfffffffffffffff8,%rbx
add    $0xfffffffffffffffe,%r12
jne    12f0 <lmafir+0x1f0>
test   $0x1,%r14b
je     1362 <lmafir+0x262>
mov    %ebp,%eax
sub    %r15d,%eax
lea    (%r9,%rax,1),%esi
add    %r9d,%eax
add    $0x1,%eax
movupd -0x18(%rdx,%rsi,8),%xmm1
movupd -0x8(%rdx,%rsi,8),%xmm2
movupd %xmm2,-0x8(%rdx,%rax,8)
movupd %xmm1,-0x18(%rdx,%rax,8)
cmp    %r11,%r10
je     1164 <lmafir+0x64>
sub    %r11,%rbp
jmp    1137 <lmafir+0x37>
xor    %r15d,%r15d
test   $0x1,%r14b
jne    133b <lmafir+0x23b>
jmp    1362 <lmafir+0x262>

LLVM IR (-O0):
define double @lmafir(double %0, double* %1, i32 %2, double* %3, i32 %4, i32 %5) {
%7 = alloca double
%8 = alloca double*
%9 = alloca i32
%10 = alloca double*
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
store double %0, double* %7
store double* %1, double** %8
store i32 %2, i32* %9
store double* %3, double** %10
store i32 %4, i32* %11
store i32 %5, i32* %12
%14 = load i32, i32* %9
%15 = sub nsw i32 %14, 1
store i32 %15, i32* %13
br label %16
16: ; preds = %30, %6
%17 = load i32, i32* %13
%18 = icmp sge i32 %17, 1
br i1 %18, label %19, label %33
19: ; preds = %16
%20 = load double*, double** %10
%21 = load i32, i32* %13
%22 = sub nsw i32 %21, 1
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds double, double* %20, i64 %23
%25 = load double, double* %24
%26 = load double*, double** %10
%27 = load i32, i32* %13
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds double, double* %26, i64 %28
store double %25, double* %29
br label %30
30: ; preds = %19
%31 = load i32, i32* %13
%32 = add nsw i32 %31, -1
store i32 %32, i32* %13
br label %16
33: ; preds = %16
%34 = load double, double* %7
%35 = load double*, double** %10
%36 = getelementptr inbounds double, double* %35, i64 0
store double %34, double* %36
store double 0.000000e+00, double* %7
%37 = load i32, i32* %11
store i32 %37, i32* %13
br label %38
38: ; preds = %56, %33
%39 = load i32, i32* %13
%40 = load i32, i32* %12
%41 = icmp sle i32 %39, %40
br i1 %41, label %42, label %59
42: ; preds = %38
%43 = load double*, double** %8
%44 = load i32, i32* %13
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds double, double* %43, i64 %45
%47 = load double, double* %46
%48 = load double*, double** %10
%49 = load i32, i32* %13
%50 = sub nsw i32 %49, 1
%51 = sext i32 %50 to i64
%52 = getelementptr inbounds double, double* %48, i64 %51
%53 = load double, double* %52
%54 = load double, double* %7
%55 = call double @llvm.fmuladd.f64(double %47, double %53, double %54)
store double %55, double* %7
br label %56
56: ; preds = %42
%57 = load i32, i32* %13
%58 = add nsw i32 %57, 1
store i32 %58, i32* %13
br label %38
59: ; preds = %38
%60 = load double, double* %7
ret double %60
}

LLVM IR (-O2):
define double @lmafir(double %0, double* nocapture %1, i32 %2, double* nocapture %3, i32 %4, i32 %5) {
%7 = icmp sgt i32 %2, 1
br i1 %7, label %8, label %161
8: ; preds = %6
%9 = zext i32 %2 to i64
%10 = add nuw nsw i64 %9, 1
%11 = call i64 @llvm.umin.i64(i64 %9, i64 2)
%12 = sub nsw i64 %10, %11
%13 = icmp ult i64 %12, 4
br i1 %13, label %149, label %14
14: ; preds = %8
%15 = call i64 @llvm.umin.i64(i64 %9, i64 2)
%16 = sub nsw i64 %9, %15
%17 = add i32 %2, -1
%18 = trunc i64 %16 to i32
%19 = icmp ult i32 %17, %18
%20 = icmp ugt i64 %16, 4294967295
%21 = or i1 %19, %20
%22 = add i32 %2, -2
%23 = trunc i64 %16 to i32
%24 = icmp ult i32 %22, %23
%25 = icmp ugt i64 %16, 4294967295
%26 = or i1 %24, %25
%27 = zext i32 %17 to i64
%28 = getelementptr double, double* %3, i64 %27
%29 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %16, i64 8)
%30 = extractvalue { i64, i1 } %29, 0
%31 = extractvalue { i64, i1 } %29, 1
%32 = bitcast double* %28 to i8*
%33 = sub i64 0, %30
%34 = getelementptr i8, i8* %32, i64 %33
%35 = icmp ugt i8* %34, %32
%36 = or i1 %35, %31
%37 = zext i32 %22 to i64
%38 = getelementptr double, double* %3, i64 %37
%39 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %16, i64 8)
%40 = extractvalue { i64, i1 } %39, 0
%41 = extractvalue { i64, i1 } %39, 1
%42 = bitcast double* %38 to i8*
%43 = sub i64 0, %40
%44 = getelementptr i8, i8* %42, i64 %43
%45 = icmp ugt i8* %44, %42
%46 = or i1 %45, %41
%47 = or i1 %21, %26
%48 = or i1 %47, %36
%49 = or i1 %48, %46
br i1 %49, label %149, label %50
50: ; preds = %14
%51 = call i64 @llvm.umin.i64(i64 %9, i64 2)
%52 = add i32 %2, -1
%53 = zext i32 %52 to i64
%54 = add nuw nsw i64 %51, %53
%55 = sub nsw i64 %54, %9
%56 = getelementptr double, double* %3, i64 %55
%57 = add nuw nsw i64 %53, 1
%58 = getelementptr double, double* %3, i64 %57
%59 = add i32 %2, -2
%60 = zext i32 %59 to i64
%61 = add nuw nsw i64 %51, %60
%62 = sub nsw i64 %61, %9
%63 = getelementptr double, double* %3, i64 %62
%64 = add nuw nsw i64 %60, 1
%65 = getelementptr double, double* %3, i64 %64
%66 = icmp ult double* %56, %65
%67 = icmp ult double* %63, %58
%68 = and i1 %66, %67
br i1 %68, label %149, label %69
69: ; preds = %50
%70 = and i64 %12, -4
%71 = sub nsw i64 %9, %70
%72 = add nsw i64 %70, -4
%73 = lshr exact i64 %72, 2
%74 = add nuw nsw i64 %73, 1
%75 = and i64 %74, 1
%76 = icmp eq i64 %72, 0
br i1 %76, label %124, label %77
77: ; preds = %69
%78 = and i64 %74, 9223372036854775806
br label %79
79: ; preds = %79, %77
%80 = phi i64 [ 0, %77 ], [ %121, %79 ]
%81 = phi i64 [ 0, %77 ], [ %122, %79 ]
%82 = sub i64 %9, %80
%83 = add i64 %82, 4294967295
%84 = add nuw i64 %82, 4294967294
%85 = and i64 %84, 4294967295
%86 = getelementptr inbounds double, double* %3, i64 %85
%87 = getelementptr inbounds double, double* %86, i64 -1
%88 = bitcast double* %87 to <2 x double>*
%89 = load <2 x double>, <2 x double>* %88
%90 = getelementptr inbounds double, double* %86, i64 -2
%91 = getelementptr inbounds double, double* %90, i64 -1
%92 = bitcast double* %91 to <2 x double>*
%93 = load <2 x double>, <2 x double>* %92
%94 = and i64 %83, 4294967295
%95 = getelementptr inbounds double, double* %3, i64 %94
%96 = getelementptr inbounds double, double* %95, i64 -1
%97 = bitcast double* %96 to <2 x double>*
store <2 x double> %89, <2 x double>* %97
%98 = getelementptr inbounds double, double* %95, i64 -2
%99 = getelementptr inbounds double, double* %98, i64 -1
%100 = bitcast double* %99 to <2 x double>*
store <2 x double> %93, <2 x double>* %100
%101 = or i64 %80, 4
%102 = sub i64 %9, %101
%103 = add i64 %102, 4294967295
%104 = add nuw i64 %102, 4294967294
%105 = and i64 %104, 4294967295
%106 = getelementptr inbounds double, double* %3, i64 %105
%107 = getelementptr inbounds double, double* %106, i64 -1
%108 = bitcast double* %107 to <2 x double>*
%109 = load <2 x double>, <2 x double>* %108
%110 = getelementptr inbounds double, double* %106, i64 -2
%111 = getelementptr inbounds double, double* %110, i64 -1
%112 = bitcast double* %111 to <2 x double>*
%113 = load <2 x double>, <2 x double>* %112
%114 = and i64 %103, 4294967295
%115 = getelementptr inbounds double, double* %3, i64 %114
%116 = getelementptr inbounds double, double* %115, i64 -1
%117 = bitcast double* %116 to <2 x double>*
store <2 x double> %109, <2 x double>* %117
%118 = getelementptr inbounds double, double* %115, i64 -2
%119 = getelementptr inbounds double, double* %118, i64 -1
%120 = bitcast double* %119 to <2 x double>*
store <2 x double> %113, <2 x double>* %120
%121 = add nuw i64 %80, 8
%122 = add i64 %81, 2
%123 = icmp eq i64 %122, %78
br i1 %123, label %124, label %79
124: ; preds = %79, %69
%125 = phi i64 [ 0, %69 ], [ %121, %79 ]
%126 = icmp eq i64 %75, 0
br i1 %126, label %147, label %127
127: ; preds = %124
%128 = sub i64 %9, %125
%129 = add i64 %128, 4294967295
%130 = add nuw i64 %128, 4294967294
%131 = and i64 %130, 4294967295
%132 = getelementptr inbounds double, double* %3, i64 %131
%133 = getelementptr inbounds double, double* %132, i64 -1
%134 = bitcast double* %133 to <2 x double>*
%135 = load <2 x double>, <2 x double>* %134
%136 = getelementptr inbounds double, double* %132, i64 -2
%137 = getelementptr inbounds double, double* %136, i64 -1
%138 = bitcast double* %137 to <2 x double>*
%139 = load <2 x double>, <2 x double>* %138
%140 = and i64 %129, 4294967295
%141 = getelementptr inbounds double, double* %3, i64 %140
%142 = getelementptr inbounds double, double* %141, i64 -1
%143 = bitcast double* %142 to <2 x double>*
store <2 x double> %135, <2 x double>* %143
%144 = getelementptr inbounds double, double* %141, i64 -2
%145 = getelementptr inbounds double, double* %144, i64 -1
%146 = bitcast double* %145 to <2 x double>*
store <2 x double> %139, <2 x double>* %146
br label %147
147: ; preds = %124, %127
%148 = icmp eq i64 %12, %70
br i1 %148, label %161, label %149
149: ; preds = %50, %14, %8, %147
%150 = phi i64 [ %9, %50 ], [ %9, %14 ], [ %9, %8 ], [ %71, %147 ]
br label %151
151: ; preds = %149, %151
%152 = phi i64 [ %153, %151 ], [ %150, %149 ]
%153 = add nsw i64 %152, -1
%154 = add nuw i64 %152, 4294967294
%155 = and i64 %154, 4294967295
%156 = getelementptr inbounds double, double* %3, i64 %155
%157 = load double, double* %156
%158 = and i64 %153, 4294967295
%159 = getelementptr inbounds double, double* %3, i64 %158
store double %157, double* %159
%160 = icmp ugt i64 %152, 2
br i1 %160, label %151, label %161
161: ; preds = %151, %147, %6
store double %0, double* %3
%162 = icmp slt i32 %5, %4
br i1 %162, label %218, label %163
163: ; preds = %161
%164 = sext i32 %4 to i64
%165 = add i32 %5, 1
%166 = sub i32 %165, %4
%167 = sub i32 %5, %4
%168 = and i32 %166, 3
%169 = icmp eq i32 %168, 0
br i1 %169, label %183, label %170
170: ; preds = %163, %170
%171 = phi i64 [ %180, %170 ], [ %164, %163 ]
%172 = phi double [ %179, %170 ], [ 0.000000e+00, %163 ]
%173 = phi i32 [ %181, %170 ], [ 0, %163 ]
%174 = getelementptr inbounds double, double* %1, i64 %171
%175 = load double, double* %174
%176 = add nsw i64 %171, -1
%177 = getelementptr inbounds double, double* %3, i64 %176
%178 = load double, double* %177
%179 = tail call double @llvm.fmuladd.f64(double %175, double %178, double %172)
%180 = add nsw i64 %171, 1
%181 = add i32 %173, 1
%182 = icmp eq i32 %181, %168
br i1 %182, label %183, label %170
183: ; preds = %170, %163
%184 = phi double [ undef, %163 ], [ %179, %170 ]
%185 = phi i64 [ %164, %163 ], [ %180, %170 ]
%186 = phi double [ 0.000000e+00, %163 ], [ %179, %170 ]
%187 = icmp ult i32 %167, 3
br i1 %187, label %218, label %188
188: ; preds = %183, %188
%189 = phi i64 [ %215, %188 ], [ %185, %183 ]
%190 = phi double [ %214, %188 ], [ %186, %183 ]
%191 = getelementptr inbounds double, double* %1, i64 %189
%192 = load double, double* %191
%193 = add nsw i64 %189, -1
%194 = getelementptr inbounds double, double* %3, i64 %193
%195 = load double, double* %194
%196 = tail call double @llvm.fmuladd.f64(double %192, double %195, double %190)
%197 = add nsw i64 %189, 1
%198 = getelementptr inbounds double, double* %1, i64 %197
%199 = load double, double* %198
%200 = getelementptr inbounds double, double* %3, i64 %189
%201 = load double, double* %200
%202 = tail call double @llvm.fmuladd.f64(double %199, double %201, double %196)
%203 = add nsw i64 %189, 2
%204 = getelementptr inbounds double, double* %1, i64 %203
%205 = load double, double* %204
%206 = getelementptr inbounds double, double* %3, i64 %197
%207 = load double, double* %206
%208 = tail call double @llvm.fmuladd.f64(double %205, double %207, double %202)
%209 = add nsw i64 %189, 3
%210 = getelementptr inbounds double, double* %1, i64 %209
%211 = load double, double* %210
%212 = getelementptr inbounds double, double* %3, i64 %203
%213 = load double, double* %212
%214 = tail call double @llvm.fmuladd.f64(double %211, double %213, double %208)
%215 = add nsw i64 %189, 4
%216 = trunc i64 %215 to i32
%217 = icmp eq i32 %165, %216
br i1 %217, label %218, label %188
218: ; preds = %183, %188, %161
%219 = phi double [ 0.000000e+00, %161 ], [ %184, %183 ], [ %214, %188 ]
ret double %219
}