#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 */
long double __builtin_pack_longdouble(double, double);
double __builtin_unpack_longdouble(long double, int);
int /*<<< orphan*/ abort();
double pow(double, int);
int main(void) {
  double high = pow(2.0, 60);
  double low = 2.0;
  long double a = ((long double)high) + ((long double)low);
  double x0 = __builtin_unpack_longdouble(a, 0);
  double x1 = __builtin_unpack_longdouble(a, 1);
  long double b = __builtin_pack_longdouble(x0, x1);
  if (high != x0)
    abort();
  if (low != x1)
    abort();
  if (a != b)
    abort();
  if (x0 != high)
    abort();
  if (x1 != low)
    abort();
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
movl   $0x0,-0x4(%rbp)
movsd  0xea9(%rip),%xmm0
mov    $0x3c,%edi
call   1060 <pow@plt>
movsd  %xmm0,-0x10(%rbp)
movabs $0x4000000000000000,%rax
mov    %rax,-0x18(%rbp)
fldl   -0x10(%rbp)
fldl   -0x18(%rbp)
faddp  %st,%st(1)
fstpt  -0x30(%rbp)
fldt   -0x30(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
xor    %edi,%edi
call   1050 <__builtin_unpack_longdouble@plt>
movsd  %xmm0,-0x38(%rbp)
fldt   -0x30(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
mov    $0x1,%edi
call   1050 <__builtin_unpack_longdouble@plt>
movsd  %xmm0,-0x40(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm1
call   1040 <__builtin_pack_longdouble@plt>
fstpt  -0x50(%rbp)
movsd  -0x10(%rbp),%xmm0
ucomisd -0x38(%rbp),%xmm0
jne    11d7 <main+0x97>
jp     11d7 <main+0x97>
jmp    11de <main+0x9e>
mov    $0x0,%al
call   1030 <abort@plt>
movsd  -0x18(%rbp),%xmm0
ucomisd -0x40(%rbp),%xmm0
jne    11f9 <main+0xb9>
jp     11f9 <main+0xb9>
jmp    1200 <main+0xc0>
mov    $0x0,%al
call   1030 <abort@plt>
fldt   -0x30(%rbp)
fldt   -0x50(%rbp)
fxch   %st(1)
fucomip %st(1),%st
fstp   %st(0)
jne    121d <main+0xdd>
jp     121d <main+0xdd>
jmp    1224 <main+0xe4>
mov    $0x0,%al
call   1030 <abort@plt>
movsd  -0x38(%rbp),%xmm0
ucomisd -0x10(%rbp),%xmm0
jne    123f <main+0xff>
jp     123f <main+0xff>
jmp    1246 <main+0x106>
mov    $0x0,%al
call   1030 <abort@plt>
movsd  -0x40(%rbp),%xmm0
ucomisd -0x18(%rbp),%xmm0
jne    1261 <main+0x121>
jp     1261 <main+0x121>
jmp    1268 <main+0x128>
mov    $0x0,%al
call   1030 <abort@plt>
xor    %eax,%eax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
sub    $0x48,%rsp
movsd  0xeb4(%rip),%xmm0
mov    $0x3c,%edi
call   1060 <pow@plt>
movsd  %xmm0,0x38(%rsp)
movsd  %xmm0,0x40(%rsp)
fldl   0x40(%rsp)
fadds  0xe9c(%rip)
fld    %st(0)
fstpt  0x24(%rsp)
fstpt  (%rsp)
xor    %edi,%edi
call   1050 <__builtin_unpack_longdouble@plt>
movsd  %xmm0,0x18(%rsp)
fldt   0x24(%rsp)
fstpt  (%rsp)
mov    $0x1,%edi
call   1050 <__builtin_unpack_longdouble@plt>
movaps %xmm0,%xmm1
movsd  0x18(%rsp),%xmm0
movsd  %xmm1,0x30(%rsp)
call   1040 <__builtin_pack_longdouble@plt>
movsd  0x38(%rsp),%xmm0
ucomisd 0x18(%rsp),%xmm0
jne    11dc <main+0x9c>
jp     11dc <main+0x9c>
movsd  0x30(%rsp),%xmm0
ucomisd 0xe3b(%rip),%xmm0
jne    11dc <main+0x9c>
jp     11dc <main+0x9c>
fldt   0x24(%rsp)
fucomip %st(1),%st
fstp   %st(0)
jne    11de <main+0x9e>
jp     11de <main+0x9e>
xor    %eax,%eax
add    $0x48,%rsp
ret
fstp   %st(0)
xor    %eax,%eax
call   1030 <abort@plt>

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

LLVM IR (-O2):
define i32 @main() {
%1 = tail call double @pow(double 2.000000e+00, i32 60)
%2 = fpext double %1 to x86_fp80
%3 = fadd x86_fp80 %2, 0xK40008000000000000000
%4 = tail call double @__builtin_unpack_longdouble(x86_fp80 %3, i32 0)
%5 = tail call double @__builtin_unpack_longdouble(x86_fp80 %3, i32 1)
%6 = tail call x86_fp80 @__builtin_pack_longdouble(double %4, double %5)
%7 = fcmp une double %1, %4
br i1 %7, label %8, label %10
8: ; preds = %0
%9 = tail call i32 (...) @abort()
unreachable
10: ; preds = %0
%11 = fcmp une double %5, 2.000000e+00
br i1 %11, label %12, label %14
12: ; preds = %10
%13 = tail call i32 (...) @abort()
unreachable
14: ; preds = %10
%15 = fcmp une x86_fp80 %3, %6
br i1 %15, label %16, label %18
16: ; preds = %14
%17 = tail call i32 (...) @abort()
unreachable
18: ; preds = %14
ret i32 0
}