void ssbfgs(int n, double gamma, double sj[], double hjv[], double hjyj[],
            double yjsj, double yjhyj, double vsj, double vhyj,
            double hjp1v[]) {
  double beta, delta;
  int i;
  if (yjsj == 0.0) {
    delta = 0.0;
    beta = 0.0;
  } else {
    delta = (gamma * yjhyj / yjsj + 1.0) * vsj / yjsj - gamma * vhyj / yjsj;
    beta = -gamma * vsj / yjsj;
  }
  for (i = 0; i < n; i++)
    hjp1v[i] = gamma * hjv[i] + delta * sj[i] + beta * hjyj[i];
}


x86 assembly (clang, -O0):
<ssbfgs>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
movsd  %xmm0,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
movsd  %xmm1,-0x30(%rbp)
movsd  %xmm2,-0x38(%rbp)
movsd  %xmm3,-0x40(%rbp)
movsd  %xmm4,-0x48(%rbp)
mov    %r8,-0x50(%rbp)
movsd  -0x30(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    115d <ssbfgs+0x5d>
jp     115d <ssbfgs+0x5d>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x60(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x58(%rbp)
jmp    11c5 <ssbfgs+0xc5>
movsd  -0x10(%rbp),%xmm0
mulsd  -0x38(%rbp),%xmm0
divsd  -0x30(%rbp),%xmm0
movsd  0xe8c(%rip),%xmm1
addsd  %xmm1,%xmm0
mulsd  -0x40(%rbp),%xmm0
divsd  -0x30(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm1
mulsd  -0x48(%rbp),%xmm1
divsd  -0x30(%rbp),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  -0x40(%rbp),%xmm0
divsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movl   $0x0,-0x64(%rbp)
mov    -0x64(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    1239 <ssbfgs+0x139>
movsd  -0x10(%rbp),%xmm1
mov    -0x20(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x60(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x64(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x58(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x50(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    11cc <ssbfgs+0xcc>
pop    %rbp
ret

x86 assembly (clang, -O2):
<ssbfgs>:
push   %rbp
push   %r14
push   %rbx
xorpd  %xmm9,%xmm9
ucomisd %xmm9,%xmm1
xorpd  %xmm8,%xmm8
jne    1117 <ssbfgs+0x17>
jnp    116e <ssbfgs+0x6e>
mulsd  %xmm0,%xmm2
divsd  %xmm1,%xmm2
addsd  0xed9(%rip),%xmm2
unpcklpd %xmm0,%xmm2
movapd %xmm3,%xmm8
unpcklpd %xmm4,%xmm8
mulpd  %xmm2,%xmm8
movapd %xmm1,%xmm2
unpcklpd %xmm1,%xmm2
divpd  %xmm2,%xmm8
movapd %xmm8,%xmm2
unpckhpd %xmm8,%xmm2
subsd  %xmm2,%xmm8
movapd 0xeb1(%rip),%xmm9
xorpd  %xmm0,%xmm9
mulsd  %xmm3,%xmm9
divsd  %xmm1,%xmm9
test   %edi,%edi
jle    1323 <ssbfgs+0x223>
mov    %edi,%r9d
cmp    $0x4,%edi
jae    1185 <ssbfgs+0x85>
xor    %edi,%edi
jmp    1278 <ssbfgs+0x178>
lea    (%rdx,%r9,8),%rax
cmp    %r8,%rax
seta   %r14b
lea    (%r8,%r9,8),%rdi
cmp    %rdx,%rdi
seta   %bl
lea    (%rsi,%r9,8),%rax
cmp    %r8,%rax
seta   %al
lea    (%rcx,%r9,8),%rbp
cmp    %rsi,%rdi
seta   %r11b
cmp    %r8,%rbp
seta   %r10b
cmp    %rcx,%rdi
seta   %bpl
xor    %edi,%edi
test   %bl,%r14b
jne    1278 <ssbfgs+0x178>
and    %r11b,%al
jne    1278 <ssbfgs+0x178>
and    %bpl,%r10b
jne    1278 <ssbfgs+0x178>
mov    %r9d,%edi
and    $0xfffffffc,%edi
movapd %xmm8,%xmm1
unpcklpd %xmm8,%xmm1
movapd %xmm0,%xmm2
unpcklpd %xmm0,%xmm2
movapd %xmm9,%xmm3
unpcklpd %xmm9,%xmm3
lea    0x0(,%r9,8),%r10
and    $0xffffffffffffffe0,%r10
xor    %eax,%eax
nopw   0x0(%rax,%rax,1)
movupd (%rdx,%rax,1),%xmm4
movupd 0x10(%rdx,%rax,1),%xmm7
movupd (%rsi,%rax,1),%xmm5
movupd 0x10(%rsi,%rax,1),%xmm6
mulpd  %xmm1,%xmm5
mulpd  %xmm1,%xmm6
mulpd  %xmm2,%xmm4
addpd  %xmm5,%xmm4
mulpd  %xmm2,%xmm7
addpd  %xmm6,%xmm7
movupd (%rcx,%rax,1),%xmm5
movupd 0x10(%rcx,%rax,1),%xmm6
mulpd  %xmm3,%xmm5
addpd  %xmm4,%xmm5
mulpd  %xmm3,%xmm6
addpd  %xmm7,%xmm6
movupd %xmm5,(%r8,%rax,1)
movupd %xmm6,0x10(%r8,%rax,1)
add    $0x20,%rax
cmp    %rax,%r10
jne    1210 <ssbfgs+0x110>
cmp    %r9,%rdi
je     1323 <ssbfgs+0x223>
mov    %rdi,%rax
not    %rax
test   $0x1,%r9b
je     12b3 <ssbfgs+0x1b3>
movsd  (%rsi,%rdi,8),%xmm1
mulsd  %xmm8,%xmm1
movsd  (%rdx,%rdi,8),%xmm2
mulsd  %xmm0,%xmm2
addsd  %xmm1,%xmm2
movsd  (%rcx,%rdi,8),%xmm1
mulsd  %xmm9,%xmm1
addsd  %xmm2,%xmm1
movsd  %xmm1,(%r8,%rdi,8)
or     $0x1,%rdi
add    %r9,%rax
je     1323 <ssbfgs+0x223>
nopl   0x0(%rax,%rax,1)
movsd  (%rsi,%rdi,8),%xmm1
mulsd  %xmm8,%xmm1
movsd  (%rdx,%rdi,8),%xmm2
mulsd  %xmm0,%xmm2
addsd  %xmm1,%xmm2
movsd  (%rcx,%rdi,8),%xmm1
mulsd  %xmm9,%xmm1
addsd  %xmm2,%xmm1
movsd  %xmm1,(%r8,%rdi,8)
movsd  0x8(%rsi,%rdi,8),%xmm1
mulsd  %xmm8,%xmm1
movsd  0x8(%rdx,%rdi,8),%xmm2
mulsd  %xmm0,%xmm2
addsd  %xmm1,%xmm2
movsd  0x8(%rcx,%rdi,8),%xmm1
mulsd  %xmm9,%xmm1
addsd  %xmm2,%xmm1
movsd  %xmm1,0x8(%r8,%rdi,8)
add    $0x2,%rdi
cmp    %rdi,%r9
jne    12c0 <ssbfgs+0x1c0>
pop    %rbx
pop    %r14
pop    %rbp
ret

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

LLVM IR (-O2):
define void @ssbfgs(i32 %0, double %1, double* nocapture %2, double* nocapture %3, double* nocapture %4, double %5, double %6, double %7, double %8, double* nocapture writeonly %9) {
%11 = fcmp oeq double %5, 0.000000e+00
br i1 %11, label %30, label %12
12: ; preds = %10
%13 = fmul double %1, %6
%14 = fdiv double %13, %5
%15 = fadd double %14, 1.000000e+00
%16 = insertelement <2 x double> poison, double %1, i64 1
%17 = insertelement <2 x double> %16, double %15, i64 0
%18 = insertelement <2 x double> poison, double %7, i64 0
%19 = insertelement <2 x double> %18, double %8, i64 1
%20 = fmul <2 x double> %17, %19
%21 = insertelement <2 x double> poison, double %5, i64 0
%22 = shufflevector <2 x double> %21, <2 x double> poison, <2 x i32> zeroinitializer
%23 = fdiv <2 x double> %20, %22
%24 = shufflevector <2 x double> %23, <2 x double> poison, <2 x i32> <i32 1, i32 undef>
%25 = fsub <2 x double> %23, %24
%26 = extractelement <2 x double> %25, i64 0
%27 = fneg double %1
%28 = fmul double %27, %7
%29 = fdiv double %28, %5
br label %30
30: ; preds = %10, %12
%31 = phi double [ %29, %12 ], [ 0.000000e+00, %10 ]
%32 = phi double [ %26, %12 ], [ 0.000000e+00, %10 ]
%33 = icmp sgt i32 %0, 0
br i1 %33, label %34, label %147
34: ; preds = %30
%35 = zext i32 %0 to i64
%36 = icmp ult i32 %0, 4
br i1 %36, label %101, label %37
37: ; preds = %34
%38 = getelementptr double, double* %9, i64 %35
%39 = getelementptr double, double* %3, i64 %35
%40 = getelementptr double, double* %2, i64 %35
%41 = getelementptr double, double* %4, i64 %35
%42 = icmp ugt double* %39, %9
%43 = icmp ugt double* %38, %3
%44 = and i1 %42, %43
%45 = icmp ugt double* %40, %9
%46 = icmp ugt double* %38, %2
%47 = and i1 %45, %46
%48 = or i1 %44, %47
%49 = icmp ugt double* %41, %9
%50 = icmp ugt double* %38, %4
%51 = and i1 %49, %50
%52 = or i1 %48, %51
br i1 %52, label %101, label %53
53: ; preds = %37
%54 = and i64 %35, 4294967292
%55 = insertelement <2 x double> poison, double %32, i64 0
%56 = shufflevector <2 x double> %55, <2 x double> poison, <2 x i32> zeroinitializer
%57 = insertelement <2 x double> poison, double %32, i64 0
%58 = shufflevector <2 x double> %57, <2 x double> poison, <2 x i32> zeroinitializer
%59 = insertelement <2 x double> poison, double %1, i64 0
%60 = shufflevector <2 x double> %59, <2 x double> poison, <2 x i32> zeroinitializer
%61 = insertelement <2 x double> poison, double %1, i64 0
%62 = shufflevector <2 x double> %61, <2 x double> poison, <2 x i32> zeroinitializer
%63 = insertelement <2 x double> poison, double %31, i64 0
%64 = shufflevector <2 x double> %63, <2 x double> poison, <2 x i32> zeroinitializer
%65 = insertelement <2 x double> poison, double %31, i64 0
%66 = shufflevector <2 x double> %65, <2 x double> poison, <2 x i32> zeroinitializer
br label %67
67: ; preds = %67, %53
%68 = phi i64 [ 0, %53 ], [ %97, %67 ]
%69 = getelementptr inbounds double, double* %3, i64 %68
%70 = bitcast double* %69 to <2 x double>*
%71 = load <2 x double>, <2 x double>* %70
%72 = getelementptr inbounds double, double* %69, i64 2
%73 = bitcast double* %72 to <2 x double>*
%74 = load <2 x double>, <2 x double>* %73
%75 = getelementptr inbounds double, double* %2, i64 %68
%76 = bitcast double* %75 to <2 x double>*
%77 = load <2 x double>, <2 x double>* %76
%78 = getelementptr inbounds double, double* %75, i64 2
%79 = bitcast double* %78 to <2 x double>*
%80 = load <2 x double>, <2 x double>* %79
%81 = fmul <2 x double> %56, %77
%82 = fmul <2 x double> %58, %80
%83 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %60, <2 x double> %71, <2 x double> %81)
%84 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %62, <2 x double> %74, <2 x double> %82)
%85 = getelementptr inbounds double, double* %4, i64 %68
%86 = bitcast double* %85 to <2 x double>*
%87 = load <2 x double>, <2 x double>* %86
%88 = getelementptr inbounds double, double* %85, i64 2
%89 = bitcast double* %88 to <2 x double>*
%90 = load <2 x double>, <2 x double>* %89
%91 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %64, <2 x double> %87, <2 x double> %83)
%92 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %66, <2 x double> %90, <2 x double> %84)
%93 = getelementptr inbounds double, double* %9, i64 %68
%94 = bitcast double* %93 to <2 x double>*
store <2 x double> %91, <2 x double>* %94
%95 = getelementptr inbounds double, double* %93, i64 2
%96 = bitcast double* %95 to <2 x double>*
store <2 x double> %92, <2 x double>* %96
%97 = add nuw i64 %68, 4
%98 = icmp eq i64 %97, %54
br i1 %98, label %99, label %67
99: ; preds = %67
%100 = icmp eq i64 %54, %35
br i1 %100, label %147, label %101
101: ; preds = %37, %34, %99
%102 = phi i64 [ 0, %37 ], [ 0, %34 ], [ %54, %99 ]
%103 = xor i64 %102, -1
%104 = and i64 %35, 1
%105 = icmp eq i64 %104, 0
br i1 %105, label %118, label %106
106: ; preds = %101
%107 = getelementptr inbounds double, double* %3, i64 %102
%108 = load double, double* %107
%109 = getelementptr inbounds double, double* %2, i64 %102
%110 = load double, double* %109
%111 = fmul double %32, %110
%112 = tail call double @llvm.fmuladd.f64(double %1, double %108, double %111)
%113 = getelementptr inbounds double, double* %4, i64 %102
%114 = load double, double* %113
%115 = tail call double @llvm.fmuladd.f64(double %31, double %114, double %112)
%116 = getelementptr inbounds double, double* %9, i64 %102
store double %115, double* %116
%117 = or i64 %102, 1
br label %118
118: ; preds = %106, %101
%119 = phi i64 [ %102, %101 ], [ %117, %106 ]
%120 = sub nsw i64 0, %35
%121 = icmp eq i64 %103, %120
br i1 %121, label %147, label %122
122: ; preds = %118, %122
%123 = phi i64 [ %145, %122 ], [ %119, %118 ]
%124 = getelementptr inbounds double, double* %3, i64 %123
%125 = load double, double* %124
%126 = getelementptr inbounds double, double* %2, i64 %123
%127 = load double, double* %126
%128 = fmul double %32, %127
%129 = tail call double @llvm.fmuladd.f64(double %1, double %125, double %128)
%130 = getelementptr inbounds double, double* %4, i64 %123
%131 = load double, double* %130
%132 = tail call double @llvm.fmuladd.f64(double %31, double %131, double %129)
%133 = getelementptr inbounds double, double* %9, i64 %123
store double %132, double* %133
%134 = add nuw nsw i64 %123, 1
%135 = getelementptr inbounds double, double* %3, i64 %134
%136 = load double, double* %135
%137 = getelementptr inbounds double, double* %2, i64 %134
%138 = load double, double* %137
%139 = fmul double %32, %138
%140 = tail call double @llvm.fmuladd.f64(double %1, double %136, double %139)
%141 = getelementptr inbounds double, double* %4, i64 %134
%142 = load double, double* %141
%143 = tail call double @llvm.fmuladd.f64(double %31, double %142, double %140)
%144 = getelementptr inbounds double, double* %9, i64 %134
store double %143, double* %144
%145 = add nuw nsw i64 %123, 2
%146 = icmp eq i64 %145, %35
br i1 %146, label %147, label %122
147: ; preds = %118, %122, %99, %30
ret void
}