double ddot_(int n, double *dx, double *dy) {
  double dtemp = 0.0;
  int i, m;
  if (n <= 0) {
    return 0;
  }
  m = n % 5;
  if (m != 0) {
    for (i = 0; i < m; ++i) {
      dtemp += dx[i] * dy[i];
    }
    if (n < 5) {
      return dtemp;
    }
  }
  for (i = m; i < n; i += 5) {
    dtemp = dtemp + dx[i] * dy[i] + dx[i + 1] * dy[i + 1] +
            dx[i + 2] * dy[i + 2] + dx[i + 3] * dy[i + 3] +
            dx[i + 4] * dy[i + 4];
  }
  return dtemp;
}


x86 assembly (clang, -O0):
<ddot_>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0xc(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
cmpl   $0x0,-0xc(%rbp)
jg     112e <ddot_+0x2e>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12b7 <ddot_+0x1b7>
mov    -0xc(%rbp),%eax
mov    $0x5,%ecx
cltd
idiv   %ecx
mov    %edx,-0x30(%rbp)
cmpl   $0x0,-0x30(%rbp)
je     11b1 <ddot_+0xb1>
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x30(%rbp),%eax
jge    1193 <ddot_+0x93>
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x28(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    114d <ddot_+0x4d>
cmpl   $0x5,-0xc(%rbp)
jge    11ac <ddot_+0xac>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12b7 <ddot_+0x1b7>
jmp    11b1 <ddot_+0xb1>
mov    -0x30(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    12ad <ddot_+0x1ad>
movsd  -0x28(%rbp),%xmm1
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
mov    -0x2c(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x20(%rbp),%rax
mov    -0x2c(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x18(%rbp),%rax
mov    -0x2c(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x2c(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
mov    -0x2c(%rbp),%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x20(%rbp),%rax
mov    -0x2c(%rbp),%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x18(%rbp),%rax
mov    -0x2c(%rbp),%ecx
add    $0x4,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x2c(%rbp),%ecx
add    $0x4,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x5,%eax
mov    %eax,-0x2c(%rbp)
jmp    11b7 <ddot_+0xb7>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<ddot_>:
push   %rbx
test   %edi,%edi
jle    114d <ddot_+0x4d>
mov    %edi,%ebx
mov    $0xcccccccd,%ecx
mov    %rbx,%rax
imul   %rcx,%rax
shr    $0x22,%rax
lea    (%rax,%rax,4),%eax
mov    %edi,%r8d
sub    %eax,%r8d
je     1152 <ddot_+0x52>
mov    %r8d,%r9d
imul   %rbx,%rcx
shr    $0x22,%rcx
lea    (%rcx,%rcx,4),%eax
mov    %edi,%ecx
sub    %eax,%ecx
add    $0xffffffffffffffff,%rcx
mov    %r9d,%r10d
and    $0x3,%r10d
cmp    $0x3,%rcx
jae    115b <ddot_+0x5b>
xorpd  %xmm0,%xmm0
xor    %ecx,%ecx
jmp    11b7 <ddot_+0xb7>
xorps  %xmm0,%xmm0
pop    %rbx
ret
xorpd  %xmm0,%xmm0
jmp    11f2 <ddot_+0xf2>
and    $0x4,%r9d
xorpd  %xmm0,%xmm0
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nop
movsd  (%rsi,%rcx,8),%xmm1
movsd  0x8(%rsi,%rcx,8),%xmm2
mulsd  (%rdx,%rcx,8),%xmm1
mulsd  0x8(%rdx,%rcx,8),%xmm2
addsd  %xmm0,%xmm1
movsd  0x10(%rsi,%rcx,8),%xmm3
mulsd  0x10(%rdx,%rcx,8),%xmm3
addsd  %xmm1,%xmm2
movsd  0x18(%rsi,%rcx,8),%xmm0
mulsd  0x18(%rdx,%rcx,8),%xmm0
addsd  %xmm2,%xmm3
addsd  %xmm3,%xmm0
add    $0x4,%rcx
cmp    %rcx,%r9
jne    1170 <ddot_+0x70>
test   %r10,%r10
je     11e9 <ddot_+0xe9>
lea    (%rdx,%rcx,8),%r9
lea    (%rsi,%rcx,8),%r11
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
movsd  (%r11,%rcx,8),%xmm1
mulsd  (%r9,%rcx,8),%xmm1
addsd  %xmm1,%xmm0
add    $0x1,%rcx
cmp    %rcx,%r10
jne    11d0 <ddot_+0xd0>
cmp    $0x5,%edi
jl     1289 <ddot_+0x189>
cmp    %edi,%r8d
jge    1289 <ddot_+0x189>
mov    $0xcccccccd,%eax
imul   %rbx,%rax
shr    $0x22,%rax
lea    (%rax,%rax,4),%rcx
mov    $0x4,%r8d
sub    %rcx,%r8
lea    (%rdx,%r8,8),%rcx
lea    (%rsi,%r8,8),%rdx
lea    (%rax,%rax,4),%esi
neg    %esi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movsd  -0x20(%rdx,%rbx,8),%xmm1
mulsd  -0x20(%rcx,%rbx,8),%xmm1
movsd  -0x18(%rdx,%rbx,8),%xmm2
addsd  %xmm0,%xmm1
mulsd  -0x18(%rcx,%rbx,8),%xmm2
addsd  %xmm1,%xmm2
movsd  -0x10(%rdx,%rbx,8),%xmm0
mulsd  -0x10(%rcx,%rbx,8),%xmm0
addsd  %xmm2,%xmm0
movsd  -0x8(%rdx,%rbx,8),%xmm1
mulsd  -0x8(%rcx,%rbx,8),%xmm1
addsd  %xmm0,%xmm1
movsd  (%rdx,%rbx,8),%xmm0
mulsd  (%rcx,%rbx,8),%xmm0
addsd  %xmm1,%xmm0
add    $0x5,%rbx
lea    (%rsi,%rbx,1),%eax
cmp    %edi,%eax
jl     1230 <ddot_+0x130>
pop    %rbx
ret

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

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