double max_dp(double *p, int n, int *idx) {
  double max = *p++;
  int ri = 0;
  int i;
  for (i = 1; i < n; i++) {
    double t = *p++;
    if (t > max) {
      max = t;
      ri = i;
    }
  }
  if (idx)
    *idx = ri;
  return max;
}


x86 assembly (clang, -O0):
<max_dp>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x8(%rbp)
movsd  (%rax),%xmm0
movsd  %xmm0,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
movl   $0x1,-0x28(%rbp)
mov    -0x28(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    118c <max_dp+0x8c>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x8(%rbp)
movsd  (%rax),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
ucomisd -0x20(%rbp),%xmm0
jbe    1179 <max_dp+0x79>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x28(%rbp),%eax
mov    %eax,-0x24(%rbp)
jmp    117e <max_dp+0x7e>
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    1135 <max_dp+0x35>
cmpq   $0x0,-0x18(%rbp)
je     11a0 <max_dp+0xa0>
mov    -0x24(%rbp),%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
movsd  -0x20(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<max_dp>:
movsd  (%rdi),%xmm1
xor    %eax,%eax
cmp    $0x2,%esi
jl     1121 <max_dp+0x21>
lea    -0x1(%rsi),%r8d
lea    -0x2(%rsi),%eax
cmp    $0x3,%eax
jae    112a <max_dp+0x2a>
xor    %eax,%eax
mov    $0x1,%r10d
jmp    119a <max_dp+0x9a>
movapd %xmm1,%xmm0
jmp    11e2 <max_dp+0xe2>
mov    %r8d,%r9d
and    $0xfffffffc,%r9d
xor    %eax,%eax
mov    $0x1,%r10d
nopl   0x0(%rax)
movsd  0x8(%rdi),%xmm0
ucomisd %xmm1,%xmm0
movsd  0x10(%rdi),%xmm2
cmova  %r10d,%eax
maxsd  %xmm1,%xmm0
lea    0x1(%r10),%ecx
ucomisd %xmm0,%xmm2
maxsd  %xmm0,%xmm2
cmovbe %eax,%ecx
movsd  0x18(%rdi),%xmm0
lea    0x2(%r10),%eax
ucomisd %xmm2,%xmm0
maxsd  %xmm2,%xmm0
cmovbe %ecx,%eax
movsd  0x20(%rdi),%xmm1
add    $0x20,%rdi
ucomisd %xmm0,%xmm1
lea    0x3(%r10),%ecx
cmova  %ecx,%eax
maxsd  %xmm0,%xmm1
add    $0x4,%r10d
cmp    %r9d,%ecx
jne    1140 <max_dp+0x40>
movapd %xmm1,%xmm0
test   $0x3,%r8b
je     11e2 <max_dp+0xe2>
mov    %r10d,%r8d
add    $0xff,%sil
movzbl %sil,%r9d
and    $0x3,%r9d
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nop
movsd  0x8(%rdi,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
lea    (%r8,%rcx,1),%esi
cmova  %esi,%eax
maxsd  %xmm1,%xmm0
add    $0x1,%rcx
movapd %xmm0,%xmm1
cmp    %ecx,%r9d
jne    11c0 <max_dp+0xc0>
test   %rdx,%rdx
je     11e9 <max_dp+0xe9>
mov    %eax,(%rdx)
ret

LLVM IR (-O0):
define double @max_dp(double* %0, i32 %1, i32* %2) {
%4 = alloca double*
%5 = alloca i32
%6 = alloca i32*
%7 = alloca double
%8 = alloca i32
%9 = alloca i32
%10 = alloca double
store double* %0, double** %4
store i32 %1, i32* %5
store i32* %2, i32** %6
%11 = load double*, double** %4
%12 = getelementptr inbounds double, double* %11, i32 1
store double* %12, double** %4
%13 = load double, double* %11
store double %13, double* %7
store i32 0, i32* %8
store i32 1, i32* %9
br label %14
14: ; preds = %29, %3
%15 = load i32, i32* %9
%16 = load i32, i32* %5
%17 = icmp slt i32 %15, %16
br i1 %17, label %18, label %32
18: ; preds = %14
%19 = load double*, double** %4
%20 = getelementptr inbounds double, double* %19, i32 1
store double* %20, double** %4
%21 = load double, double* %19
store double %21, double* %10
%22 = load double, double* %10
%23 = load double, double* %7
%24 = fcmp ogt double %22, %23
br i1 %24, label %25, label %28
25: ; preds = %18
%26 = load double, double* %10
store double %26, double* %7
%27 = load i32, i32* %9
store i32 %27, i32* %8
br label %28
28: ; preds = %25, %18
br label %29
29: ; preds = %28
%30 = load i32, i32* %9
%31 = add nsw i32 %30, 1
store i32 %31, i32* %9
br label %14
32: ; preds = %14
%33 = load i32*, i32** %6
%34 = icmp ne i32* %33, null
br i1 %34, label %35, label %38
35: ; preds = %32
%36 = load i32, i32* %8
%37 = load i32*, i32** %6
store i32 %36, i32* %37
br label %38
38: ; preds = %35, %32
%39 = load double, double* %7
ret double %39
}

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