#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 linear_to_srgb(double);
scalar_t__ ordered_dither_lowlevel(double, int, int);
int scale_to_int(double, int);
double srgb_to_linear(double);
int quantize(double v_to_1, int numcc, int x, int y, int dither, int from_srgb,
             int to_srgb) {
  double v_to_1_linear;
  double v_to_1_targetcs;
  double v_to_maxcc;
  double floor_to_maxcc, ceil_to_maxcc;
  double floor_to_1, ceil_to_1;
  double floor_to_1_linear, ceil_to_1_linear;
  double fraction;
  int all_linear;
  int maxcc = numcc - 1;
  if (dither < 1 && !from_srgb && !to_srgb) {
    return scale_to_int(v_to_1, numcc);
  }
  all_linear = (!from_srgb && !to_srgb);
  if (all_linear)
    v_to_1_targetcs = v_to_1;
  else
    v_to_1_targetcs = from_srgb ? v_to_1 : linear_to_srgb(v_to_1);
  v_to_maxcc = v_to_1_targetcs * maxcc;
  floor_to_maxcc = floor(v_to_maxcc);
  if (floor_to_maxcc >= (double)maxcc)
    return maxcc;
  ceil_to_maxcc = floor_to_maxcc + 1.0;
  floor_to_1 = floor_to_maxcc / maxcc;
  ceil_to_1 = ceil_to_maxcc / maxcc;
  if (all_linear)
    floor_to_1_linear = floor_to_1;
  else
    floor_to_1_linear = srgb_to_linear(floor_to_1);
  v_to_1_linear = from_srgb ? srgb_to_linear(v_to_1) : v_to_1;
  if (all_linear)
    ceil_to_1_linear = ceil_to_1;
  else
    ceil_to_1_linear = srgb_to_linear(ceil_to_1);
  fraction = (v_to_1_linear - floor_to_1_linear) /
             (ceil_to_1_linear - floor_to_1_linear);
  if (ordered_dither_lowlevel(fraction, x, y))
    return (int)ceil_to_maxcc;
  else
    return (int)floor_to_maxcc;
}


