double mypotential(double *x, int N, double *grad, double eps, double sig) {
  int i, j, k;
  double energy = 0;
  double sig12, sig24;
  double g, r, r2, ir2, ir12, ir24;
  double dr[3];
  sig12 = sig * sig * sig;
  sig12 *= sig12;
  sig12 *= sig12;
  sig24 = sig12 * sig12;
  for (i = 0; i < N; i += 3) {
    for (j = i + 3; j < N; j += 3) {
      r2 = 0;
      for (k = 0; k < 3; ++k) {
        dr[k] = x[i + k] - x[j + k];
        r2 += dr[k] * dr[k];
      }
      ir2 = 1. / r2;
      ir12 = ir2 * ir2 * ir2;
      ir12 *= ir12;
      ir24 = ir12 * ir12;
      energy += 4. * eps * (sig24 * ir24 - sig12 * ir12);
      g = 4. * eps * (-24. * sig24 * ir24 + 12. * sig12 * ir12);
      for (k = 0; k < 3; ++k) {
        grad[i + k] += g * ir2 * dr[k];
        grad[j + k] -= g * ir2 * dr[k];
      }
    }
  }
  return energy;
}


x86 assembly (clang, -O0):
<mypotential>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
movsd  %xmm0,-0x20(%rbp)
movsd  %xmm1,-0x28(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x28(%rbp),%xmm0
mulsd  -0x28(%rbp),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
mulsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
mulsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
mulsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    13b2 <mypotential+0x2b2>
mov    -0x2c(%rbp),%eax
add    $0x3,%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    139f <mypotential+0x29f>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x68(%rbp)
movl   $0x0,-0x34(%rbp)
cmpl   $0x3,-0x34(%rbp)
jge    1212 <mypotential+0x112>
mov    -0x8(%rbp),%rax
mov    -0x2c(%rbp),%ecx
add    -0x34(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x30(%rbp),%ecx
add    -0x34(%rbp),%ecx
movslq %ecx,%rcx
subsd  (%rax,%rcx,8),%xmm0
movslq -0x34(%rbp),%rax
movsd  %xmm0,-0xa0(%rbp,%rax,8)
ff ff
movslq -0x34(%rbp),%rax
movsd  -0xa0(%rbp,%rax,8),%xmm0
ff ff
movslq -0x34(%rbp),%rax
movsd  -0xa0(%rbp,%rax,8),%xmm2
ff ff
movsd  -0x68(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    119d <mypotential+0x9d>
movsd  0xdfe(%rip),%xmm0
divsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x70(%rbp),%xmm0
mulsd  -0x70(%rbp),%xmm0
mulsd  -0x70(%rbp),%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  -0x78(%rbp),%xmm0
mulsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  -0x78(%rbp),%xmm0
mulsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  0xdb2(%rip),%xmm0
mulsd  -0x20(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x80(%rbp),%xmm3
movsd  -0x48(%rbp),%xmm1
mulsd  -0x78(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm3,%xmm2
addsd  %xmm1,%xmm2
movsd  -0x40(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  0xd60(%rip),%xmm0
mulsd  -0x20(%rbp),%xmm0
movsd  0xd4b(%rip),%xmm1
mulsd  -0x50(%rbp),%xmm1
movsd  -0x80(%rbp),%xmm3
movsd  0xd31(%rip),%xmm2
mulsd  -0x48(%rbp),%xmm2
mulsd  -0x78(%rbp),%xmm2
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
movl   $0x0,-0x34(%rbp)
cmpl   $0x3,-0x34(%rbp)
jge    138c <mypotential+0x28c>
movsd  -0x58(%rbp),%xmm0
mulsd  -0x70(%rbp),%xmm0
movslq -0x34(%rbp),%rax
movsd  -0xa0(%rbp,%rax,8),%xmm2
ff ff
mov    -0x18(%rbp),%rax
mov    -0x2c(%rbp),%ecx
add    -0x34(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x58(%rbp),%xmm0
mulsd  -0x70(%rbp),%xmm0
movslq -0x34(%rbp),%rax
movsd  -0xa0(%rbp,%rax,8),%xmm2
ff ff
mov    -0x18(%rbp),%rax
mov    -0x30(%rbp),%ecx
add    -0x34(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
movq   %xmm0,%rdx
movabs $0x8000000000000000,%rsi
xor    %rsi,%rdx
movq   %rdx,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    12f1 <mypotential+0x1f1>
jmp    1391 <mypotential+0x291>
mov    -0x30(%rbp),%eax
add    $0x3,%eax
mov    %eax,-0x30(%rbp)
jmp    1182 <mypotential+0x82>
jmp    13a4 <mypotential+0x2a4>
mov    -0x2c(%rbp),%eax
add    $0x3,%eax
mov    %eax,-0x2c(%rbp)
jmp    116d <mypotential+0x6d>
movsd  -0x40(%rbp),%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<mypotential>:
test   %esi,%esi
jle    12bc <mypotential+0x1bc>
movapd %xmm1,%xmm10
mulsd  %xmm1,%xmm10
mulsd  %xmm1,%xmm10
mulsd  %xmm10,%xmm10
mulsd  %xmm10,%xmm10
movapd %xmm10,%xmm11
mulsd  %xmm10,%xmm11
mulsd  0xecd(%rip),%xmm0
movapd 0xee4(%rip),%xmm12
xorpd  %xmm10,%xmm12
movsd  0xebe(%rip),%xmm13
mulsd  %xmm11,%xmm13
mulsd  0xeb8(%rip),%xmm10
mov    %esi,%r8d
xorpd  %xmm8,%xmm8
mov    $0x3,%r10d
xor    %eax,%eax
movsd  0xea7(%rip),%xmm9
xorpd  %xmm14,%xmm14
cs nopw 0x0(%rax,%rax,1)
lea    0x3(%rax),%r9
cmp    %r8,%r9
jae    12b6 <mypotential+0x1b6>
mov    %r10,%rcx
movsd  (%rdi,%rax,8),%xmm7
movsd  0x8(%rdi,%rax,8),%xmm6
subsd  (%rdi,%rcx,8),%xmm7
movapd %xmm7,%xmm2
mulsd  %xmm7,%xmm2
addsd  %xmm8,%xmm2
subsd  0x8(%rdi,%rcx,8),%xmm6
movapd %xmm6,%xmm3
mulsd  %xmm6,%xmm3
addsd  %xmm2,%xmm3
movsd  0x10(%rdi,%rax,8),%xmm15
subsd  0x10(%rdi,%rcx,8),%xmm15
movapd %xmm15,%xmm4
mulsd  %xmm15,%xmm4
addsd  %xmm3,%xmm4
movapd %xmm9,%xmm1
divsd  %xmm4,%xmm1
movapd %xmm1,%xmm5
mulsd  %xmm1,%xmm5
mulsd  %xmm1,%xmm5
mulsd  %xmm5,%xmm5
movapd %xmm5,%xmm3
mulsd  %xmm5,%xmm3
movapd %xmm10,%xmm2
mulsd  %xmm5,%xmm2
mulsd  %xmm12,%xmm5
movapd %xmm11,%xmm4
mulsd  %xmm3,%xmm4
addsd  %xmm5,%xmm4
mulsd  %xmm13,%xmm3
addsd  %xmm2,%xmm3
mulsd  %xmm0,%xmm3
mulsd  %xmm1,%xmm3
mulsd  %xmm3,%xmm7
movsd  (%rdx,%rax,8),%xmm1
addsd  %xmm7,%xmm1
movsd  %xmm1,(%rdx,%rax,8)
movsd  (%rdx,%rcx,8),%xmm1
subsd  %xmm7,%xmm1
movsd  %xmm1,(%rdx,%rcx,8)
mulsd  %xmm3,%xmm6
movsd  0x8(%rdx,%rax,8),%xmm1
addsd  %xmm6,%xmm1
movsd  %xmm1,0x8(%rdx,%rax,8)
movsd  0x8(%rdx,%rcx,8),%xmm1
subsd  %xmm6,%xmm1
movsd  %xmm1,0x8(%rdx,%rcx,8)
mulsd  %xmm15,%xmm3
movsd  0x10(%rdx,%rax,8),%xmm1
addsd  %xmm3,%xmm1
movsd  %xmm1,0x10(%rdx,%rax,8)
movsd  0x10(%rdx,%rcx,8),%xmm1
subsd  %xmm3,%xmm1
movsd  %xmm1,0x10(%rdx,%rcx,8)
mulsd  %xmm0,%xmm4
addsd  %xmm4,%xmm14
add    $0x3,%rcx
cmp    %esi,%ecx
jl     1190 <mypotential+0x90>
add    $0x3,%r10
mov    %r9,%rax
cmp    %r8,%r9
jb     1180 <mypotential+0x80>
movapd %xmm14,%xmm0
ret
xorps  %xmm14,%xmm14
movaps %xmm14,%xmm0
ret

LLVM IR (-O0):
define double @mypotential(double* %0, i32 %1, double* %2, double %3, double %4) {
%6 = alloca double*
%7 = alloca i32
%8 = alloca double*
%9 = alloca double
%10 = alloca double
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca double
%15 = alloca double
%16 = alloca double
%17 = alloca double
%18 = alloca double
%19 = alloca double
%20 = alloca double
%21 = alloca double
%22 = alloca double
%23 = alloca [3 x double]
store double* %0, double** %6
store i32 %1, i32* %7
store double* %2, double** %8
store double %3, double* %9
store double %4, double* %10
store double 0.000000e+00, double* %14
%24 = load double, double* %10
%25 = load double, double* %10
%26 = fmul double %24, %25
%27 = load double, double* %10
%28 = fmul double %26, %27
store double %28, double* %15
%29 = load double, double* %15
%30 = load double, double* %15
%31 = fmul double %30, %29
store double %31, double* %15
%32 = load double, double* %15
%33 = load double, double* %15
%34 = fmul double %33, %32
store double %34, double* %15
%35 = load double, double* %15
%36 = load double, double* %15
%37 = fmul double %35, %36
store double %37, double* %16
store i32 0, i32* %11
br label %38
38: ; preds = %164, %5
%39 = load i32, i32* %11
%40 = load i32, i32* %7
%41 = icmp slt i32 %39, %40
br i1 %41, label %42, label %167
42: ; preds = %38
%43 = load i32, i32* %11
%44 = add nsw i32 %43, 3
store i32 %44, i32* %12
br label %45
45: ; preds = %160, %42
%46 = load i32, i32* %12
%47 = load i32, i32* %7
%48 = icmp slt i32 %46, %47
br i1 %48, label %49, label %163
49: ; preds = %45
store double 0.000000e+00, double* %19
store i32 0, i32* %13
br label %50
50: ; preds = %82, %49
%51 = load i32, i32* %13
%52 = icmp slt i32 %51, 3
br i1 %52, label %53, label %85
53: ; preds = %50
%54 = load double*, double** %6
%55 = load i32, i32* %11
%56 = load i32, i32* %13
%57 = add nsw i32 %55, %56
%58 = sext i32 %57 to i64
%59 = getelementptr inbounds double, double* %54, i64 %58
%60 = load double, double* %59
%61 = load double*, double** %6
%62 = load i32, i32* %12
%63 = load i32, i32* %13
%64 = add nsw i32 %62, %63
%65 = sext i32 %64 to i64
%66 = getelementptr inbounds double, double* %61, i64 %65
%67 = load double, double* %66
%68 = fsub double %60, %67
%69 = load i32, i32* %13
%70 = sext i32 %69 to i64
%71 = getelementptr inbounds [3 x double], [3 x double]* %23, i64 0, i64 %70
store double %68, double* %71
%72 = load i32, i32* %13
%73 = sext i32 %72 to i64
%74 = getelementptr inbounds [3 x double], [3 x double]* %23, i64 0, i64 %73
%75 = load double, double* %74
%76 = load i32, i32* %13
%77 = sext i32 %76 to i64
%78 = getelementptr inbounds [3 x double], [3 x double]* %23, i64 0, i64 %77
%79 = load double, double* %78
%80 = load double, double* %19
%81 = call double @llvm.fmuladd.f64(double %75, double %79, double %80)
store double %81, double* %19
br label %82
82: ; preds = %53
%83 = load i32, i32* %13
%84 = add nsw i32 %83, 1
store i32 %84, i32* %13
br label %50
85: ; preds = %50
%86 = load double, double* %19
%87 = fdiv double 1.000000e+00, %86
store double %87, double* %20
%88 = load double, double* %20
%89 = load double, double* %20
%90 = fmul double %88, %89
%91 = load double, double* %20
%92 = fmul double %90, %91
store double %92, double* %21
%93 = load double, double* %21
%94 = load double, double* %21
%95 = fmul double %94, %93
store double %95, double* %21
%96 = load double, double* %21
%97 = load double, double* %21
%98 = fmul double %96, %97
store double %98, double* %22
%99 = load double, double* %9
%100 = fmul double 4.000000e+00, %99
%101 = load double, double* %16
%102 = load double, double* %22
%103 = load double, double* %15
%104 = load double, double* %21
%105 = fmul double %103, %104
%106 = fneg double %105
%107 = call double @llvm.fmuladd.f64(double %101, double %102, double %106)
%108 = load double, double* %14
%109 = call double @llvm.fmuladd.f64(double %100, double %107, double %108)
store double %109, double* %14
%110 = load double, double* %9
%111 = fmul double 4.000000e+00, %110
%112 = load double, double* %16
%113 = fmul double -2.400000e+01, %112
%114 = load double, double* %22
%115 = load double, double* %15
%116 = fmul double 1.200000e+01, %115
%117 = load double, double* %21
%118 = fmul double %116, %117
%119 = call double @llvm.fmuladd.f64(double %113, double %114, double %118)
%120 = fmul double %111, %119
store double %120, double* %17
store i32 0, i32* %13
br label %121
121: ; preds = %156, %85
%122 = load i32, i32* %13
%123 = icmp slt i32 %122, 3
br i1 %123, label %124, label %159
124: ; preds = %121
%125 = load double, double* %17
%126 = load double, double* %20
%127 = fmul double %125, %126
%128 = load i32, i32* %13
%129 = sext i32 %128 to i64
%130 = getelementptr inbounds [3 x double], [3 x double]* %23, i64 0, i64 %129
%131 = load double, double* %130
%132 = load double*, double** %8
%133 = load i32, i32* %11
%134 = load i32, i32* %13
%135 = add nsw i32 %133, %134
%136 = sext i32 %135 to i64
%137 = getelementptr inbounds double, double* %132, i64 %136
%138 = load double, double* %137
%139 = call double @llvm.fmuladd.f64(double %127, double %131, double %138)
store double %139, double* %137
%140 = load double, double* %17
%141 = load double, double* %20
%142 = fmul double %140, %141
%143 = load i32, i32* %13
%144 = sext i32 %143 to i64
%145 = getelementptr inbounds [3 x double], [3 x double]* %23, i64 0, i64 %144
%146 = load double, double* %145
%147 = load double*, double** %8
%148 = load i32, i32* %12
%149 = load i32, i32* %13
%150 = add nsw i32 %148, %149
%151 = sext i32 %150 to i64
%152 = getelementptr inbounds double, double* %147, i64 %151
%153 = load double, double* %152
%154 = fneg double %142
%155 = call double @llvm.fmuladd.f64(double %154, double %146, double %153)
store double %155, double* %152
br label %156
156: ; preds = %124
%157 = load i32, i32* %13
%158 = add nsw i32 %157, 1
store i32 %158, i32* %13
br label %121
159: ; preds = %121
br label %160
160: ; preds = %159
%161 = load i32, i32* %12
%162 = add nsw i32 %161, 3
store i32 %162, i32* %12
br label %45
163: ; preds = %45
br label %164
164: ; preds = %163
%165 = load i32, i32* %11
%166 = add nsw i32 %165, 3
store i32 %166, i32* %11
br label %38
167: ; preds = %38
%168 = load double, double* %14
ret double %168
}

LLVM IR (-O2):
define double @mypotential(double* nocapture %0, i32 %1, double* nocapture %2, double %3, double %4) {
%6 = fmul double %4, %4
%7 = fmul double %6, %4
%8 = fmul double %7, %7
%9 = fmul double %8, %8
%10 = fmul double %9, %9
%11 = icmp sgt i32 %1, 0
br i1 %11, label %12, label %86
12: ; preds = %5
%13 = fmul double %3, 4.000000e+00
%14 = fneg double %9
%15 = fmul double %10, -2.400000e+01
%16 = fmul double %9, 1.200000e+01
%17 = zext i32 %1 to i64
br label %20
18: ; preds = %35
%19 = add nuw nsw i64 %22, 3
br i1 %25, label %20, label %86
20: ; preds = %12, %18
%21 = phi i64 [ 0, %12 ], [ %24, %18 ]
%22 = phi i64 [ 3, %12 ], [ %19, %18 ]
%23 = phi double [ 0.000000e+00, %12 ], [ %82, %18 ]
%24 = add nuw nsw i64 %21, 3
%25 = icmp ult i64 %24, %17
br i1 %25, label %26, label %86
26: ; preds = %20
%27 = getelementptr inbounds double, double* %0, i64 %21
%28 = add nuw nsw i64 %21, 1
%29 = getelementptr inbounds double, double* %0, i64 %28
%30 = add nuw nsw i64 %21, 2
%31 = getelementptr inbounds double, double* %0, i64 %30
%32 = getelementptr inbounds double, double* %2, i64 %21
%33 = getelementptr inbounds double, double* %2, i64 %28
%34 = getelementptr inbounds double, double* %2, i64 %30
br label %35
35: ; preds = %26, %35
%36 = phi i64 [ %22, %26 ], [ %83, %35 ]
%37 = phi double [ %23, %26 ], [ %82, %35 ]
%38 = load double, double* %27
%39 = getelementptr inbounds double, double* %0, i64 %36
%40 = load double, double* %39
%41 = fsub double %38, %40
%42 = tail call double @llvm.fmuladd.f64(double %41, double %41, double 0.000000e+00)
%43 = load double, double* %29
%44 = add nuw nsw i64 %36, 1
%45 = getelementptr inbounds double, double* %0, i64 %44
%46 = load double, double* %45
%47 = fsub double %43, %46
%48 = tail call double @llvm.fmuladd.f64(double %47, double %47, double %42)
%49 = load double, double* %31
%50 = add nuw nsw i64 %36, 2
%51 = getelementptr inbounds double, double* %0, i64 %50
%52 = load double, double* %51
%53 = fsub double %49, %52
%54 = tail call double @llvm.fmuladd.f64(double %53, double %53, double %48)
%55 = fdiv double 1.000000e+00, %54
%56 = fmul double %55, %55
%57 = fmul double %55, %56
%58 = fmul double %57, %57
%59 = fmul double %58, %58
%60 = fmul double %58, %14
%61 = tail call double @llvm.fmuladd.f64(double %10, double %59, double %60)
%62 = fmul double %16, %58
%63 = tail call double @llvm.fmuladd.f64(double %15, double %59, double %62)
%64 = fmul double %13, %63
%65 = fmul double %55, %64
%66 = fneg double %65
%67 = load double, double* %32
%68 = tail call double @llvm.fmuladd.f64(double %65, double %41, double %67)
store double %68, double* %32
%69 = getelementptr inbounds double, double* %2, i64 %36
%70 = load double, double* %69
%71 = tail call double @llvm.fmuladd.f64(double %66, double %41, double %70)
store double %71, double* %69
%72 = load double, double* %33
%73 = tail call double @llvm.fmuladd.f64(double %65, double %47, double %72)
store double %73, double* %33
%74 = getelementptr inbounds double, double* %2, i64 %44
%75 = load double, double* %74
%76 = tail call double @llvm.fmuladd.f64(double %66, double %47, double %75)
store double %76, double* %74
%77 = load double, double* %34
%78 = tail call double @llvm.fmuladd.f64(double %65, double %53, double %77)
store double %78, double* %34
%79 = getelementptr inbounds double, double* %2, i64 %50
%80 = load double, double* %79
%81 = tail call double @llvm.fmuladd.f64(double %66, double %53, double %80)
store double %81, double* %79
%82 = tail call double @llvm.fmuladd.f64(double %13, double %61, double %37)
%83 = add nuw nsw i64 %36, 3
%84 = trunc i64 %83 to i32
%85 = icmp slt i32 %84, %1
br i1 %85, label %35, label %18
86: ; preds = %18, %20, %5
%87 = phi double [ 0.000000e+00, %5 ], [ %23, %20 ], [ %82, %18 ]
ret double %87
}