void gen_xbounds(int nx, double *xvals, double *xbounds) {
  int i;
  for (i = 0; i < nx - 1; i++) {
    xbounds[i + 1] = 0.5 * (xvals[i] + xvals[i + 1]);
  }
  xbounds[0] = 2 * xvals[0] - xbounds[1];
  xbounds[nx] = 2 * xvals[nx - 1] - xbounds[nx - 1];
}


x86 assembly (clang, -O0):
<gen_xbounds>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    -0x4(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    1172 <gen_xbounds+0x72>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
addsd  (%rax,%rcx,8),%xmm1
movsd  0xeb2(%rip),%xmm0
mulsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1116 <gen_xbounds+0x16>
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
addsd  %xmm0,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x10(%rbp),%rax
mov    -0x4(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x4(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
addsd  %xmm0,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movslq -0x4(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
pop    %rbp
ret

x86 assembly (clang, -O2):
<gen_xbounds>:
lea    -0x1(%rdi),%r8d
cmp    $0x2,%edi
jl     12b9 <gen_xbounds+0x1b9>
mov    %r8d,%r10d
cmp    $0x4,%r8d
jb     113c <gen_xbounds+0x3c>
lea    0x8(%rdx),%rax
lea    (%rsi,%r10,8),%rcx
add    $0x8,%rcx
cmp    %rcx,%rax
jae    11bc <gen_xbounds+0xbc>
lea    (%rdx,%r10,8),%rax
add    $0x8,%rax
cmp    %rsi,%rax
jbe    11bc <gen_xbounds+0xbc>
xor    %ecx,%ecx
mov    %rcx,%rax
not    %rax
test   $0x1,%r10b
je     1165 <gen_xbounds+0x65>
movsd  (%rsi,%rcx,8),%xmm0
or     $0x1,%rcx
addsd  (%rsi,%rcx,8),%xmm0
mulsd  0xeb0(%rip),%xmm0
movsd  %xmm0,(%rdx,%rcx,8)
add    %r10,%rax
je     12b9 <gen_xbounds+0x1b9>
movsd  0xe9a(%rip),%xmm0
cs nopw 0x0(%rax,%rax,1)
movsd  (%rsi,%rcx,8),%xmm1
addsd  0x8(%rsi,%rcx,8),%xmm1
mulsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rdx,%rcx,8)
movsd  0x8(%rsi,%rcx,8),%xmm1
addsd  0x10(%rsi,%rcx,8),%xmm1
mulsd  %xmm0,%xmm1
movsd  %xmm1,0x10(%rdx,%rcx,8)
lea    0x2(%rcx),%rax
mov    %rax,%rcx
cmp    %rax,%r10
jne    1180 <gen_xbounds+0x80>
jmp    12b9 <gen_xbounds+0x1b9>
mov    %r10d,%ecx
and    $0xfffffffc,%ecx
lea    -0x4(%rcx),%rax
mov    %rax,%r9
shr    $0x2,%r9
add    $0x1,%r9
test   %rax,%rax
je     12e4 <gen_xbounds+0x1e4>
mov    %r9,%r11
and    $0xfffffffffffffffe,%r11
xor    %eax,%eax
movapd 0xe15(%rip),%xmm0
nopl   0x0(%rax,%rax,1)
movupd (%rsi,%rax,8),%xmm1
movupd 0x8(%rsi,%rax,8),%xmm2
addpd  %xmm1,%xmm2
movupd 0x10(%rsi,%rax,8),%xmm1
movupd 0x18(%rsi,%rax,8),%xmm3
addpd  %xmm1,%xmm3
mulpd  %xmm0,%xmm2
mulpd  %xmm0,%xmm3
movupd %xmm2,0x8(%rdx,%rax,8)
movupd %xmm3,0x18(%rdx,%rax,8)
movupd 0x20(%rsi,%rax,8),%xmm1
movupd 0x28(%rsi,%rax,8),%xmm2
addpd  %xmm1,%xmm2
movupd 0x30(%rsi,%rax,8),%xmm1
movupd 0x38(%rsi,%rax,8),%xmm3
addpd  %xmm1,%xmm3
mulpd  %xmm0,%xmm2
mulpd  %xmm0,%xmm3
movupd %xmm2,0x28(%rdx,%rax,8)
movupd %xmm3,0x38(%rdx,%rax,8)
add    $0x8,%rax
add    $0xfffffffffffffffe,%r11
jne    11f0 <gen_xbounds+0xf0>
test   $0x1,%r9b
je     12b0 <gen_xbounds+0x1b0>
lea    0x0(,%rax,8),%r9
movupd (%rsi,%rax,8),%xmm0
movupd 0x10(%rsi,%rax,8),%xmm1
or     $0x8,%r9
movupd (%rsi,%r9,1),%xmm2
addpd  %xmm0,%xmm2
movupd 0x10(%rsi,%r9,1),%xmm0
addpd  %xmm1,%xmm0
movapd 0xd65(%rip),%xmm1
mulpd  %xmm1,%xmm2
mulpd  %xmm1,%xmm0
movupd %xmm2,(%rdx,%r9,1)
movupd %xmm0,0x10(%rdx,%r9,1)
cmp    %r10,%rcx
jne    113e <gen_xbounds+0x3e>
movsd  (%rsi),%xmm0
addsd  %xmm0,%xmm0
subsd  0x8(%rdx),%xmm0
movsd  %xmm0,(%rdx)
movslq %r8d,%rax
movsd  (%rsi,%rax,8),%xmm0
addsd  %xmm0,%xmm0
subsd  (%rdx,%rax,8),%xmm0
movslq %edi,%rax
movsd  %xmm0,(%rdx,%rax,8)
ret
xor    %eax,%eax
test   $0x1,%r9b
jne    1267 <gen_xbounds+0x167>
jmp    12b0 <gen_xbounds+0x1b0>

LLVM IR (-O0):
define void @gen_xbounds(i32 %0, double* %1, double* %2) {
%4 = alloca i32
%5 = alloca double*
%6 = alloca double*
%7 = alloca i32
store i32 %0, i32* %4
store double* %1, double** %5
store double* %2, double** %6
store i32 0, i32* %7
br label %8
8: ; preds = %32, %3
%9 = load i32, i32* %7
%10 = load i32, i32* %4
%11 = sub nsw i32 %10, 1
%12 = icmp slt i32 %9, %11
br i1 %12, label %13, label %35
13: ; preds = %8
%14 = load double*, double** %5
%15 = load i32, i32* %7
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds double, double* %14, i64 %16
%18 = load double, double* %17
%19 = load double*, double** %5
%20 = load i32, i32* %7
%21 = add nsw i32 %20, 1
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds double, double* %19, i64 %22
%24 = load double, double* %23
%25 = fadd double %18, %24
%26 = fmul double 5.000000e-01, %25
%27 = load double*, double** %6
%28 = load i32, i32* %7
%29 = add nsw i32 %28, 1
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds double, double* %27, i64 %30
store double %26, double* %31
br label %32
32: ; preds = %13
%33 = load i32, i32* %7
%34 = add nsw i32 %33, 1
store i32 %34, i32* %7
br label %8
35: ; preds = %8
%36 = load double*, double** %5
%37 = getelementptr inbounds double, double* %36, i64 0
%38 = load double, double* %37
%39 = load double*, double** %6
%40 = getelementptr inbounds double, double* %39, i64 1
%41 = load double, double* %40
%42 = fneg double %41
%43 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %38, double %42)
%44 = load double*, double** %6
%45 = getelementptr inbounds double, double* %44, i64 0
store double %43, double* %45
%46 = load double*, double** %5
%47 = load i32, i32* %4
%48 = sub nsw i32 %47, 1
%49 = sext i32 %48 to i64
%50 = getelementptr inbounds double, double* %46, i64 %49
%51 = load double, double* %50
%52 = load double*, double** %6
%53 = load i32, i32* %4
%54 = sub nsw i32 %53, 1
%55 = sext i32 %54 to i64
%56 = getelementptr inbounds double, double* %52, i64 %55
%57 = load double, double* %56
%58 = fneg double %57
%59 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %51, double %58)
%60 = load double*, double** %6
%61 = load i32, i32* %4
%62 = sext i32 %61 to i64
%63 = getelementptr inbounds double, double* %60, i64 %62
store double %59, double* %63
ret void
}

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