#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
double round(double);
double atomicSeparation2(double ax, double ay, double az, double bx, double by,
                         double bz, double xdim, double ydim, double zdim,
                         int pbcx, int pbcy, int pbcz) {
  double rx, ry, rz, r2;
  rx = ax - bx;
  ry = ay - by;
  rz = az - bz;
  if (pbcx == 1) {
    rx = rx - round(rx / xdim) * xdim;
  }
  if (pbcy == 1) {
    ry = ry - round(ry / ydim) * ydim;
  }
  if (pbcz == 1) {
    rz = rz - round(rz / zdim) * zdim;
  }
  r2 = rx * rx + ry * ry + rz * rz;
  return r2;
}


x86 assembly (clang, -O0):
<atomicSeparation2>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
movsd  0x10(%rbp),%xmm8
movsd  %xmm0,-0x8(%rbp)
movsd  %xmm1,-0x10(%rbp)
movsd  %xmm2,-0x18(%rbp)
movsd  %xmm3,-0x20(%rbp)
movsd  %xmm4,-0x28(%rbp)
movsd  %xmm5,-0x30(%rbp)
movsd  %xmm6,-0x38(%rbp)
movsd  %xmm7,-0x40(%rbp)
mov    %edi,-0x44(%rbp)
mov    %esi,-0x48(%rbp)
mov    %edx,-0x4c(%rbp)
movsd  -0x8(%rbp),%xmm0
subsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x10(%rbp),%xmm0
subsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x18(%rbp),%xmm0
subsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
cmpl   $0x1,-0x44(%rbp)
jne    11d0 <atomicSeparation2+0xc0>
movsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  -0x58(%rbp),%xmm0
divsd  -0x38(%rbp),%xmm0
call   1030 <round@plt>
movsd  -0x78(%rbp),%xmm1
movsd  -0x38(%rbp),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
cmpl   $0x1,-0x48(%rbp)
jne    1221 <atomicSeparation2+0x111>
movsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  -0x60(%rbp),%xmm0
divsd  -0x40(%rbp),%xmm0
call   1030 <round@plt>
movsd  -0x80(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
cmpl   $0x1,-0x4c(%rbp)
jne    1278 <atomicSeparation2+0x168>
movsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
movsd  -0x68(%rbp),%xmm0
divsd  0x10(%rbp),%xmm0
call   1030 <round@plt>
movsd  -0x88(%rbp),%xmm1
ff
movsd  0x10(%rbp),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x58(%rbp),%xmm1
movsd  -0x58(%rbp),%xmm2
movsd  -0x60(%rbp),%xmm0
mulsd  -0x60(%rbp),%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x68(%rbp),%xmm0
movsd  -0x68(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x70(%rbp),%xmm0
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<atomicSeparation2>:
push   %rbp
push   %rbx
sub    $0x38,%rsp
mov    %edx,%ebx
mov    %esi,%ebp
movsd  %xmm7,0x18(%rsp)
movsd  %xmm5,0x30(%rsp)
movsd  %xmm2,(%rsp)
movapd %xmm1,%xmm2
subsd  %xmm3,%xmm0
cmp    $0x1,%edi
jne    1187 <atomicSeparation2+0x77>
movsd  %xmm0,0x8(%rsp)
movsd  0x8(%rsp),%xmm0
divsd  %xmm6,%xmm0
movsd  %xmm2,0x10(%rsp)
movsd  %xmm4,0x28(%rsp)
movsd  %xmm6,0x20(%rsp)
call   1030 <round@plt>
movsd  0x28(%rsp),%xmm4
movsd  0x10(%rsp),%xmm2
mulsd  0x20(%rsp),%xmm0
movsd  0x8(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
movsd  0x8(%rsp),%xmm0
movsd  %xmm0,0x8(%rsp)
subsd  %xmm4,%xmm2
cmp    $0x1,%ebp
jne    11bb <atomicSeparation2+0xab>
movapd %xmm2,%xmm0
divsd  0x18(%rsp),%xmm0
movsd  %xmm2,0x10(%rsp)
call   1030 <round@plt>
movsd  0x10(%rsp),%xmm2
mulsd  0x18(%rsp),%xmm0
subsd  %xmm0,%xmm2
movsd  (%rsp),%xmm0
subsd  0x30(%rsp),%xmm0
cmp    $0x1,%ebx
jne    1205 <atomicSeparation2+0xf5>
movsd  %xmm0,(%rsp)
movsd  (%rsp),%xmm0
divsd  0x50(%rsp),%xmm0
movsd  %xmm2,0x10(%rsp)
call   1030 <round@plt>
movsd  0x10(%rsp),%xmm2
mulsd  0x50(%rsp),%xmm0
movsd  (%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,(%rsp)
movsd  (%rsp),%xmm0
mulsd  %xmm2,%xmm2
movsd  0x8(%rsp),%xmm1
mulsd  %xmm1,%xmm1
addsd  %xmm2,%xmm1
mulsd  %xmm0,%xmm0
addsd  %xmm1,%xmm0
add    $0x38,%rsp
pop    %rbx
pop    %rbp
ret

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

LLVM IR (-O2):
define double @atomicSeparation2(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, double %8, i32 %9, i32 %10, i32 %11) {
%13 = fsub double %0, %3
%14 = fsub double %1, %4
%15 = fsub double %2, %5
%16 = icmp eq i32 %9, 1
br i1 %16, label %17, label %22
17: ; preds = %12
%18 = fdiv double %13, %6
%19 = tail call double @llvm.round.f64(double %18)
%20 = fneg double %19
%21 = tail call double @llvm.fmuladd.f64(double %20, double %6, double %13)
br label %22
22: ; preds = %17, %12
%23 = phi double [ %21, %17 ], [ %13, %12 ]
%24 = icmp eq i32 %10, 1
br i1 %24, label %25, label %30
25: ; preds = %22
%26 = fdiv double %14, %7
%27 = tail call double @llvm.round.f64(double %26)
%28 = fneg double %27
%29 = tail call double @llvm.fmuladd.f64(double %28, double %7, double %14)
br label %30
30: ; preds = %25, %22
%31 = phi double [ %29, %25 ], [ %14, %22 ]
%32 = icmp eq i32 %11, 1
br i1 %32, label %33, label %38
33: ; preds = %30
%34 = fdiv double %15, %8
%35 = tail call double @llvm.round.f64(double %34)
%36 = fneg double %35
%37 = tail call double @llvm.fmuladd.f64(double %36, double %8, double %15)
br label %38
38: ; preds = %33, %30
%39 = phi double [ %37, %33 ], [ %15, %30 ]
%40 = fmul double %31, %31
%41 = tail call double @llvm.fmuladd.f64(double %23, double %23, double %40)
%42 = tail call double @llvm.fmuladd.f64(double %39, double %39, double %41)
ret double %42
}