double dfs(double x, double *a, int m, double *b, int n, double *buf,
           int *bufp) {
  double y = 0.0;
  int i, p;
  int max;
  n++;
  m++;
  (m < n) ? (max = n) : (max = m);
  x = x * a[0];
  for (i = 1; i < m; i++) {
    if ((p = *bufp + i) >= max)
      p -= max;
    x -= buf[p] * a[i];
  }
  buf[*bufp] = x;
  for (i = 0; i < n; i++) {
    if ((p = *bufp + i) >= max)
      p -= max;
    y += buf[p] * b[i];
  }
  if (--*bufp < 0)
    *bufp += max;
  return (y);
}


x86 assembly (clang, -O0):
<dfs>:
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    %r8,-0x30(%rbp)
mov    %r9,-0x38(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    1150 <dfs+0x50>
mov    -0x24(%rbp),%eax
mov    %eax,-0x4c(%rbp)
jmp    1156 <dfs+0x56>
mov    -0x14(%rbp),%eax
mov    %eax,-0x4c(%rbp)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mulsd  (%rax),%xmm0
movsd  %xmm0,-0x8(%rbp)
movl   $0x1,-0x44(%rbp)
mov    -0x44(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    11ec <dfs+0xec>
mov    -0x38(%rbp),%rax
mov    (%rax),%eax
add    -0x44(%rbp),%eax
mov    %eax,-0x48(%rbp)
cmp    -0x4c(%rbp),%eax
jl     119b <dfs+0x9b>
mov    -0x4c(%rbp),%ecx
mov    -0x48(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0x48(%rbp)
mov    -0x30(%rbp),%rax
movslq -0x48(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x44(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x8(%rbp),%xmm1
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
mov    -0x44(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x44(%rbp)
jmp    116f <dfs+0x6f>
movsd  -0x8(%rbp),%xmm0
mov    -0x30(%rbp),%rax
mov    -0x38(%rbp),%rcx
movslq (%rcx),%rcx
movsd  %xmm0,(%rax,%rcx,8)
movl   $0x0,-0x44(%rbp)
mov    -0x44(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    126e <dfs+0x16e>
mov    -0x38(%rbp),%rax
mov    (%rax),%eax
add    -0x44(%rbp),%eax
mov    %eax,-0x48(%rbp)
cmp    -0x4c(%rbp),%eax
jl     1234 <dfs+0x134>
mov    -0x4c(%rbp),%ecx
mov    -0x48(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0x48(%rbp)
mov    -0x30(%rbp),%rax
movslq -0x48(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x44(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x40(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x44(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x44(%rbp)
jmp    1208 <dfs+0x108>
mov    -0x38(%rbp),%rcx
mov    (%rcx),%eax
add    $0xffffffff,%eax
mov    %eax,(%rcx)
cmp    $0x0,%eax
jge    128d <dfs+0x18d>
mov    -0x4c(%rbp),%ecx
mov    -0x38(%rbp),%rax
add    (%rax),%ecx
mov    %ecx,(%rax)
movsd  -0x40(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<dfs>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
cmp    %ecx,%esi
mov    %esi,%r10d
cmovl  %ecx,%r10d
lea    0x1(%r10),%eax
mulsd  (%rdi),%xmm0
movslq (%r9),%r11
movslq %r10d,%r13
movslq %eax,%r15
test   %esi,%esi
jle    11ee <dfs+0xee>
mov    %esi,%r14d
cmp    $0x1,%esi
jne    113e <dfs+0x3e>
mov    $0x1,%esi
jmp    11c9 <dfs+0xc9>
lea    (%r8,%r11,8),%rax
mov    %r14d,%r12d
and    $0xfffffffe,%r12d
neg    %r12
mov    $0x1,%esi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
lea    (%r11,%rsi,1),%rbx
cmp    %r13,%rbx
mov    $0x0,%ebx
cmovg  %r15,%rbx
shl    $0x3,%rbx
mov    %rax,%rbp
sub    %rbx,%rbp
movsd  0x0(%rbp,%rsi,8),%xmm1
mulsd  (%rdi,%rsi,8),%xmm1
subsd  %xmm1,%xmm0
lea    (%r11,%rsi,1),%rbx
add    $0x1,%rbx
cmp    %r13,%rbx
mov    $0x0,%ebx
cmovg  %r15,%rbx
shl    $0x3,%rbx
mov    %rax,%rbp
sub    %rbx,%rbp
movsd  0x8(%rbp,%rsi,8),%xmm1
mulsd  0x8(%rdi,%rsi,8),%xmm1
subsd  %xmm1,%xmm0
lea    (%r12,%rsi,1),%rbx
add    $0x2,%rbx
add    $0x2,%rsi
cmp    $0x1,%rbx
jne    1160 <dfs+0x60>
test   $0x1,%r14b
je     11ee <dfs+0xee>
lea    (%rsi,%r11,1),%rax
xor    %ebx,%ebx
cmp    %r13,%rax
cmovg  %r15,%rbx
sub    %rbx,%rax
movsd  (%r8,%rax,8),%xmm1
mulsd  (%rdi,%rsi,8),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,(%r8,%r11,8)
test   %ecx,%ecx
js     1277 <dfs+0x177>
lea    0x1(%rcx),%esi
test   %ecx,%ecx
je     127d <dfs+0x17d>
mov    %esi,%eax
and    $0xfffffffe,%eax
lea    (%r8,%r11,8),%rbp
xorpd  %xmm0,%xmm0
xor    %ecx,%ecx
xchg   %ax,%ax
lea    (%r11,%rcx,1),%rbx
cmp    %r13,%rbx
mov    $0x0,%ebx
cmovg  %r15,%rbx
shl    $0x3,%rbx
mov    %rbp,%rdi
sub    %rbx,%rdi
movsd  (%rdi,%rcx,8),%xmm1
mulsd  (%rdx,%rcx,8),%xmm1
addsd  %xmm0,%xmm1
lea    (%r11,%rcx,1),%rdi
add    $0x1,%rdi
cmp    %r13,%rdi
mov    $0x0,%edi
cmovg  %r15,%rdi
shl    $0x3,%rdi
mov    %rbp,%rbx
sub    %rdi,%rbx
movsd  0x8(%rbx,%rcx,8),%xmm0
mulsd  0x8(%rdx,%rcx,8),%xmm0
addsd  %xmm1,%xmm0
add    $0x2,%rcx
cmp    %rcx,%rax
jne    1210 <dfs+0x110>
test   $0x1,%sil
jne    1289 <dfs+0x189>
jmp    12a8 <dfs+0x1a8>
xorpd  %xmm0,%xmm0
jmp    12a8 <dfs+0x1a8>
xorpd  %xmm0,%xmm0
xor    %ecx,%ecx
test   $0x1,%sil
je     12a8 <dfs+0x1a8>
lea    (%rcx,%r11,1),%rax
xor    %esi,%esi
cmp    %r13,%rax
cmovg  %r15,%rsi
sub    %rsi,%rax
movsd  (%r8,%rax,8),%xmm1
mulsd  (%rdx,%rcx,8),%xmm1
addsd  %xmm1,%xmm0
test   %r11d,%r11d
mov    $0xffffffff,%eax
cmovle %r10d,%eax
add    %r11d,%eax
mov    %eax,(%r9)
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define double @dfs(double %0, double* %1, i32 %2, double* %3, i32 %4, double* %5, i32* %6) {
%8 = alloca double
%9 = alloca double*
%10 = alloca i32
%11 = alloca double*
%12 = alloca i32
%13 = alloca double*
%14 = alloca i32*
%15 = alloca double
%16 = alloca i32
%17 = alloca i32
%18 = alloca i32
store double %0, double* %8
store double* %1, double** %9
store i32 %2, i32* %10
store double* %3, double** %11
store i32 %4, i32* %12
store double* %5, double** %13
store i32* %6, i32** %14
store double 0.000000e+00, double* %15
%19 = load i32, i32* %12
%20 = add nsw i32 %19, 1
store i32 %20, i32* %12
%21 = load i32, i32* %10
%22 = add nsw i32 %21, 1
store i32 %22, i32* %10
%23 = load i32, i32* %10
%24 = load i32, i32* %12
%25 = icmp slt i32 %23, %24
br i1 %25, label %26, label %28
26: ; preds = %7
%27 = load i32, i32* %12
store i32 %27, i32* %18
br label %30
28: ; preds = %7
%29 = load i32, i32* %10
store i32 %29, i32* %18
br label %30
30: ; preds = %28, %26
%31 = phi i32 [ %27, %26 ], [ %29, %28 ]
%32 = load double, double* %8
%33 = load double*, double** %9
%34 = getelementptr inbounds double, double* %33, i64 0
%35 = load double, double* %34
%36 = fmul double %32, %35
store double %36, double* %8
store i32 1, i32* %16
br label %37
37: ; preds = %66, %30
%38 = load i32, i32* %16
%39 = load i32, i32* %10
%40 = icmp slt i32 %38, %39
br i1 %40, label %41, label %69
41: ; preds = %37
%42 = load i32*, i32** %14
%43 = load i32, i32* %42
%44 = load i32, i32* %16
%45 = add nsw i32 %43, %44
store i32 %45, i32* %17
%46 = load i32, i32* %18
%47 = icmp sge i32 %45, %46
br i1 %47, label %48, label %52
48: ; preds = %41
%49 = load i32, i32* %18
%50 = load i32, i32* %17
%51 = sub nsw i32 %50, %49
store i32 %51, i32* %17
br label %52
52: ; preds = %48, %41
%53 = load double*, double** %13
%54 = load i32, i32* %17
%55 = sext i32 %54 to i64
%56 = getelementptr inbounds double, double* %53, i64 %55
%57 = load double, double* %56
%58 = load double*, double** %9
%59 = load i32, i32* %16
%60 = sext i32 %59 to i64
%61 = getelementptr inbounds double, double* %58, i64 %60
%62 = load double, double* %61
%63 = load double, double* %8
%64 = fneg double %57
%65 = call double @llvm.fmuladd.f64(double %64, double %62, double %63)
store double %65, double* %8
br label %66
66: ; preds = %52
%67 = load i32, i32* %16
%68 = add nsw i32 %67, 1
store i32 %68, i32* %16
br label %37
69: ; preds = %37
%70 = load double, double* %8
%71 = load double*, double** %13
%72 = load i32*, i32** %14
%73 = load i32, i32* %72
%74 = sext i32 %73 to i64
%75 = getelementptr inbounds double, double* %71, i64 %74
store double %70, double* %75
store i32 0, i32* %16
br label %76
76: ; preds = %104, %69
%77 = load i32, i32* %16
%78 = load i32, i32* %12
%79 = icmp slt i32 %77, %78
br i1 %79, label %80, label %107
80: ; preds = %76
%81 = load i32*, i32** %14
%82 = load i32, i32* %81
%83 = load i32, i32* %16
%84 = add nsw i32 %82, %83
store i32 %84, i32* %17
%85 = load i32, i32* %18
%86 = icmp sge i32 %84, %85
br i1 %86, label %87, label %91
87: ; preds = %80
%88 = load i32, i32* %18
%89 = load i32, i32* %17
%90 = sub nsw i32 %89, %88
store i32 %90, i32* %17
br label %91
91: ; preds = %87, %80
%92 = load double*, double** %13
%93 = load i32, i32* %17
%94 = sext i32 %93 to i64
%95 = getelementptr inbounds double, double* %92, i64 %94
%96 = load double, double* %95
%97 = load double*, double** %11
%98 = load i32, i32* %16
%99 = sext i32 %98 to i64
%100 = getelementptr inbounds double, double* %97, i64 %99
%101 = load double, double* %100
%102 = load double, double* %15
%103 = call double @llvm.fmuladd.f64(double %96, double %101, double %102)
store double %103, double* %15
br label %104
104: ; preds = %91
%105 = load i32, i32* %16
%106 = add nsw i32 %105, 1
store i32 %106, i32* %16
br label %76
107: ; preds = %76
%108 = load i32*, i32** %14
%109 = load i32, i32* %108
%110 = add nsw i32 %109, -1
store i32 %110, i32* %108
%111 = icmp slt i32 %110, 0
br i1 %111, label %112, label %117
112: ; preds = %107
%113 = load i32, i32* %18
%114 = load i32*, i32** %14
%115 = load i32, i32* %114
%116 = add nsw i32 %115, %113
store i32 %116, i32* %114
br label %117
117: ; preds = %112, %107
%118 = load double, double* %15
ret double %118
}

LLVM IR (-O2):
define double @dfs(double %0, double* nocapture %1, i32 %2, double* nocapture %3, i32 %4, double* nocapture %5, i32* nocapture %6) {
%8 = icmp slt i32 %2, %4
%9 = select i1 %8, i32 %4, i32 %2
%10 = add nsw i32 %9, 1
%11 = load double, double* %1
%12 = fmul double %11, %0
%13 = icmp slt i32 %2, 1
%14 = load i32, i32* %6
%15 = sext i32 %14 to i64
br i1 %13, label %68, label %16
16: ; preds = %7
%17 = sext i32 %9 to i64
%18 = sext i32 %10 to i64
%19 = zext i32 %2 to i64
%20 = and i64 %19, 1
%21 = icmp eq i32 %2, 1
br i1 %21, label %52, label %22
22: ; preds = %16
%23 = and i64 %19, 4294967294
br label %24
24: ; preds = %24, %22
%25 = phi i64 [ 1, %22 ], [ %49, %24 ]
%26 = phi double [ %12, %22 ], [ %48, %24 ]
%27 = phi i64 [ 0, %22 ], [ %50, %24 ]
%28 = add nsw i64 %25, %15
%29 = icmp sgt i64 %28, %17
%30 = select i1 %29, i64 %18, i64 0
%31 = sub nsw i64 %28, %30
%32 = getelementptr inbounds double, double* %5, i64 %31
%33 = load double, double* %32
%34 = getelementptr inbounds double, double* %1, i64 %25
%35 = load double, double* %34
%36 = fneg double %33
%37 = tail call double @llvm.fmuladd.f64(double %36, double %35, double %26)
%38 = add nuw nsw i64 %25, 1
%39 = add nsw i64 %38, %15
%40 = icmp sgt i64 %39, %17
%41 = select i1 %40, i64 %18, i64 0
%42 = sub nsw i64 %39, %41
%43 = getelementptr inbounds double, double* %5, i64 %42
%44 = load double, double* %43
%45 = getelementptr inbounds double, double* %1, i64 %38
%46 = load double, double* %45
%47 = fneg double %44
%48 = tail call double @llvm.fmuladd.f64(double %47, double %46, double %37)
%49 = add nuw nsw i64 %25, 2
%50 = add i64 %27, 2
%51 = icmp eq i64 %50, %23
br i1 %51, label %52, label %24
52: ; preds = %24, %16
%53 = phi double [ undef, %16 ], [ %48, %24 ]
%54 = phi i64 [ 1, %16 ], [ %49, %24 ]
%55 = phi double [ %12, %16 ], [ %48, %24 ]
%56 = icmp eq i64 %20, 0
br i1 %56, label %68, label %57
57: ; preds = %52
%58 = add nsw i64 %54, %15
%59 = icmp sgt i64 %58, %17
%60 = select i1 %59, i64 %18, i64 0
%61 = sub nsw i64 %58, %60
%62 = getelementptr inbounds double, double* %5, i64 %61
%63 = load double, double* %62
%64 = getelementptr inbounds double, double* %1, i64 %54
%65 = load double, double* %64
%66 = fneg double %63
%67 = tail call double @llvm.fmuladd.f64(double %66, double %65, double %55)
br label %68
68: ; preds = %57, %52, %7
%69 = phi double [ %12, %7 ], [ %53, %52 ], [ %67, %57 ]
%70 = getelementptr inbounds double, double* %5, i64 %15
store double %69, double* %70
%71 = icmp slt i32 %4, 0
br i1 %71, label %122, label %72
72: ; preds = %68
%73 = sext i32 %9 to i64
%74 = add nuw i32 %4, 1
%75 = zext i32 %74 to i64
%76 = sext i32 %10 to i64
%77 = and i64 %75, 1
%78 = icmp eq i32 %4, 0
br i1 %78, label %107, label %79
79: ; preds = %72
%80 = and i64 %75, 4294967294
br label %81
81: ; preds = %81, %79
%82 = phi i64 [ 0, %79 ], [ %104, %81 ]
%83 = phi double [ 0.000000e+00, %79 ], [ %103, %81 ]
%84 = phi i64 [ 0, %79 ], [ %105, %81 ]
%85 = add nsw i64 %82, %15
%86 = icmp sgt i64 %85, %73
%87 = select i1 %86, i64 %76, i64 0
%88 = sub nsw i64 %85, %87
%89 = getelementptr inbounds double, double* %5, i64 %88
%90 = load double, double* %89
%91 = getelementptr inbounds double, double* %3, i64 %82
%92 = load double, double* %91
%93 = tail call double @llvm.fmuladd.f64(double %90, double %92, double %83)
%94 = or i64 %82, 1
%95 = add nsw i64 %94, %15
%96 = icmp sgt i64 %95, %73
%97 = select i1 %96, i64 %76, i64 0
%98 = sub nsw i64 %95, %97
%99 = getelementptr inbounds double, double* %5, i64 %98
%100 = load double, double* %99
%101 = getelementptr inbounds double, double* %3, i64 %94
%102 = load double, double* %101
%103 = tail call double @llvm.fmuladd.f64(double %100, double %102, double %93)
%104 = add nuw nsw i64 %82, 2
%105 = add i64 %84, 2
%106 = icmp eq i64 %105, %80
br i1 %106, label %107, label %81
107: ; preds = %81, %72
%108 = phi double [ undef, %72 ], [ %103, %81 ]
%109 = phi i64 [ 0, %72 ], [ %104, %81 ]
%110 = phi double [ 0.000000e+00, %72 ], [ %103, %81 ]
%111 = icmp eq i64 %77, 0
br i1 %111, label %122, label %112
112: ; preds = %107
%113 = add nsw i64 %109, %15
%114 = icmp sgt i64 %113, %73
%115 = select i1 %114, i64 %76, i64 0
%116 = sub nsw i64 %113, %115
%117 = getelementptr inbounds double, double* %5, i64 %116
%118 = load double, double* %117
%119 = getelementptr inbounds double, double* %3, i64 %109
%120 = load double, double* %119
%121 = tail call double @llvm.fmuladd.f64(double %118, double %120, double %110)
br label %122
122: ; preds = %112, %107, %68
%123 = phi double [ 0.000000e+00, %68 ], [ %108, %107 ], [ %121, %112 ]
%124 = icmp slt i32 %14, 1
%125 = select i1 %124, i32 %9, i32 -1
%126 = add i32 %125, %14
store i32 %126, i32* %6
ret double %123
}