#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 */
typedef int /*<<< orphan*/ x;
typedef int /*<<< orphan*/ fn;

/* Variables and functions */
scalar_t__ __isnanl(double);
int /*<<< orphan*/ finite(double);
scalar_t__ isnan(double);
scalar_t__ isnanf(double);
double rint(double);
double scalbn(double, int);
double scalb(double x, double fn) {
  if (((sizeof(x) == sizeof(float))    ? isnanf(x)
       : (sizeof(x) == sizeof(double)) ? isnan(x)
                                       : __isnanl(x)) ||
      ((sizeof(fn) == sizeof(float))    ? isnanf(fn)
       : (sizeof(fn) == sizeof(double)) ? isnan(fn)
                                        : __isnanl(fn)))
    return x * fn;
  if (!finite(fn)) {
    if (fn > 0.0)
      return x * fn;
    else
      return x / (-fn);
  }
  if (rint(fn) != fn)
    return (fn - fn) / (fn - fn);
  if (fn > 65000.0)
    return scalbn(x, 65000);
  if (-fn > 65000.0)
    return scalbn(x, -65000);
  return scalbn(x, (int)fn);
}


x86 assembly (clang, -O0):
<scalb>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
xor    %eax,%eax
test   $0x1,%al
jne    1171 <scalb+0x21>
jmp    118a <scalb+0x3a>
movsd  -0x10(%rbp),%xmm0
call   1030 <isnanf@plt>
cmp    $0x0,%rax
jne    122a <scalb+0xda>
jmp    11c6 <scalb+0x76>
mov    $0x1,%al
test   $0x1,%al
jne    1199 <scalb+0x49>
jmp    11b2 <scalb+0x62>
movsd  -0x10(%rbp),%xmm0
call   1070 <isnan@plt>
cmp    $0x0,%rax
jne    122a <scalb+0xda>
jmp    11c6 <scalb+0x76>
movsd  -0x10(%rbp),%xmm0
call   1050 <__isnanl@plt>
cmp    $0x0,%rax
jne    122a <scalb+0xda>
xor    %eax,%eax
test   $0x1,%al
jne    11d5 <scalb+0x85>
jmp    11ee <scalb+0x9e>
movsd  -0x18(%rbp),%xmm0
call   1030 <isnanf@plt>
cmp    $0x0,%rax
jne    122a <scalb+0xda>
jmp    123e <scalb+0xee>
mov    $0x1,%al
test   $0x1,%al
jne    11fd <scalb+0xad>
jmp    1216 <scalb+0xc6>
movsd  -0x18(%rbp),%xmm0
call   1070 <isnan@plt>
cmp    $0x0,%rax
jne    122a <scalb+0xda>
jmp    123e <scalb+0xee>
movsd  -0x18(%rbp),%xmm0
call   1050 <__isnanl@plt>
cmp    $0x0,%rax
je     123e <scalb+0xee>
movsd  -0x10(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1382 <scalb+0x232>
movsd  -0x18(%rbp),%xmm0
movaps 0xdc6(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  0xdaa(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    12b5 <scalb+0x165>
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    1286 <scalb+0x136>
movsd  -0x10(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1382 <scalb+0x232>
movsd  -0x10(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1382 <scalb+0x232>
movsd  -0x18(%rbp),%xmm0
call   1040 <rint@plt>
ucomisd -0x18(%rbp),%xmm0
jne    12d5 <scalb+0x185>
jp     12d5 <scalb+0x185>
jmp    12f7 <scalb+0x1a7>
movsd  -0x18(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
subsd  -0x18(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1382 <scalb+0x232>
movsd  -0x18(%rbp),%xmm0
movsd  0xd04(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1327 <scalb+0x1d7>
movsd  -0x10(%rbp),%xmm0
mov    $0xfde8,%edi
call   1060 <scalbn@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    1382 <scalb+0x232>
movsd  -0x18(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xcbd(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    136e <scalb+0x21e>
movsd  -0x10(%rbp),%xmm0
mov    $0xffff0218,%edi
call   1060 <scalbn@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    1382 <scalb+0x232>
movsd  -0x10(%rbp),%xmm0
cvttsd2si -0x18(%rbp),%edi
call   1060 <scalbn@plt>
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<scalb>:
sub    $0x18,%rsp
movapd %xmm1,(%rsp)
movsd  %xmm0,0x10(%rsp)
call   1050 <isnan@plt>
test   %rax,%rax
jne    1158 <scalb+0x28>
movapd (%rsp),%xmm0
call   1050 <isnan@plt>
test   %rax,%rax
je     1168 <scalb+0x38>
movsd  0x10(%rsp),%xmm0
mulsd  (%rsp),%xmm0
add    $0x18,%rsp
ret
movapd 0xe90(%rip),%xmm0
andpd  (%rsp),%xmm0
ucomisd 0xea3(%rip),%xmm0
je     11a4 <scalb+0x74>
movapd (%rsp),%xmm0
call   1030 <rint@plt>
ucomisd (%rsp),%xmm0
jne    1192 <scalb+0x62>
jnp    11cf <scalb+0x9f>
movapd (%rsp),%xmm0
subsd  %xmm0,%xmm0
divsd  %xmm0,%xmm0
add    $0x18,%rsp
ret
xorpd  %xmm0,%xmm0
movapd (%rsp),%xmm1
ucomisd %xmm0,%xmm1
ja     1158 <scalb+0x28>
movapd (%rsp),%xmm1
xorpd  0xe50(%rip),%xmm1
movsd  0x10(%rsp),%xmm0
divsd  %xmm1,%xmm0
add    $0x18,%rsp
ret
movapd (%rsp),%xmm0
ucomisd 0xe4c(%rip),%xmm0
jbe    11f2 <scalb+0xc2>
movsd  0x10(%rsp),%xmm0
mov    $0xfde8,%edi
add    $0x18,%rsp
jmp    1040 <scalbn@plt>
movsd  0xe36(%rip),%xmm0
ucomisd (%rsp),%xmm0
movsd  0x10(%rsp),%xmm0
jbe    1215 <scalb+0xe5>
mov    $0xffff0218,%edi
add    $0x18,%rsp
jmp    1040 <scalbn@plt>
cvttsd2si (%rsp),%edi
add    $0x18,%rsp
jmp    1040 <scalbn@plt>

LLVM IR (-O0):
define double @scalb(double %0, double %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca double
store double %0, double* %4
store double %1, double* %5
br i1 false, label %6, label %10
6: ; preds = %2
%7 = load double, double* %4
%8 = call i64 @isnanf(double %7)
%9 = icmp ne i64 %8, 0
br i1 %9, label %33, label %19
10: ; preds = %2
br i1 true, label %11, label %15
11: ; preds = %10
%12 = load double, double* %4
%13 = call i64 @isnan(double %12)
%14 = icmp ne i64 %13, 0
br i1 %14, label %33, label %19
15: ; preds = %10
%16 = load double, double* %4
%17 = call i64 @__isnanl(double %16)
%18 = icmp ne i64 %17, 0
br i1 %18, label %33, label %19
19: ; preds = %15, %11, %6
br i1 false, label %20, label %24
20: ; preds = %19
%21 = load double, double* %5
%22 = call i64 @isnanf(double %21)
%23 = icmp ne i64 %22, 0
br i1 %23, label %33, label %37
24: ; preds = %19
br i1 true, label %25, label %29
25: ; preds = %24
%26 = load double, double* %5
%27 = call i64 @isnan(double %26)
%28 = icmp ne i64 %27, 0
br i1 %28, label %33, label %37
29: ; preds = %24
%30 = load double, double* %5
%31 = call i64 @__isnanl(double %30)
%32 = icmp ne i64 %31, 0
br i1 %32, label %33, label %37
33: ; preds = %29, %25, %20, %15, %11, %6
%34 = load double, double* %4
%35 = load double, double* %5
%36 = fmul double %34, %35
store double %36, double* %3
br label %84
37: ; preds = %29, %25, %20
%38 = load double, double* %5
%39 = call double @llvm.fabs.f64(double %38)
%40 = fcmp one double %39, 0x7FF0000000000000
br i1 %40, label %53, label %41
41: ; preds = %37
%42 = load double, double* %5
%43 = fcmp ogt double %42, 0.000000e+00
br i1 %43, label %44, label %48
44: ; preds = %41
%45 = load double, double* %4
%46 = load double, double* %5
%47 = fmul double %45, %46
store double %47, double* %3
br label %84
48: ; preds = %41
%49 = load double, double* %4
%50 = load double, double* %5
%51 = fneg double %50
%52 = fdiv double %49, %51
store double %52, double* %3
br label %84
53: ; preds = %37
%54 = load double, double* %5
%55 = call double @llvm.rint.f64(double %54)
%56 = load double, double* %5
%57 = fcmp une double %55, %56
br i1 %57, label %58, label %66
58: ; preds = %53
%59 = load double, double* %5
%60 = load double, double* %5
%61 = fsub double %59, %60
%62 = load double, double* %5
%63 = load double, double* %5
%64 = fsub double %62, %63
%65 = fdiv double %61, %64
store double %65, double* %3
br label %84
66: ; preds = %53
%67 = load double, double* %5
%68 = fcmp ogt double %67, 6.500000e+04
br i1 %68, label %69, label %72
69: ; preds = %66
%70 = load double, double* %4
%71 = call double @scalbn(double %70, i32 65000)
store double %71, double* %3
br label %84
72: ; preds = %66
%73 = load double, double* %5
%74 = fneg double %73
%75 = fcmp ogt double %74, 6.500000e+04
br i1 %75, label %76, label %79
76: ; preds = %72
%77 = load double, double* %4
%78 = call double @scalbn(double %77, i32 -65000)
store double %78, double* %3
br label %84
79: ; preds = %72
%80 = load double, double* %4
%81 = load double, double* %5
%82 = fptosi double %81 to i32
%83 = call double @scalbn(double %80, i32 %82)
store double %83, double* %3
br label %84
84: ; preds = %79, %76, %69, %58, %48, %44, %33
%85 = load double, double* %3
ret double %85
}

LLVM IR (-O2):
define double @scalb(double %0, double %1) {
%3 = tail call i64 @isnan(double %0)
%4 = icmp eq i64 %3, 0
br i1 %4, label %5, label %8
5: ; preds = %2
%6 = tail call i64 @isnan(double %1)
%7 = icmp eq i64 %6, 0
br i1 %7, label %10, label %8
8: ; preds = %5, %2
%9 = fmul double %0, %1
br label %37
10: ; preds = %5
%11 = tail call double @llvm.fabs.f64(double %1)
%12 = fcmp ueq double %11, 0x7FF0000000000000
br i1 %12, label %13, label %20
13: ; preds = %10
%14 = fcmp ogt double %1, 0.000000e+00
br i1 %14, label %15, label %17
15: ; preds = %13
%16 = fmul double %0, %1
br label %37
17: ; preds = %13
%18 = fneg double %1
%19 = fdiv double %0, %18
br label %37
20: ; preds = %10
%21 = tail call double @llvm.rint.f64(double %1)
%22 = fcmp une double %21, %1
br i1 %22, label %23, label %26
23: ; preds = %20
%24 = fsub double %1, %1
%25 = fdiv double %24, %24
br label %37
26: ; preds = %20
%27 = fcmp ogt double %1, 6.500000e+04
br i1 %27, label %28, label %30
28: ; preds = %26
%29 = tail call double @scalbn(double %0, i32 65000)
br label %37
30: ; preds = %26
%31 = fcmp olt double %1, -6.500000e+04
br i1 %31, label %32, label %34
32: ; preds = %30
%33 = tail call double @scalbn(double %0, i32 -65000)
br label %37
34: ; preds = %30
%35 = fptosi double %1 to i32
%36 = tail call double @scalbn(double %0, i32 %35)
br label %37
37: ; preds = %34, %32, %28, %23, %17, %15, %8
%38 = phi double [ %9, %8 ], [ %25, %23 ], [ %29, %28 ], [ %33, %32 ], [ %36, %34 ], [ %16, %15 ], [ %19, %17 ]
ret double %38
}