#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 */
int /*<<< orphan*/ dd_dec(double *, double *);
int /*<<< orphan*/ dd_div(double const *, double *, double *);
int /*<<< orphan*/ dd_mul(double *, double *, double *);
int /*<<< orphan*/ dd_mul_dd_d(double *, double, double *);
int /*<<< orphan*/ dd_nint(double *, double *);
int /*<<< orphan*/ dd_sub(double const *, double *, double *);
double floor(double);
int /*<<< orphan*/ printf(char *);
void dd_reduce_modulo_2pi(const double *x, double *t, int *j, int *k,
                          int *abs_k, int *fail) {
  double q, y[2], z[2], r[2], twopi[2], pi2[2], pi16[2];
  const double twopi_hi = 6.283185307179586232e+00;
  const double twopi_lo = 2.449293598294706414e-16;
  const double pi2_hi = 1.570796326794896558e+00;
  const double pi2_lo = 6.123233995736766036e-17;
  const double pi16_hi = 1.963495408493620697e-01;
  const double pi16_lo = 7.654042494670957545e-18;
  *j = 0;
  *k = 0;
  *abs_k = 0;
  *fail = 0;
  twopi[0] = twopi_hi;
  twopi[1] = twopi_lo;
  pi2[0] = pi2_hi;
  pi2[1] = pi2_lo;
  pi16[0] = pi16_hi;
  pi16[1] = pi16_lo;
  dd_div(x, twopi, y);
  dd_nint(y, z);
  dd_mul(twopi, z, y);
  dd_sub(x, y, r);
  q = floor(r[0] / pi2_hi + 0.5);
  dd_mul_dd_d(pi2, q, y);
  dd_sub(r, y, t);
  *j = (int)q;
  if ((*j < -2) || (*j > 2)) {
    printf("dd_sin: cannot reduce module pi/2");
    *fail = 1;
  } else {
    q = floor(t[0] / pi16_hi + 0.5);
    dd_mul_dd_d(pi16, q, y);
    dd_dec(t, y);
    *k = (int)q;
    if (*k < 0)
      *abs_k = -(*k);
    else
      *abs_k = *k;
    if (*abs_k > 4) {
      printf("dd_sin: cannot reduce module pi/16");
      *fail = 1;
    } else
      *fail = 0;
  }
}


