#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 fmod(double, int);
double nasty_function(double x) {
  x = 4 / 3.14159265358979323846 * fmod(x, 2 * 3.14159265358979323846);
  if (x < 1)
    return x;
  else if (x < 2)
    return 1;
  else if (x < 3)
    return x - 2;
  else if (x < 4)
    return 1;
  else if (x < 5)
    return x - 3;
  else if (x < 6)
    return -x + 7;
  else if (x < 7)
    return 1;
  else
    return x - 6;
}


x86 assembly (clang, -O0):
<nasty_function>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
mov    $0x6,%edi
call   1030 <fmod@plt>
cvtsi2sd %eax,%xmm1
movsd  0xed0(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xeb7(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1163 <nasty_function+0x53>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1289 <nasty_function+0x179>
movsd  0xea5(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1188 <nasty_function+0x78>
movsd  0xe82(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1289 <nasty_function+0x179>
movsd  0xe88(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    11b6 <nasty_function+0xa6>
movsd  -0x10(%rbp),%xmm0
movsd  0xe68(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1289 <nasty_function+0x179>
movsd  0xe62(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    11db <nasty_function+0xcb>
movsd  0xe2f(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1289 <nasty_function+0x179>
movsd  0xe45(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1209 <nasty_function+0xf9>
movsd  -0x10(%rbp),%xmm0
movsd  0xe1d(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1289 <nasty_function+0x179>
movsd  0xe1f(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    124e <nasty_function+0x13e>
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xdf8(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1289 <nasty_function+0x179>
movsd  0xde2(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1273 <nasty_function+0x163>
movsd  0xd97(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1289 <nasty_function+0x179>
movsd  -0x10(%rbp),%xmm0
movsd  0xdb0(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<nasty_function>:
push   %rax
mov    $0x6,%edi
call   1030 <fmod@plt>
cvtsi2sd %eax,%xmm1
mulsd  0xed9(%rip),%xmm1
movsd  0xed9(%rip),%xmm0
ucomisd %xmm1,%xmm0
ja     11b3 <nasty_function+0xa3>
movsd  0xed3(%rip),%xmm2
ucomisd %xmm1,%xmm2
ja     11b7 <nasty_function+0xa7>
movsd  0xecd(%rip),%xmm2
ucomisd %xmm1,%xmm2
jbe    115b <nasty_function+0x4b>
addsd  0xef7(%rip),%xmm1
jmp    11b3 <nasty_function+0xa3>
movsd  0xebd(%rip),%xmm2
ucomisd %xmm1,%xmm2
ja     11b7 <nasty_function+0xa7>
movsd  0xeb7(%rip),%xmm2
ucomisd %xmm1,%xmm2
jbe    1181 <nasty_function+0x71>
addsd  0xec9(%rip),%xmm1
jmp    11b3 <nasty_function+0xa3>
movsd  0xea7(%rip),%xmm2
ucomisd %xmm1,%xmm2
jbe    119d <nasty_function+0x8d>
movsd  0xea1(%rip),%xmm0
subsd  %xmm1,%xmm0
pop    %rax
ret
movsd  0xe93(%rip),%xmm2
ucomisd %xmm1,%xmm2
ja     11b7 <nasty_function+0xa7>
addsd  0xe8d(%rip),%xmm1
movapd %xmm1,%xmm0
pop    %rax
ret

LLVM IR (-O0):
define double @nasty_function(double %0) {
%2 = alloca double
%3 = alloca double
store double %0, double* %3
%4 = load double, double* %3
%5 = call i32 @fmod(double %4, i32 6)
%6 = sitofp i32 %5 to double
%7 = fmul double 0x3FF45F306DC9C883, %6
store double %7, double* %3
%8 = load double, double* %3
%9 = fcmp olt double %8, 1.000000e+00
br i1 %9, label %10, label %12
10: ; preds = %1
%11 = load double, double* %3
store double %11, double* %2
br label %46
12: ; preds = %1
%13 = load double, double* %3
%14 = fcmp olt double %13, 2.000000e+00
br i1 %14, label %15, label %16
15: ; preds = %12
store double 1.000000e+00, double* %2
br label %46
16: ; preds = %12
%17 = load double, double* %3
%18 = fcmp olt double %17, 3.000000e+00
br i1 %18, label %19, label %22
19: ; preds = %16
%20 = load double, double* %3
%21 = fsub double %20, 2.000000e+00
store double %21, double* %2
br label %46
22: ; preds = %16
%23 = load double, double* %3
%24 = fcmp olt double %23, 4.000000e+00
br i1 %24, label %25, label %26
25: ; preds = %22
store double 1.000000e+00, double* %2
br label %46
26: ; preds = %22
%27 = load double, double* %3
%28 = fcmp olt double %27, 5.000000e+00
br i1 %28, label %29, label %32
29: ; preds = %26
%30 = load double, double* %3
%31 = fsub double %30, 3.000000e+00
store double %31, double* %2
br label %46
32: ; preds = %26
%33 = load double, double* %3
%34 = fcmp olt double %33, 6.000000e+00
br i1 %34, label %35, label %39
35: ; preds = %32
%36 = load double, double* %3
%37 = fneg double %36
%38 = fadd double %37, 7.000000e+00
store double %38, double* %2
br label %46
39: ; preds = %32
%40 = load double, double* %3
%41 = fcmp olt double %40, 7.000000e+00
br i1 %41, label %42, label %43
42: ; preds = %39
store double 1.000000e+00, double* %2
br label %46
43: ; preds = %39
%44 = load double, double* %3
%45 = fsub double %44, 6.000000e+00
store double %45, double* %2
br label %46
46: ; preds = %43, %42, %35, %29, %25, %19, %15, %10
%47 = load double, double* %2
ret double %47
}

LLVM IR (-O2):
define double @nasty_function(double %0) {
%2 = tail call i32 @fmod(double %0, i32 6)
%3 = sitofp i32 %2 to double
%4 = fmul double %3, 0x3FF45F306DC9C883
%5 = fcmp olt double %4, 1.000000e+00
br i1 %5, label %26, label %6
6: ; preds = %1
%7 = fcmp olt double %4, 2.000000e+00
br i1 %7, label %26, label %8
8: ; preds = %6
%9 = fcmp olt double %4, 3.000000e+00
br i1 %9, label %10, label %12
10: ; preds = %8
%11 = fadd double %4, -2.000000e+00
br label %26
12: ; preds = %8
%13 = fcmp olt double %4, 4.000000e+00
br i1 %13, label %26, label %14
14: ; preds = %12
%15 = fcmp olt double %4, 5.000000e+00
br i1 %15, label %16, label %18
16: ; preds = %14
%17 = fadd double %4, -3.000000e+00
br label %26
18: ; preds = %14
%19 = fcmp olt double %4, 6.000000e+00
br i1 %19, label %20, label %22
20: ; preds = %18
%21 = fsub double 7.000000e+00, %4
br label %26
22: ; preds = %18
%23 = fcmp olt double %4, 7.000000e+00
br i1 %23, label %26, label %24
24: ; preds = %22
%25 = fadd double %4, -6.000000e+00
br label %26
26: ; preds = %22, %12, %6, %1, %24, %20, %16, %10
%27 = phi double [ %11, %10 ], [ %17, %16 ], [ %21, %20 ], [ %25, %24 ], [ %4, %1 ], [ 1.000000e+00, %6 ], [ 1.000000e+00, %12 ], [ 1.000000e+00, %22 ]
ret double %27
}