double nm2(int n, double *y, double h) {
  int k;
  double sum, sum1, sum2;
  sum1 = 0.0;
  sum2 = 0.0;
  for (k = 0; k < n; k = k + 2)
    sum1 += y[k] * y[k];
  for (k = 1; k < n; k = k + 2)
    sum2 += y[k] * y[k];
  sum = 2.0 * sum1 + 4.0 * sum2 - y[0] * y[0] - y[n - 1] * y[n - 1];
  sum = sum * h / 3.0;
  return sum;
}


x86 assembly (clang, -O0):
<nm2>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x30(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    116d <nm2+0x6d>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x30(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x1c(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x1c(%rbp)
jmp    1127 <nm2+0x27>
movl   $0x1,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    11ba <nm2+0xba>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x38(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x1c(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x1c(%rbp)
jmp    1174 <nm2+0x74>
movsd  -0x30(%rbp),%xmm0
movsd  0xe41(%rip),%xmm1
mulsd  -0x38(%rbp),%xmm1
addsd  %xmm0,%xmm0
addsd  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm1
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
mov    -0x4(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x4(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  0xda3(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<nm2>:
test   %edi,%edi
jle    1128 <nm2+0x28>
mov    %edi,%r8d
lea    -0x1(%r8),%rdx
mov    %rdx,%rcx
shr    %rcx
add    $0x1,%rcx
mov    %ecx,%eax
and    $0x3,%eax
cmp    $0x6,%rdx
jae    1135 <nm2+0x35>
xorpd  %xmm1,%xmm1
xor    %edx,%edx
jmp    1181 <nm2+0x81>
xorpd  %xmm1,%xmm1
xorpd  %xmm2,%xmm2
jmp    125e <nm2+0x15e>
and    $0xfffffffffffffffc,%rcx
xorpd  %xmm1,%xmm1
xor    %edx,%edx
nop
movsd  (%rsi,%rdx,8),%xmm2
movsd  0x10(%rsi,%rdx,8),%xmm3
mulsd  %xmm2,%xmm2
addsd  %xmm1,%xmm2
mulsd  %xmm3,%xmm3
addsd  %xmm2,%xmm3
movsd  0x20(%rsi,%rdx,8),%xmm2
mulsd  %xmm2,%xmm2
addsd  %xmm3,%xmm2
movsd  0x30(%rsi,%rdx,8),%xmm1
mulsd  %xmm1,%xmm1
addsd  %xmm2,%xmm1
add    $0x8,%rdx
add    $0xfffffffffffffffc,%rcx
jne    1140 <nm2+0x40>
test   %rax,%rax
je     11a6 <nm2+0xa6>
lea    (%rsi,%rdx,8),%rcx
shl    $0x4,%rax
xor    %edx,%edx
movsd  (%rcx,%rdx,1),%xmm2
mulsd  %xmm2,%xmm2
addsd  %xmm2,%xmm1
add    $0x10,%rdx
cmp    %rdx,%rax
jne    1190 <nm2+0x90>
xorpd  %xmm2,%xmm2
cmp    $0x2,%edi
jl     125e <nm2+0x15e>
add    $0xfffffffffffffffe,%r8
mov    %r8,%rax
shr    %rax
add    $0x1,%rax
mov    %eax,%ecx
and    $0x3,%ecx
cmp    $0x6,%r8
jae    11d7 <nm2+0xd7>
xorpd  %xmm2,%xmm2
mov    $0x1,%edx
jmp    1231 <nm2+0x131>
and    $0xfffffffffffffffc,%rax
xorpd  %xmm2,%xmm2
mov    $0x1,%edx
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movsd  (%rsi,%rdx,8),%xmm3
movsd  0x10(%rsi,%rdx,8),%xmm4
mulsd  %xmm3,%xmm3
addsd  %xmm2,%xmm3
mulsd  %xmm4,%xmm4
addsd  %xmm3,%xmm4
movsd  0x20(%rsi,%rdx,8),%xmm3
mulsd  %xmm3,%xmm3
addsd  %xmm4,%xmm3
movsd  0x30(%rsi,%rdx,8),%xmm2
mulsd  %xmm2,%xmm2
addsd  %xmm3,%xmm2
add    $0x8,%rdx
add    $0xfffffffffffffffc,%rax
jne    11f0 <nm2+0xf0>
test   %rcx,%rcx
je     1256 <nm2+0x156>
lea    (%rsi,%rdx,8),%rax
shl    $0x4,%rcx
xor    %edx,%edx
movsd  (%rax,%rdx,1),%xmm3
mulsd  %xmm3,%xmm3
addsd  %xmm3,%xmm2
add    $0x10,%rdx
cmp    %rdx,%rcx
jne    1240 <nm2+0x140>
mulsd  0xda2(%rip),%xmm2
addsd  %xmm1,%xmm1
addsd  %xmm2,%xmm1
movsd  (%rsi),%xmm2
mulsd  %xmm2,%xmm2
subsd  %xmm2,%xmm1
movslq %edi,%rax
movsd  -0x8(%rsi,%rax,8),%xmm2
mulsd  %xmm2,%xmm2
subsd  %xmm2,%xmm1
mulsd  %xmm0,%xmm1
divsd  0xd79(%rip),%xmm1
movapd %xmm1,%xmm0
ret

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

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