x86 assembly (clang, -O0):
<quantize>:
push   %rbp
mov    %rsp,%rbp
sub    $0xa0,%rsp
movsd  %xmm0,-0x10(%rbp)
mov    %edi,-0x14(%rbp)
mov    %esi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
mov    %ecx,-0x20(%rbp)
mov    %r8d,-0x24(%rbp)
mov    %r9d,-0x28(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x80(%rbp)
cmpl   $0x1,-0x20(%rbp)
jge    11b0 <quantize+0x60>
cmpl   $0x0,-0x24(%rbp)
jne    11b0 <quantize+0x60>
cmpl   $0x0,-0x28(%rbp)
jne    11b0 <quantize+0x60>
movsd  -0x10(%rbp),%xmm0
mov    -0x14(%rbp),%edi
call   1030 <scale_to_int@plt>
mov    %eax,-0x4(%rbp)
jmp    1383 <quantize+0x233>
xor    %eax,%eax
cmpl   $0x0,-0x24(%rbp)
mov    %al,-0x81(%rbp)
jne    11d1 <quantize+0x81>
cmpl   $0x0,-0x28(%rbp)
setne  %al
xor    $0xff,%al
mov    %al,-0x81(%rbp)
mov    -0x81(%rbp),%al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x7c(%rbp)
cmpl   $0x0,-0x7c(%rbp)
je     11f8 <quantize+0xa8>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
jmp    1233 <quantize+0xe3>
cmpl   $0x0,-0x24(%rbp)
je     1214 <quantize+0xc4>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
jmp    1226 <quantize+0xd6>
movsd  -0x10(%rbp),%xmm0
call   1060 <linear_to_srgb@plt>
movsd  %xmm0,-0x90(%rbp)
ff
movsd  -0x90(%rbp),%xmm0
ff
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
cvtsi2sdl -0x80(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
call   1070 <floor@plt>
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
cvtsi2sdl -0x80(%rbp),%xmm1
ucomisd %xmm1,%xmm0
jb     1274 <quantize+0x124>
mov    -0x80(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1383 <quantize+0x233>
movsd  0xd84(%rip),%xmm0
addsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x48(%rbp),%xmm0
cvtsi2sdl -0x80(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x50(%rbp),%xmm0
cvtsi2sdl -0x80(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
cmpl   $0x0,-0x7c(%rbp)
je     12c5 <quantize+0x175>
movsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
jmp    12d4 <quantize+0x184>
movsd  -0x58(%rbp),%xmm0
call   1040 <srgb_to_linear@plt>
movsd  %xmm0,-0x68(%rbp)
cmpl   $0x0,-0x24(%rbp)
je     12f5 <quantize+0x1a5>
movsd  -0x10(%rbp),%xmm0
call   1040 <srgb_to_linear@plt>
movsd  %xmm0,-0x98(%rbp)
ff
jmp    1302 <quantize+0x1b2>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
movsd  -0x98(%rbp),%xmm0
ff
movsd  %xmm0,-0x30(%rbp)
cmpl   $0x0,-0x7c(%rbp)
je     1328 <quantize+0x1d8>
movsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x70(%rbp)
jmp    1337 <quantize+0x1e7>
movsd  -0x60(%rbp),%xmm0
call   1040 <srgb_to_linear@plt>
movsd  %xmm0,-0x70(%rbp)
movsd  -0x30(%rbp),%xmm0
subsd  -0x68(%rbp),%xmm0
movsd  -0x70(%rbp),%xmm1
subsd  -0x68(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  -0x78(%rbp),%xmm0
mov    -0x18(%rbp),%edi
mov    -0x1c(%rbp),%esi
call   1050 <ordered_dither_lowlevel@plt>
cmp    $0x0,%rax
je     137b <quantize+0x22b>
cvttsd2si -0x50(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1383 <quantize+0x233>
cvttsd2si -0x48(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0xa0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<quantize>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x30,%rsp
mov    %r9d,%ebx
mov    %r8d,%r12d
mov    %edx,%r14d
mov    %esi,%r15d
mov    %edi,%ebp
movapd %xmm0,%xmm1
or     %r8d,%ebx
test   %ecx,%ecx
jg     1190 <quantize+0x40>
test   %ebx,%ebx
jne    1190 <quantize+0x40>
movapd %xmm1,%xmm0
mov    %ebp,%edi
add    $0x30,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
jmp    1030 <scale_to_int@plt>
add    $0xffffffff,%ebp
movapd %xmm1,%xmm0
test   %ebx,%ebx
movsd  %xmm1,0x8(%rsp)
je     11b3 <quantize+0x63>
movapd %xmm1,%xmm0
test   %r12d,%r12d
jne    11b3 <quantize+0x63>
movapd %xmm1,%xmm0
call   1060 <linear_to_srgb@plt>
xorps  %xmm1,%xmm1
cvtsi2sd %ebp,%xmm1
movsd  %xmm1,0x28(%rsp)
mulsd  %xmm1,%xmm0
call   1070 <floor@plt>
movsd  0x28(%rsp),%xmm2
ucomisd %xmm2,%xmm0
jae    1287 <quantize+0x137>
movapd %xmm0,%xmm1
divsd  %xmm2,%xmm1
test   %ebx,%ebx
movsd  %xmm0,0x10(%rsp)
je     1202 <quantize+0xb2>
movapd %xmm1,%xmm0
call   1040 <srgb_to_linear@plt>
movsd  %xmm0,0x18(%rsp)
movsd  0x10(%rsp),%xmm0
jmp    1208 <quantize+0xb8>
movsd  %xmm1,0x18(%rsp)
movsd  0x8(%rsp),%xmm1
movsd  0xdea(%rip),%xmm2
addsd  %xmm0,%xmm2
movsd  %xmm2,0x20(%rsp)
test   %r12d,%r12d
je     1232 <quantize+0xe2>
movapd %xmm1,%xmm0
call   1040 <srgb_to_linear@plt>
movapd %xmm0,%xmm1
movsd  0x20(%rsp),%xmm0
divsd  0x28(%rsp),%xmm0
test   %ebx,%ebx
je     1253 <quantize+0x103>
movsd  %xmm1,0x8(%rsp)
call   1040 <srgb_to_linear@plt>
movsd  0x8(%rsp),%xmm1
movsd  0x18(%rsp),%xmm2
subsd  %xmm2,%xmm1
subsd  %xmm2,%xmm0
divsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
mov    %r15d,%edi
mov    %r14d,%esi
call   1050 <ordered_dither_lowlevel@plt>
test   %rax,%rax
je     1281 <quantize+0x131>
cvttsd2si 0x20(%rsp),%ebp
jmp    1287 <quantize+0x137>
cvttsd2si 0x10(%rsp),%ebp
mov    %ebp,%eax
add    $0x30,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @quantize(double %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6) {
%8 = alloca i32
%9 = alloca double
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca double
%17 = alloca double
%18 = alloca double
%19 = alloca double
%20 = alloca double
%21 = alloca double
%22 = alloca double
%23 = alloca double
%24 = alloca double
%25 = alloca double
%26 = alloca i32
%27 = alloca i32
store double %0, double* %9
store i32 %1, i32* %10
store i32 %2, i32* %11
store i32 %3, i32* %12
store i32 %4, i32* %13
store i32 %5, i32* %14
store i32 %6, i32* %15
%28 = load i32, i32* %10
%29 = sub nsw i32 %28, 1
store i32 %29, i32* %27
%30 = load i32, i32* %13
%31 = icmp slt i32 %30, 1
br i1 %31, label %32, label %42
32: ; preds = %7
%33 = load i32, i32* %14
%34 = icmp ne i32 %33, 0
br i1 %34, label %42, label %35
35: ; preds = %32
%36 = load i32, i32* %15
%37 = icmp ne i32 %36, 0
br i1 %37, label %42, label %38
38: ; preds = %35
%39 = load double, double* %9
%40 = load i32, i32* %10
%41 = call i32 @scale_to_int(double %39, i32 %40)
store i32 %41, i32* %8
br label %133
42: ; preds = %35, %32, %7
%43 = load i32, i32* %14
%44 = icmp ne i32 %43, 0
br i1 %44, label %49, label %45
45: ; preds = %42
%46 = load i32, i32* %15
%47 = icmp ne i32 %46, 0
%48 = xor i1 %47, true
br label %49
49: ; preds = %45, %42
%50 = phi i1 [ false, %42 ], [ %48, %45 ]
%51 = zext i1 %50 to i32
store i32 %51, i32* %26
%52 = load i32, i32* %26
%53 = icmp ne i32 %52, 0
br i1 %53, label %54, label %56
54: ; preds = %49
%55 = load double, double* %9
store double %55, double* %17
br label %66
56: ; preds = %49
%57 = load i32, i32* %14
%58 = icmp ne i32 %57, 0
br i1 %58, label %59, label %61
59: ; preds = %56
%60 = load double, double* %9
br label %64
61: ; preds = %56
%62 = load double, double* %9
%63 = call double @linear_to_srgb(double %62)
br label %64
64: ; preds = %61, %59
%65 = phi double [ %60, %59 ], [ %63, %61 ]
store double %65, double* %17
br label %66
66: ; preds = %64, %54
%67 = load double, double* %17
%68 = load i32, i32* %27
%69 = sitofp i32 %68 to double
%70 = fmul double %67, %69
store double %70, double* %18
%71 = load double, double* %18
%72 = call double @llvm.floor.f64(double %71)
store double %72, double* %19
%73 = load double, double* %19
%74 = load i32, i32* %27
%75 = sitofp i32 %74 to double
%76 = fcmp oge double %73, %75
br i1 %76, label %77, label %79
77: ; preds = %66
%78 = load i32, i32* %27
store i32 %78, i32* %8
br label %133
79: ; preds = %66
%80 = load double, double* %19
%81 = fadd double %80, 1.000000e+00
store double %81, double* %20
%82 = load double, double* %19
%83 = load i32, i32* %27
%84 = sitofp i32 %83 to double
%85 = fdiv double %82, %84
store double %85, double* %21
%86 = load double, double* %20
%87 = load i32, i32* %27
%88 = sitofp i32 %87 to double
%89 = fdiv double %86, %88
store double %89, double* %22
%90 = load i32, i32* %26
%91 = icmp ne i32 %90, 0
br i1 %91, label %92, label %94
92: ; preds = %79
%93 = load double, double* %21
store double %93, double* %23
br label %97
94: ; preds = %79
%95 = load double, double* %21
%96 = call double @srgb_to_linear(double %95)
store double %96, double* %23
br label %97
97: ; preds = %94, %92
%98 = load i32, i32* %14
%99 = icmp ne i32 %98, 0
br i1 %99, label %100, label %103
100: ; preds = %97
%101 = load double, double* %9
%102 = call double @srgb_to_linear(double %101)
br label %105
103: ; preds = %97
%104 = load double, double* %9
br label %105
105: ; preds = %103, %100
%106 = phi double [ %102, %100 ], [ %104, %103 ]
store double %106, double* %16
%107 = load i32, i32* %26
%108 = icmp ne i32 %107, 0
br i1 %108, label %109, label %111
109: ; preds = %105
%110 = load double, double* %22
store double %110, double* %24
br label %114
111: ; preds = %105
%112 = load double, double* %22
%113 = call double @srgb_to_linear(double %112)
store double %113, double* %24
br label %114
114: ; preds = %111, %109
%115 = load double, double* %16
%116 = load double, double* %23
%117 = fsub double %115, %116
%118 = load double, double* %24
%119 = load double, double* %23
%120 = fsub double %118, %119
%121 = fdiv double %117, %120
store double %121, double* %25
%122 = load double, double* %25
%123 = load i32, i32* %11
%124 = load i32, i32* %12
%125 = call i64 @ordered_dither_lowlevel(double %122, i32 %123, i32 %124)
%126 = icmp ne i64 %125, 0
br i1 %126, label %127, label %130
127: ; preds = %114
%128 = load double, double* %20
%129 = fptosi double %128 to i32
store i32 %129, i32* %8
br label %133
130: ; preds = %114
%131 = load double, double* %19
%132 = fptosi double %131 to i32
store i32 %132, i32* %8
br label %133
133: ; preds = %130, %127, %77, %38
%134 = load i32, i32* %8
ret i32 %134
}

LLVM IR (-O2):
define i32 @quantize(double %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6) {
%8 = add nsw i32 %1, -1
%9 = icmp sgt i32 %4, 0
%10 = icmp eq i32 %5, 0
%11 = or i32 %6, %5
%12 = icmp ne i32 %11, 0
%13 = or i1 %9, %12
br i1 %13, label %16, label %14
14: ; preds = %7
%15 = tail call i32 @scale_to_int(double %0, i32 %1)
br label %53
16: ; preds = %7
%17 = icmp eq i32 %11, 0
%18 = xor i1 %10, true
%19 = or i1 %17, %18
br i1 %19, label %22, label %20
20: ; preds = %16
%21 = tail call double @linear_to_srgb(double %0)
br label %22
22: ; preds = %16, %20
%23 = phi double [ %0, %16 ], [ %21, %20 ]
%24 = sitofp i32 %8 to double
%25 = fmul double %23, %24
%26 = tail call double @llvm.floor.f64(double %25)
%27 = fcmp ult double %26, %24
br i1 %27, label %28, label %53
28: ; preds = %22
%29 = fadd double %26, 1.000000e+00
%30 = fdiv double %26, %24
%31 = fdiv double %29, %24
br i1 %17, label %34, label %32
32: ; preds = %28
%33 = tail call double @srgb_to_linear(double %30)
br label %34
34: ; preds = %28, %32
%35 = phi double [ %33, %32 ], [ %30, %28 ]
br i1 %10, label %38, label %36
36: ; preds = %34
%37 = tail call double @srgb_to_linear(double %0)
br label %38
38: ; preds = %34, %36
%39 = phi double [ %37, %36 ], [ %0, %34 ]
br i1 %17, label %42, label %40
40: ; preds = %38
%41 = tail call double @srgb_to_linear(double %31)
br label %42
42: ; preds = %38, %40
%43 = phi double [ %41, %40 ], [ %31, %38 ]
%44 = fsub double %39, %35
%45 = fsub double %43, %35
%46 = fdiv double %44, %45
%47 = tail call i64 @ordered_dither_lowlevel(double %46, i32 %2, i32 %3)
%48 = icmp eq i64 %47, 0
br i1 %48, label %51, label %49
49: ; preds = %42
%50 = fptosi double %29 to i32
br label %53
51: ; preds = %42
%52 = fptosi double %26 to i32
br label %53
53: ; preds = %22, %51, %49, %14
%54 = phi i32 [ %50, %49 ], [ %52, %51 ], [ %15, %14 ], [ %8, %22 ]
ret i32 %54
}