__attribute__((visibility("default"))) double
compose_g(double J_sum, double J1, double J2, double g1, double g2) {
  if (!J_sum)
    return 0;
  double J_sum_2 = J_sum * (J_sum + 1);
  double J1_2 = J1 * (J1 + 1);
  double J2_2 = J2 * (J2 + 1);
  return (g1 * (J_sum_2 + J1_2 - J2_2) + g2 * (J_sum_2 + J2_2 - J1_2)) / 2 /
         J_sum_2;
}


x86 assembly (clang, -O0):
<compose_g>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
movsd  %xmm3,-0x28(%rbp)
movsd  %xmm4,-0x30(%rbp)
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1142 <compose_g+0x42>
jp     1142 <compose_g+0x42>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11dd <compose_g+0xdd>
movsd  -0x10(%rbp),%xmm0
movsd  0xeb9(%rip),%xmm1
addsd  -0x10(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  0xe9e(%rip),%xmm1
addsd  -0x18(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xe83(%rip),%xmm1
addsd  -0x20(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  -0x38(%rbp),%xmm2
addsd  -0x40(%rbp),%xmm2
subsd  -0x48(%rbp),%xmm2
movsd  -0x30(%rbp),%xmm1
movsd  -0x38(%rbp),%xmm3
addsd  -0x48(%rbp),%xmm3
subsd  -0x40(%rbp),%xmm3
mulsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0xe31(%rip),%xmm1
divsd  %xmm1,%xmm0
divsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<compose_g>:
xorpd  %xmm5,%xmm5
ucomisd %xmm5,%xmm0
jne    110c <compose_g+0xc>
jnp    1168 <compose_g+0x68>
movsd  0xeec(%rip),%xmm5
addsd  %xmm1,%xmm5
mulsd  %xmm1,%xmm5
unpcklpd %xmm2,%xmm0
movapd 0xee8(%rip),%xmm1
addpd  %xmm0,%xmm1
mulpd  %xmm0,%xmm1
movapd %xmm1,%xmm0
addsd  %xmm5,%xmm0
movapd %xmm1,%xmm2
unpckhpd %xmm1,%xmm2
subsd  %xmm2,%xmm0
addsd  %xmm1,%xmm2
subsd  %xmm5,%xmm2
mulsd  %xmm4,%xmm2
mulsd  %xmm0,%xmm3
addsd  %xmm2,%xmm3
mulsd  0xea8(%rip),%xmm3
divsd  %xmm1,%xmm3
movapd %xmm3,%xmm5
movapd %xmm5,%xmm0
ret

LLVM IR (-O0):
define double @compose_g(double %0, double %1, double %2, double %3, double %4) {
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = alloca double
%12 = alloca double
%13 = alloca double
%14 = alloca double
store double %0, double* %7
store double %1, double* %8
store double %2, double* %9
store double %3, double* %10
store double %4, double* %11
%15 = load double, double* %7
%16 = fcmp une double %15, 0.000000e+00
br i1 %16, label %18, label %17
17: ; preds = %5
store double 0.000000e+00, double* %6
br label %48
18: ; preds = %5
%19 = load double, double* %7
%20 = load double, double* %7
%21 = fadd double %20, 1.000000e+00
%22 = fmul double %19, %21
store double %22, double* %12
%23 = load double, double* %8
%24 = load double, double* %8
%25 = fadd double %24, 1.000000e+00
%26 = fmul double %23, %25
store double %26, double* %13
%27 = load double, double* %9
%28 = load double, double* %9
%29 = fadd double %28, 1.000000e+00
%30 = fmul double %27, %29
store double %30, double* %14
%31 = load double, double* %10
%32 = load double, double* %12
%33 = load double, double* %13
%34 = fadd double %32, %33
%35 = load double, double* %14
%36 = fsub double %34, %35
%37 = load double, double* %11
%38 = load double, double* %12
%39 = load double, double* %14
%40 = fadd double %38, %39
%41 = load double, double* %13
%42 = fsub double %40, %41
%43 = fmul double %37, %42
%44 = call double @llvm.fmuladd.f64(double %31, double %36, double %43)
%45 = fdiv double %44, 2.000000e+00
%46 = load double, double* %12
%47 = fdiv double %45, %46
store double %47, double* %6
br label %48
48: ; preds = %18, %17
%49 = load double, double* %6
ret double %49
}

LLVM IR (-O2):
define double @compose_g(double %0, double %1, double %2, double %3, double %4) {
%6 = fcmp une double %0, 0.000000e+00
br i1 %6, label %7, label %24
7: ; preds = %5
%8 = fadd double %1, 1.000000e+00
%9 = fmul double %8, %1
%10 = insertelement <2 x double> poison, double %0, i64 0
%11 = insertelement <2 x double> %10, double %2, i64 1
%12 = fadd <2 x double> %11, <double 1.000000e+00, double 1.000000e+00>
%13 = fmul <2 x double> %12, %11
%14 = extractelement <2 x double> %13, i64 0
%15 = fadd double %14, %9
%16 = extractelement <2 x double> %13, i64 1
%17 = fsub double %15, %16
%18 = fadd double %14, %16
%19 = fsub double %18, %9
%20 = fmul double %19, %4
%21 = tail call double @llvm.fmuladd.f64(double %3, double %17, double %20)
%22 = fmul double %21, 5.000000e-01
%23 = fdiv double %22, %14
br label %24
24: ; preds = %5, %7
%25 = phi double [ %23, %7 ], [ 0.000000e+00, %5 ]
ret double %25
}