#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 */
double floor(double);
double fmod(double x, double y) {
  if (y == 0.0)
    return x;
  double m = x - y * floor(x / y);
  if (y > 0.0) {
    if (m >= y)
      return 0.0;
    if (m < 0.0) {
      if ((y + m) == y)
        return 0.0;
      else
        return y + m;
    }
  } else {
    if (m <= y)
      return 0.0;
    if (m > 0.0) {
      if ((y + m) == y)
        return 0.0;
      else
        return y + m;
    }
  }
  return m;
}


x86 assembly (clang, -O0):
<fmod>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1149 <fmod+0x39>
jp     1149 <fmod+0x39>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1299 <fmod+0x189>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x10(%rbp),%xmm0
divsd  -0x18(%rbp),%xmm0
call   1030 <floor@plt>
movsd  -0x30(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x28(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    121b <fmod+0x10b>
movsd  -0x20(%rbp),%xmm0
ucomisd -0x18(%rbp),%xmm0
jb     11cc <fmod+0xbc>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1299 <fmod+0x189>
xorps  %xmm0,%xmm0
ucomisd -0x20(%rbp),%xmm0
jbe    1216 <fmod+0x106>
movsd  -0x18(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
ucomisd -0x18(%rbp),%xmm0
jne    1202 <fmod+0xf2>
jp     1202 <fmod+0xf2>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1299 <fmod+0x189>
movsd  -0x18(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1299 <fmod+0x189>
jmp    128f <fmod+0x17f>
movsd  -0x20(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jb     123c <fmod+0x12c>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1299 <fmod+0x189>
movsd  -0x20(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    128a <fmod+0x17a>
movsd  -0x18(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
ucomisd -0x18(%rbp),%xmm0
jne    1276 <fmod+0x166>
jp     1276 <fmod+0x166>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1299 <fmod+0x189>
movsd  -0x18(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1299 <fmod+0x189>
jmp    128f <fmod+0x17f>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<fmod>:
movapd %xmm0,%xmm2
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm1
jne    1125 <fmod+0x15>
jp     1125 <fmod+0x15>
movapd %xmm2,%xmm0
ret
sub    $0x28,%rsp
movapd %xmm2,%xmm0
divsd  %xmm1,%xmm0
movapd %xmm1,0x10(%rsp)
movapd %xmm2,(%rsp)
call   1030 <floor@plt>
movapd (%rsp),%xmm2
movapd 0x10(%rsp),%xmm1
mulsd  %xmm1,%xmm0
subsd  %xmm0,%xmm2
ucomisd 0xea4(%rip),%xmm1
lea    0x28(%rsp),%rsp
xorpd  %xmm0,%xmm0
jbe    1179 <fmod+0x69>
ucomisd %xmm1,%xmm2
jae    119a <fmod+0x8a>
xorpd  %xmm0,%xmm0
ucomisd %xmm2,%xmm0
ja     1189 <fmod+0x79>
jmp    1120 <fmod+0x10>
ucomisd %xmm2,%xmm1
jae    119a <fmod+0x8a>
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm2
jbe    1120 <fmod+0x10>
addsd  %xmm1,%xmm2
cmpeqsd %xmm2,%xmm1
andnpd %xmm2,%xmm1
movapd %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @fmod(double %0, double %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca double
store double %0, double* %4
store double %1, double* %5
%7 = load double, double* %5
%8 = fcmp oeq double %7, 0.000000e+00
br i1 %8, label %9, label %11
9: ; preds = %2
%10 = load double, double* %4
store double %10, double* %3
br label %64
11: ; preds = %2
%12 = load double, double* %4
%13 = load double, double* %5
%14 = load double, double* %4
%15 = load double, double* %5
%16 = fdiv double %14, %15
%17 = call double @llvm.floor.f64(double %16)
%18 = fneg double %13
%19 = call double @llvm.fmuladd.f64(double %18, double %17, double %12)
store double %19, double* %6
%20 = load double, double* %5
%21 = fcmp ogt double %20, 0.000000e+00
br i1 %21, label %22, label %42
22: ; preds = %11
%23 = load double, double* %6
%24 = load double, double* %5
%25 = fcmp oge double %23, %24
br i1 %25, label %26, label %27
26: ; preds = %22
store double 0.000000e+00, double* %3
br label %64
27: ; preds = %22
%28 = load double, double* %6
%29 = fcmp olt double %28, 0.000000e+00
br i1 %29, label %30, label %41
30: ; preds = %27
%31 = load double, double* %5
%32 = load double, double* %6
%33 = fadd double %31, %32
%34 = load double, double* %5
%35 = fcmp oeq double %33, %34
br i1 %35, label %36, label %37
36: ; preds = %30
store double 0.000000e+00, double* %3
br label %64
37: ; preds = %30
%38 = load double, double* %5
%39 = load double, double* %6
%40 = fadd double %38, %39
store double %40, double* %3
br label %64
41: ; preds = %27
br label %62
42: ; preds = %11
%43 = load double, double* %6
%44 = load double, double* %5
%45 = fcmp ole double %43, %44
br i1 %45, label %46, label %47
46: ; preds = %42
store double 0.000000e+00, double* %3
br label %64
47: ; preds = %42
%48 = load double, double* %6
%49 = fcmp ogt double %48, 0.000000e+00
br i1 %49, label %50, label %61
50: ; preds = %47
%51 = load double, double* %5
%52 = load double, double* %6
%53 = fadd double %51, %52
%54 = load double, double* %5
%55 = fcmp oeq double %53, %54
br i1 %55, label %56, label %57
56: ; preds = %50
store double 0.000000e+00, double* %3
br label %64
57: ; preds = %50
%58 = load double, double* %5
%59 = load double, double* %6
%60 = fadd double %58, %59
store double %60, double* %3
br label %64
61: ; preds = %47
br label %62
62: ; preds = %61, %41
%63 = load double, double* %6
store double %63, double* %3
br label %64
64: ; preds = %62, %57, %56, %46, %37, %36, %26, %9
%65 = load double, double* %3
ret double %65
}

LLVM IR (-O2):
define double @fmod(double %0, double %1) {
%3 = fcmp oeq double %1, 0.000000e+00
br i1 %3, label %26, label %4
4: ; preds = %2
%5 = fdiv double %0, %1
%6 = tail call double @llvm.floor.f64(double %5)
%7 = fneg double %1
%8 = tail call double @llvm.fmuladd.f64(double %7, double %6, double %0)
%9 = fcmp ogt double %1, 0.000000e+00
br i1 %9, label %10, label %18
10: ; preds = %4
%11 = fcmp ult double %8, %1
br i1 %11, label %12, label %26
12: ; preds = %10
%13 = fcmp olt double %8, 0.000000e+00
br i1 %13, label %14, label %26
14: ; preds = %12
%15 = fadd double %8, %1
%16 = fcmp oeq double %15, %1
%17 = select i1 %16, double 0.000000e+00, double %15
br label %26
18: ; preds = %4
%19 = fcmp ugt double %8, %1
br i1 %19, label %20, label %26
20: ; preds = %18
%21 = fcmp ogt double %8, 0.000000e+00
br i1 %21, label %22, label %26
22: ; preds = %20
%23 = fadd double %8, %1
%24 = fcmp oeq double %23, %1
%25 = select i1 %24, double 0.000000e+00, double %23
br label %26
26: ; preds = %10, %14, %18, %22, %20, %12, %2
%27 = phi double [ %0, %2 ], [ 0.000000e+00, %10 ], [ %17, %14 ], [ 0.000000e+00, %18 ], [ %25, %22 ], [ %8, %20 ], [ %8, %12 ]
ret double %27
}