#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 */
scalar_t__ exp(double);
double log(scalar_t__);
double gt_logsum(double p1, double p2) {
  if (p1 > p2)
    return (p1 - p2 > 50.0) ? p1 : p1 + log(1.0 + exp(p2 - p1));
  return (p2 - p1 > 50.0) ? p2 : p2 + log(1.0 + exp(p1 - p2));
}


x86 assembly (clang, -O0):
<gt_logsum>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  -0x10(%rbp),%xmm0
ucomisd -0x18(%rbp),%xmm0
jbe    11c1 <gt_logsum+0xa1>
movsd  -0x10(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
movsd  0xeac(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    116d <gt_logsum+0x4d>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    11b2 <gt_logsum+0x92>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x18(%rbp),%xmm0
subsd  -0x10(%rbp),%xmm0
call   1030 <exp@plt>
cvtsi2sd %rax,%xmm1
movsd  0xe75(%rip),%xmm0
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x28(%rbp),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    123b <gt_logsum+0x11b>
movsd  -0x18(%rbp),%xmm0
subsd  -0x10(%rbp),%xmm0
movsd  0xe2d(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    11ec <gt_logsum+0xcc>
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    1231 <gt_logsum+0x111>
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x10(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
call   1030 <exp@plt>
cvtsi2sd %rax,%xmm1
movsd  0xdf6(%rip),%xmm0
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x38(%rbp),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<gt_logsum>:
push   %rax
ucomisd %xmm1,%xmm0
jbe    113f <gt_logsum+0x1f>
movapd %xmm0,%xmm2
subsd  %xmm1,%xmm2
ucomisd 0xec9(%rip),%xmm2
jbe    115c <gt_logsum+0x3c>
movapd %xmm0,%xmm1
jmp    1191 <gt_logsum+0x71>
movapd %xmm1,%xmm2
subsd  %xmm0,%xmm2
ucomisd 0xeb1(%rip),%xmm2
ja     1191 <gt_logsum+0x71>
subsd  %xmm1,%xmm0
movsd  %xmm1,(%rsp)
jmp    1169 <gt_logsum+0x49>
movsd  %xmm0,(%rsp)
subsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
call   1030 <exp@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  0xe8a(%rip),%xmm0
cvttsd2si %xmm0,%rdi
call   1040 <log@plt>
movapd %xmm0,%xmm1
addsd  (%rsp),%xmm1
movapd %xmm1,%xmm0
pop    %rax
ret

LLVM IR (-O0):
define double @gt_logsum(double %0, double %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca double
store double %0, double* %4
store double %1, double* %5
%6 = load double, double* %4
%7 = load double, double* %5
%8 = fcmp ogt double %6, %7
br i1 %8, label %9, label %29
9: ; preds = %2
%10 = load double, double* %4
%11 = load double, double* %5
%12 = fsub double %10, %11
%13 = fcmp ogt double %12, 5.000000e+01
br i1 %13, label %14, label %16
14: ; preds = %9
%15 = load double, double* %4
br label %27
16: ; preds = %9
%17 = load double, double* %4
%18 = load double, double* %5
%19 = load double, double* %4
%20 = fsub double %18, %19
%21 = call i64 @exp(double %20)
%22 = sitofp i64 %21 to double
%23 = fadd double 1.000000e+00, %22
%24 = fptosi double %23 to i64
%25 = call double @log(i64 %24)
%26 = fadd double %17, %25
br label %27
27: ; preds = %16, %14
%28 = phi double [ %15, %14 ], [ %26, %16 ]
store double %28, double* %3
br label %49
29: ; preds = %2
%30 = load double, double* %5
%31 = load double, double* %4
%32 = fsub double %30, %31
%33 = fcmp ogt double %32, 5.000000e+01
br i1 %33, label %34, label %36
34: ; preds = %29
%35 = load double, double* %5
br label %47
36: ; preds = %29
%37 = load double, double* %5
%38 = load double, double* %4
%39 = load double, double* %5
%40 = fsub double %38, %39
%41 = call i64 @exp(double %40)
%42 = sitofp i64 %41 to double
%43 = fadd double 1.000000e+00, %42
%44 = fptosi double %43 to i64
%45 = call double @log(i64 %44)
%46 = fadd double %37, %45
br label %47
47: ; preds = %36, %34
%48 = phi double [ %35, %34 ], [ %46, %36 ]
store double %48, double* %3
br label %49
49: ; preds = %47, %27
%50 = load double, double* %3
ret double %50
}

LLVM IR (-O2):
define double @gt_logsum(double %0, double %1) {
%3 = fcmp ogt double %0, %1
br i1 %3, label %4, label %9
4: ; preds = %2
%5 = fsub double %0, %1
%6 = fcmp ogt double %5, 5.000000e+01
br i1 %6, label %23, label %7
7: ; preds = %4
%8 = fsub double %1, %0
br label %14
9: ; preds = %2
%10 = fsub double %1, %0
%11 = fcmp ogt double %10, 5.000000e+01
br i1 %11, label %23, label %12
12: ; preds = %9
%13 = fsub double %0, %1
br label %14
14: ; preds = %7, %12
%15 = phi double [ %13, %12 ], [ %8, %7 ]
%16 = phi double [ %1, %12 ], [ %0, %7 ]
%17 = tail call i64 @exp(double %15)
%18 = sitofp i64 %17 to double
%19 = fadd double %18, 1.000000e+00
%20 = fptosi double %19 to i64
%21 = tail call double @log(i64 %20)
%22 = fadd double %21, %16
br label %23
23: ; preds = %14, %9, %4
%24 = phi double [ %0, %4 ], [ %1, %9 ], [ %22, %14 ]
ret double %24
}