double get_dC(const int cart_i, const int cart_j, const int cart_k,
              const double q[3], const double *dielectric) {
  if (cart_k == 0) {
    return (2 * q[0] * dielectric[0] + q[1] * (dielectric[1] + dielectric[3]) +
            q[2] * (dielectric[2] + dielectric[6]));
  }
  if (cart_k == 1) {
    return (2 * q[1] * dielectric[4] + q[2] * (dielectric[5] + dielectric[7]) +
            q[0] * (dielectric[1] + dielectric[3]));
  }
  if (cart_k == 2) {
    return (2 * q[2] * dielectric[8] + q[0] * (dielectric[2] + dielectric[6]) +
            q[1] * (dielectric[5] + dielectric[7]));
  }
  return 0;
}


x86 assembly (clang, -O0):
<get_dC>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0xc(%rbp)
mov    %esi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
cmpl   $0x0,-0x14(%rbp)
jne    118b <get_dC+0x8b>
mov    -0x20(%rbp),%rax
movsd  0xed5(%rip),%xmm1
mulsd  (%rax),%xmm1
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x20(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x28(%rbp),%rax
movsd  0x8(%rax),%xmm3
mov    -0x28(%rbp),%rax
addsd  0x18(%rax),%xmm3
mulsd  %xmm3,%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x20(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x28(%rbp),%rax
movsd  0x10(%rax),%xmm2
mov    -0x28(%rbp),%rax
addsd  0x30(%rax),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1281 <get_dC+0x181>
cmpl   $0x1,-0x14(%rbp)
jne    1202 <get_dC+0x102>
mov    -0x20(%rbp),%rax
movsd  0xe5f(%rip),%xmm1
mulsd  0x8(%rax),%xmm1
mov    -0x28(%rbp),%rax
movsd  0x20(%rax),%xmm2
mov    -0x20(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x28(%rbp),%rax
movsd  0x28(%rax),%xmm3
mov    -0x28(%rbp),%rax
addsd  0x38(%rax),%xmm3
mulsd  %xmm3,%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x28(%rbp),%rax
movsd  0x8(%rax),%xmm2
mov    -0x28(%rbp),%rax
addsd  0x18(%rax),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1281 <get_dC+0x181>
cmpl   $0x2,-0x14(%rbp)
jne    1279 <get_dC+0x179>
mov    -0x20(%rbp),%rax
movsd  0xde8(%rip),%xmm1
mulsd  0x10(%rax),%xmm1
mov    -0x28(%rbp),%rax
movsd  0x40(%rax),%xmm2
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x28(%rbp),%rax
movsd  0x10(%rax),%xmm3
mov    -0x28(%rbp),%rax
addsd  0x30(%rax),%xmm3
mulsd  %xmm3,%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x20(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x28(%rbp),%rax
movsd  0x28(%rax),%xmm2
mov    -0x28(%rbp),%rax
addsd  0x38(%rax),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1281 <get_dC+0x181>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<get_dC>:
cmp    $0x2,%edx
je     1144 <get_dC+0x44>
cmp    $0x1,%edx
je     1177 <get_dC+0x77>
test   %edx,%edx
jne    11ba <get_dC+0xba>
movsd  (%rcx),%xmm1
addsd  %xmm1,%xmm1
movsd  0x8(%r8),%xmm0
addsd  0x18(%r8),%xmm0
mulsd  0x8(%rcx),%xmm0
mulsd  (%r8),%xmm1
addsd  %xmm0,%xmm1
add    $0x10,%rcx
mov    $0x6,%eax
mov    $0x2,%edx
jmp    11a5 <get_dC+0xa5>
movsd  0x10(%rcx),%xmm1
addsd  %xmm1,%xmm1
movsd  0x10(%r8),%xmm0
addsd  0x30(%r8),%xmm0
mulsd  (%rcx),%xmm0
mulsd  0x40(%r8),%xmm1
addsd  %xmm0,%xmm1
add    $0x8,%rcx
mov    $0x7,%eax
mov    $0x5,%edx
jmp    11a5 <get_dC+0xa5>
movsd  0x8(%rcx),%xmm1
addsd  %xmm1,%xmm1
movsd  0x28(%r8),%xmm0
addsd  0x38(%r8),%xmm0
mulsd  0x10(%rcx),%xmm0
mulsd  0x20(%r8),%xmm1
addsd  %xmm0,%xmm1
mov    $0x3,%eax
mov    $0x1,%edx
movsd  (%r8,%rdx,8),%xmm0
addsd  (%r8,%rax,8),%xmm0
mulsd  (%rcx),%xmm0
addsd  %xmm1,%xmm0
ret
xorps  %xmm0,%xmm0
ret

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

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