x86 assembly (clang, -O0):
<dd_reduce_modulo_2pi>:
push   %rbp
mov    %rsp,%rbp
sub    $0xd0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
movsd  0xe85(%rip),%xmm0
movsd  %xmm0,-0xa8(%rbp)
ff
movsd  0xe6d(%rip),%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
movsd  0xe3d(%rip),%xmm0
movsd  %xmm0,-0xb8(%rbp)
ff
movsd  0xe45(%rip),%xmm0
movsd  %xmm0,-0xc0(%rbp)
ff
movsd  0xe2d(%rip),%xmm0
movsd  %xmm0,-0xc8(%rbp)
ff
movsd  0xe15(%rip),%xmm0
movsd  %xmm0,-0xd0(%rbp)
ff
mov    -0x18(%rbp),%rax
movl   $0x0,(%rax)
mov    -0x20(%rbp),%rax
movl   $0x0,(%rax)
mov    -0x28(%rbp),%rax
movl   $0x0,(%rax)
mov    -0x30(%rbp),%rax
movl   $0x0,(%rax)
movsd  0xdfd(%rip),%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  0xde8(%rip),%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  0xdbb(%rip),%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
movsd  0xdc3(%rip),%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
movsd  0xdab(%rip),%xmm0
movsd  %xmm0,-0xa0(%rbp)
ff
movsd  0xd93(%rip),%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
mov    -0x8(%rbp),%rdi
lea    -0x80(%rbp),%rsi
lea    -0x50(%rbp),%rdx
call   1050 <dd_div@plt>
lea    -0x50(%rbp),%rdi
lea    -0x60(%rbp),%rsi
call   1070 <dd_nint@plt>
lea    -0x80(%rbp),%rdi
lea    -0x60(%rbp),%rsi
lea    -0x50(%rbp),%rdx
call   1090 <dd_mul@plt>
mov    -0x8(%rbp),%rdi
lea    -0x50(%rbp),%rsi
lea    -0x70(%rbp),%rdx
call   1040 <dd_sub@plt>
movsd  -0x70(%rbp),%xmm0
movsd  0xd36(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  0xd22(%rip),%xmm1
addsd  %xmm1,%xmm0
call   10a0 <floor@plt>
movsd  %xmm0,-0x38(%rbp)
lea    -0x90(%rbp),%rdi
movsd  -0x38(%rbp),%xmm0
lea    -0x50(%rbp),%rsi
call   1080 <dd_mul_dd_d@plt>
lea    -0x70(%rbp),%rdi
lea    -0x50(%rbp),%rsi
mov    -0x10(%rbp),%rdx
call   1040 <dd_sub@plt>
cvttsd2si -0x38(%rbp),%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x18(%rbp),%rax
cmpl   $0xfffffffe,(%rax)
jl     1337 <dd_reduce_modulo_2pi+0x1b7>
mov    -0x18(%rbp),%rax
cmpl   $0x2,(%rax)
jle    1352 <dd_reduce_modulo_2pi+0x1d2>
lea    0xcfa(%rip),%rdi
call   1060 <printf@plt>
mov    -0x30(%rbp),%rax
movl   $0x1,(%rax)
jmp    140c <dd_reduce_modulo_2pi+0x28c>
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xcb6(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  0xc92(%rip),%xmm1
addsd  %xmm1,%xmm0
call   10a0 <floor@plt>
movsd  %xmm0,-0x38(%rbp)
lea    -0xa0(%rbp),%rdi
movsd  -0x38(%rbp),%xmm0
lea    -0x50(%rbp),%rsi
call   1080 <dd_mul_dd_d@plt>
mov    -0x10(%rbp),%rdi
lea    -0x50(%rbp),%rsi
call   1030 <dd_dec@plt>
cvttsd2si -0x38(%rbp),%ecx
mov    -0x20(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x20(%rbp),%rax
cmpl   $0x0,(%rax)
jge    13c9 <dd_reduce_modulo_2pi+0x249>
mov    -0x20(%rbp),%rax
xor    %ecx,%ecx
sub    (%rax),%ecx
mov    -0x28(%rbp),%rax
mov    %ecx,(%rax)
jmp    13d5 <dd_reduce_modulo_2pi+0x255>
mov    -0x20(%rbp),%rax
mov    (%rax),%ecx
mov    -0x28(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x28(%rbp),%rax
cmpl   $0x4,(%rax)
jle    13fd <dd_reduce_modulo_2pi+0x27d>
lea    0xc71(%rip),%rdi
call   1060 <printf@plt>
mov    -0x30(%rbp),%rax
movl   $0x1,(%rax)
jmp    1407 <dd_reduce_modulo_2pi+0x287>
mov    -0x30(%rbp),%rax
movl   $0x0,(%rax)
jmp    140c <dd_reduce_modulo_2pi+0x28c>
add    $0xd0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<dd_reduce_modulo_2pi>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x88,%rsp
mov    %rdx,%rbx
mov    %rsi,%r13
mov    %rdi,%r14
movl   $0x0,(%rdx)
mov    %rcx,0x8(%rsp)
movl   $0x0,(%rcx)
mov    %r8,0x10(%rsp)
movl   $0x0,(%r8)
mov    %r9,0x18(%rsp)
movl   $0x0,(%r9)
movaps 0xe36(%rip),%xmm0
movaps %xmm0,0x40(%rsp)
movaps 0xe3a(%rip),%xmm0
movaps %xmm0,0x30(%rsp)
movaps 0xe3e(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
lea    0x40(%rsp),%r15
lea    0x60(%rsp),%rbp
mov    %r15,%rsi
mov    %rbp,%rdx
call   1050 <dd_div@plt>
lea    0x70(%rsp),%r12
mov    %rbp,%rdi
mov    %r12,%rsi
call   1070 <dd_nint@plt>
mov    %r15,%rdi
mov    %r12,%rsi
mov    %rbp,%rdx
call   1090 <dd_mul@plt>
lea    0x50(%rsp),%r15
mov    %r14,%rdi
mov    %rbp,%rsi
mov    %r15,%rdx
call   1040 <dd_sub@plt>
movsd  0x50(%rsp),%xmm0
divsd  0xdf5(%rip),%xmm0
addsd  0xdf5(%rip),%xmm0
call   10a0 <floor@plt>
movsd  %xmm0,(%rsp)
lea    0x30(%rsp),%rdi
mov    %rbp,%rsi
call   1080 <dd_mul_dd_d@plt>
mov    %r15,%rdi
mov    %rbp,%rsi
mov    %r13,%rdx
call   1040 <dd_sub@plt>
cvttsd2si (%rsp),%eax
mov    %eax,(%rbx)
add    $0xfffffffd,%eax
cmp    $0xfffffffb,%eax
jae    1280 <dd_reduce_modulo_2pi+0x100>
lea    0xdca(%rip),%rdi
jmp    12e5 <dd_reduce_modulo_2pi+0x165>
movsd  0x0(%r13),%xmm0
divsd  0xdb2(%rip),%xmm0
addsd  0xda2(%rip),%xmm0
call   10a0 <floor@plt>
movsd  %xmm0,(%rsp)
lea    0x20(%rsp),%rdi
lea    0x60(%rsp),%rbx
mov    %rbx,%rsi
call   1080 <dd_mul_dd_d@plt>
mov    %r13,%rdi
mov    %rbx,%rsi
call   1030 <dd_dec@plt>
cvttsd2si (%rsp),%eax
mov    %eax,%ecx
neg    %ecx
cmovs  %eax,%ecx
mov    0x8(%rsp),%rdx
mov    %eax,(%rdx)
mov    0x10(%rsp),%rax
mov    %ecx,(%rax)
xor    %eax,%eax
cmp    $0x5,%ecx
jb     12ef <dd_reduce_modulo_2pi+0x16f>
lea    0xd85(%rip),%rdi
call   1060 <printf@plt>
mov    $0x1,%eax
mov    0x18(%rsp),%rcx
mov    %eax,(%rcx)
add    $0x88,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [34 x i8] c"dd_sin: cannot reduce module pi/2\00"
@.str.1 = [35 x i8] c"dd_sin: cannot reduce module pi/16\00"
define void @dd_reduce_modulo_2pi(double* %0, double* %1, i32* %2, i32* %3, i32* %4, i32* %5) {
%7 = alloca double*
%8 = alloca double*
%9 = alloca i32*
%10 = alloca i32*
%11 = alloca i32*
%12 = alloca i32*
%13 = alloca double
%14 = alloca [2 x double]
%15 = alloca [2 x double]
%16 = alloca [2 x double]
%17 = alloca [2 x double]
%18 = alloca [2 x double]
%19 = alloca [2 x double]
%20 = alloca double
%21 = alloca double
%22 = alloca double
%23 = alloca double
%24 = alloca double
%25 = alloca double
store double* %0, double** %7
store double* %1, double** %8
store i32* %2, i32** %9
store i32* %3, i32** %10
store i32* %4, i32** %11
store i32* %5, i32** %12
store double 0x401921FB54442D18, double* %20
store double 0x3CB1A62633145C07, double* %21
store double 0x3FF921FB54442D18, double* %22
store double 0x3C91A62633145C07, double* %23
store double 0x3FC921FB54442D18, double* %24
store double 0x3C61A62633145C07, double* %25
%26 = load i32*, i32** %9
store i32 0, i32* %26
%27 = load i32*, i32** %10
store i32 0, i32* %27
%28 = load i32*, i32** %11
store i32 0, i32* %28
%29 = load i32*, i32** %12
store i32 0, i32* %29
%30 = getelementptr inbounds [2 x double], [2 x double]* %17, i64 0, i64 0
store double 0x401921FB54442D18, double* %30
%31 = getelementptr inbounds [2 x double], [2 x double]* %17, i64 0, i64 1
store double 0x3CB1A62633145C07, double* %31
%32 = getelementptr inbounds [2 x double], [2 x double]* %18, i64 0, i64 0
store double 0x3FF921FB54442D18, double* %32
%33 = getelementptr inbounds [2 x double], [2 x double]* %18, i64 0, i64 1
store double 0x3C91A62633145C07, double* %33
%34 = getelementptr inbounds [2 x double], [2 x double]* %19, i64 0, i64 0
store double 0x3FC921FB54442D18, double* %34
%35 = getelementptr inbounds [2 x double], [2 x double]* %19, i64 0, i64 1
store double 0x3C61A62633145C07, double* %35
%36 = load double*, double** %7
%37 = getelementptr inbounds [2 x double], [2 x double]* %17, i64 0, i64 0
%38 = getelementptr inbounds [2 x double], [2 x double]* %14, i64 0, i64 0
%39 = call i32 @dd_div(double* %36, double* %37, double* %38)
%40 = getelementptr inbounds [2 x double], [2 x double]* %14, i64 0, i64 0
%41 = getelementptr inbounds [2 x double], [2 x double]* %15, i64 0, i64 0
%42 = call i32 @dd_nint(double* %40, double* %41)
%43 = getelementptr inbounds [2 x double], [2 x double]* %17, i64 0, i64 0
%44 = getelementptr inbounds [2 x double], [2 x double]* %15, i64 0, i64 0
%45 = getelementptr inbounds [2 x double], [2 x double]* %14, i64 0, i64 0
%46 = call i32 @dd_mul(double* %43, double* %44, double* %45)
%47 = load double*, double** %7
%48 = getelementptr inbounds [2 x double], [2 x double]* %14, i64 0, i64 0
%49 = getelementptr inbounds [2 x double], [2 x double]* %16, i64 0, i64 0
%50 = call i32 @dd_sub(double* %47, double* %48, double* %49)
%51 = getelementptr inbounds [2 x double], [2 x double]* %16, i64 0, i64 0
%52 = load double, double* %51
%53 = fdiv double %52, 0x3FF921FB54442D18
%54 = fadd double %53, 5.000000e-01
%55 = call double @llvm.floor.f64(double %54)
store double %55, double* %13
%56 = getelementptr inbounds [2 x double], [2 x double]* %18, i64 0, i64 0
%57 = load double, double* %13
%58 = getelementptr inbounds [2 x double], [2 x double]* %14, i64 0, i64 0
%59 = call i32 @dd_mul_dd_d(double* %56, double %57, double* %58)
%60 = getelementptr inbounds [2 x double], [2 x double]* %16, i64 0, i64 0
%61 = getelementptr inbounds [2 x double], [2 x double]* %14, i64 0, i64 0
%62 = load double*, double** %8
%63 = call i32 @dd_sub(double* %60, double* %61, double* %62)
%64 = load double, double* %13
%65 = fptosi double %64 to i32
%66 = load i32*, i32** %9
store i32 %65, i32* %66
%67 = load i32*, i32** %9
%68 = load i32, i32* %67
%69 = icmp slt i32 %68, -2
br i1 %69, label %74, label %70
70: ; preds = %6
%71 = load i32*, i32** %9
%72 = load i32, i32* %71
%73 = icmp sgt i32 %72, 2
br i1 %73, label %74, label %77
74: ; preds = %70, %6
%75 = call i32 @printf(i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str, i64 0, i64 0))
%76 = load i32*, i32** %12
store i32 1, i32* %76
br label %116
77: ; preds = %70
%78 = load double*, double** %8
%79 = getelementptr inbounds double, double* %78, i64 0
%80 = load double, double* %79
%81 = fdiv double %80, 0x3FC921FB54442D18
%82 = fadd double %81, 5.000000e-01
%83 = call double @llvm.floor.f64(double %82)
store double %83, double* %13
%84 = getelementptr inbounds [2 x double], [2 x double]* %19, i64 0, i64 0
%85 = load double, double* %13
%86 = getelementptr inbounds [2 x double], [2 x double]* %14, i64 0, i64 0
%87 = call i32 @dd_mul_dd_d(double* %84, double %85, double* %86)
%88 = load double*, double** %8
%89 = getelementptr inbounds [2 x double], [2 x double]* %14, i64 0, i64 0
%90 = call i32 @dd_dec(double* %88, double* %89)
%91 = load double, double* %13
%92 = fptosi double %91 to i32
%93 = load i32*, i32** %10
store i32 %92, i32* %93
%94 = load i32*, i32** %10
%95 = load i32, i32* %94
%96 = icmp slt i32 %95, 0
br i1 %96, label %97, label %102
97: ; preds = %77
%98 = load i32*, i32** %10
%99 = load i32, i32* %98
%100 = sub nsw i32 0, %99
%101 = load i32*, i32** %11
store i32 %100, i32* %101
br label %106
102: ; preds = %77
%103 = load i32*, i32** %10
%104 = load i32, i32* %103
%105 = load i32*, i32** %11
store i32 %104, i32* %105
br label %106
106: ; preds = %102, %97
%107 = load i32*, i32** %11
%108 = load i32, i32* %107
%109 = icmp sgt i32 %108, 4
br i1 %109, label %110, label %113
110: ; preds = %106
%111 = call i32 @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @.str.1, i64 0, i64 0))
%112 = load i32*, i32** %12
store i32 1, i32* %112
br label %115
113: ; preds = %106
%114 = load i32*, i32** %12
store i32 0, i32* %114
br label %115
115: ; preds = %113, %110
br label %116
116: ; preds = %115, %74
ret void
}

LLVM IR (-O2):
@.str = [34 x i8] c"dd_sin: cannot reduce module pi/2\00"
@.str.1 = [35 x i8] c"dd_sin: cannot reduce module pi/16\00"
define void @dd_reduce_modulo_2pi(double* %0, double* %1, i32* nocapture writeonly %2, i32* nocapture writeonly %3, i32* nocapture writeonly %4, i32* nocapture writeonly %5) {
%7 = alloca [2 x double]
%8 = alloca [2 x double]
%9 = alloca [2 x double]
%10 = alloca <2 x double>
%11 = alloca <2 x double>
%12 = alloca <2 x double>
%13 = bitcast [2 x double]* %7 to i8*
%14 = bitcast [2 x double]* %8 to i8*
%15 = bitcast [2 x double]* %9 to i8*
%16 = bitcast <2 x double>* %10 to i8*
%17 = bitcast <2 x double>* %11 to i8*
%18 = bitcast <2 x double>* %12 to i8*
store i32 0, i32* %2
store i32 0, i32* %3
store i32 0, i32* %4
store i32 0, i32* %5
%19 = getelementptr inbounds <2 x double>, <2 x double>* %10, i64 0, i64 0
store <2 x double> <double 0x401921FB54442D18, double 0x3CB1A62633145C07>, <2 x double>* %10
%20 = getelementptr inbounds <2 x double>, <2 x double>* %11, i64 0, i64 0
store <2 x double> <double 0x3FF921FB54442D18, double 0x3C91A62633145C07>, <2 x double>* %11
store <2 x double> <double 0x3FC921FB54442D18, double 0x3C61A62633145C07>, <2 x double>* %12
%21 = getelementptr inbounds [2 x double], [2 x double]* %7, i64 0, i64 0
%22 = call i32 @dd_div(double* %0, double* %19, double* %21)
%23 = getelementptr inbounds [2 x double], [2 x double]* %8, i64 0, i64 0
%24 = call i32 @dd_nint(double* %21, double* %23)
%25 = call i32 @dd_mul(double* %19, double* %23, double* %21)
%26 = getelementptr inbounds [2 x double], [2 x double]* %9, i64 0, i64 0
%27 = call i32 @dd_sub(double* %0, double* %21, double* %26)
%28 = load double, double* %26
%29 = fdiv double %28, 0x3FF921FB54442D18
%30 = fadd double %29, 5.000000e-01
%31 = call double @llvm.floor.f64(double %30)
%32 = call i32 @dd_mul_dd_d(double* %20, double %31, double* %21)
%33 = call i32 @dd_sub(double* %26, double* %21, double* %1)
%34 = fptosi double %31 to i32
store i32 %34, i32* %2
%35 = add i32 %34, -3
%36 = icmp ult i32 %35, -5
br i1 %36, label %48, label %37
37: ; preds = %6
%38 = getelementptr inbounds <2 x double>, <2 x double>* %12, i64 0, i64 0
%39 = load double, double* %1
%40 = fdiv double %39, 0x3FC921FB54442D18
%41 = fadd double %40, 5.000000e-01
%42 = call double @llvm.floor.f64(double %41)
%43 = call i32 @dd_mul_dd_d(double* %38, double %42, double* %21)
%44 = call i32 @dd_dec(double* %1, double* %21)
%45 = fptosi double %42 to i32
store i32 %45, i32* %3
%46 = call i32 @llvm.abs.i32(i32 %45, i1 true)
store i32 %46, i32* %4
%47 = icmp ugt i32 %46, 4
br i1 %47, label %48, label %51
48: ; preds = %37, %6
%49 = phi i8* [ getelementptr inbounds ([34 x i8], [34 x i8]* @.str, i64 0, i64 0), %6 ], [ getelementptr inbounds ([35 x i8], [35 x i8]* @.str.1, i64 0, i64 0), %37 ]
%50 = call i32 @printf(i8* dereferenceable(1) %49)
br label %51
51: ; preds = %48, %37
%52 = phi i32 [ 0, %37 ], [ 1, %48 ]
store i32 %52, i32* %5
ret void
}