double amotry(double p[3][2], double *y, double *psum, double (*funk)(double[]),
              int ihi, double fac) {
  double fac1, fac2, ytry, ptry[2];
  fac1 = 0.5 * (1.0 - fac);
  fac2 = fac1 - fac;
  ptry[0] = psum[0] * fac1 - p[ihi][0] * fac2;
  ptry[1] = psum[1] * fac1 - p[ihi][1] * fac2;
  ytry = (*funk)(ptry);
  if (ytry < y[ihi]) {
    y[ihi] = ytry;
    psum[0] += ptry[0] - p[ihi][0];
    p[ihi][0] = ptry[0];
    psum[1] += ptry[1] - p[ihi][1];
    p[ihi][1] = ptry[1];
  }
  return ytry;
}


x86 assembly (clang, -O0):
<amotry>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8d,-0x24(%rbp)
movsd  %xmm0,-0x30(%rbp)
movsd  0xedf(%rip),%xmm1
subsd  -0x30(%rbp),%xmm1
movsd  0xeca(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
movsd  -0x38(%rbp),%xmm2
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
shl    $0x4,%rcx
add    %rcx,%rax
movsd  (%rax),%xmm1
mulsd  -0x40(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  -0x38(%rbp),%xmm2
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
shl    $0x4,%rcx
add    %rcx,%rax
movsd  0x8(%rax),%xmm1
mulsd  -0x40(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x20(%rbp),%rax
lea    -0x60(%rbp),%rdi
call   *%rax
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
jbe    129b <amotry+0x19b>
movsd  -0x48(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x60(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
shl    $0x4,%rcx
add    %rcx,%rax
subsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
addsd  (%rax),%xmm0
movsd  %xmm0,(%rax)
movsd  -0x60(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
shl    $0x4,%rcx
add    %rcx,%rax
movsd  %xmm0,(%rax)
movsd  -0x58(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
shl    $0x4,%rcx
add    %rcx,%rax
subsd  0x8(%rax),%xmm0
mov    -0x18(%rbp),%rax
addsd  0x8(%rax),%xmm0
movsd  %xmm0,0x8(%rax)
movsd  -0x58(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
shl    $0x4,%rcx
add    %rcx,%rax
movsd  %xmm0,0x8(%rax)
movsd  -0x48(%rbp),%xmm0
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<amotry>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x10,%rsp
movsd  0xeeb(%rip),%xmm1
subsd  %xmm0,%xmm1
mulsd  0xee7(%rip),%xmm1
mov    %rdx,%r12
mov    %rsi,%r15
mov    %rdi,%r14
movapd %xmm1,%xmm2
subsd  %xmm0,%xmm2
movslq %r8d,%r13
mov    %r13,%rbx
shl    $0x4,%rbx
movupd (%rdx),%xmm0
movupd (%rdi,%rbx,1),%xmm3
unpcklpd %xmm2,%xmm2
mulpd  %xmm3,%xmm2
unpcklpd %xmm1,%xmm1
mulpd  %xmm0,%xmm1
subpd  %xmm2,%xmm1
movapd %xmm1,(%rsp)
mov    %rsp,%rdi
call   *%rcx
movsd  (%r15,%r13,8),%xmm1
ucomisd %xmm0,%xmm1
jbe    11bb <amotry+0xbb>
lea    (%r14,%rbx,1),%rax
movsd  %xmm0,(%r15,%r13,8)
movsd  (%rsp),%xmm1
movapd %xmm1,%xmm2
subsd  (%rax),%xmm2
lea    0x8(%r14,%rbx,1),%rcx
addsd  (%r12),%xmm2
movsd  %xmm2,(%r12)
movsd  %xmm1,(%rax)
movsd  0x8(%rsp),%xmm1
movapd %xmm1,%xmm2
subsd  (%rcx),%xmm2
addsd  0x8(%r12),%xmm2
movsd  %xmm2,0x8(%r12)
movsd  %xmm1,(%rcx)
add    $0x10,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
ret

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

LLVM IR (-O2):
define double @amotry([2 x double]* nocapture %0, double* nocapture %1, double* nocapture %2, double (double*)* nocapture %3, i32 %4, double %5) {
%7 = alloca <2 x double>
%8 = bitcast <2 x double>* %7 to i8*
%9 = fsub double 1.000000e+00, %5
%10 = fmul double %9, 5.000000e-01
%11 = fsub double %10, %5
%12 = sext i32 %4 to i64
%13 = getelementptr inbounds [2 x double], [2 x double]* %0, i64 %12, i64 0
%14 = getelementptr inbounds <2 x double>, <2 x double>* %7, i64 0, i64 0
%15 = getelementptr inbounds double, double* %2, i64 1
%16 = bitcast double* %2 to <2 x double>*
%17 = load <2 x double>, <2 x double>* %16
%18 = getelementptr inbounds [2 x double], [2 x double]* %0, i64 %12, i64 1
%19 = bitcast double* %13 to <2 x double>*
%20 = load <2 x double>, <2 x double>* %19
%21 = fneg <2 x double> %20
%22 = insertelement <2 x double> poison, double %11, i64 0
%23 = shufflevector <2 x double> %22, <2 x double> poison, <2 x i32> zeroinitializer
%24 = fmul <2 x double> %23, %21
%25 = insertelement <2 x double> poison, double %10, i64 0
%26 = shufflevector <2 x double> %25, <2 x double> poison, <2 x i32> zeroinitializer
%27 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %17, <2 x double> %26, <2 x double> %24)
store <2 x double> %27, <2 x double>* %7
%28 = call double %3(double* %14)
%29 = getelementptr inbounds double, double* %1, i64 %12
%30 = load double, double* %29
%31 = fcmp olt double %28, %30
br i1 %31, label %32, label %44
32: ; preds = %6
%33 = getelementptr inbounds <2 x double>, <2 x double>* %7, i64 0, i64 1
store double %28, double* %29
%34 = load double, double* %14
%35 = load double, double* %13
%36 = fsub double %34, %35
%37 = load double, double* %2
%38 = fadd double %37, %36
store double %38, double* %2
store double %34, double* %13
%39 = load double, double* %33
%40 = load double, double* %18
%41 = fsub double %39, %40
%42 = load double, double* %15
%43 = fadd double %42, %41
store double %43, double* %15
store double %39, double* %18
br label %44
44: ; preds = %32, %6
ret double %28
}