#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 */
struct osc_state {
  int dummy;
};

/* Variables and functions */
double tick_osc_saw(struct osc_state *, double, double, double);
double tick_osc_square(struct osc_state *, double, double, double, double);
double tick_osc(struct osc_state *osc, int waveform, double freq, double re,
                double im) {
  if (waveform < 32) {
    return tick_osc_square(osc, freq, re, im, 0);
  } else if (waveform < 64) {
    return tick_osc_square(osc, freq, re, im, -0.25);
  } else {
    return tick_osc_saw(osc, freq, re, im);
  }
}


x86 assembly (clang, -O0):
<tick_osc>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
movsd  %xmm0,-0x20(%rbp)
movsd  %xmm1,-0x28(%rbp)
movsd  %xmm2,-0x30(%rbp)
cmpl   $0x20,-0x14(%rbp)
jge    116d <tick_osc+0x4d>
mov    -0x10(%rbp),%rdi
movsd  -0x20(%rbp),%xmm0
movsd  -0x28(%rbp),%xmm1
movsd  -0x30(%rbp),%xmm2
xorps  %xmm3,%xmm3
call   1030 <tick_osc_square@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    11be <tick_osc+0x9e>
cmpl   $0x40,-0x14(%rbp)
jge    11a1 <tick_osc+0x81>
mov    -0x10(%rbp),%rdi
movsd  -0x20(%rbp),%xmm0
movsd  -0x28(%rbp),%xmm1
movsd  -0x30(%rbp),%xmm2
movsd  0xe6e(%rip),%xmm3
call   1030 <tick_osc_square@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    11be <tick_osc+0x9e>
mov    -0x10(%rbp),%rdi
movsd  -0x20(%rbp),%xmm0
movsd  -0x28(%rbp),%xmm1
movsd  -0x30(%rbp),%xmm2
call   1040 <tick_osc_saw@plt>
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<tick_osc>:
cmp    $0x1f,%esi
jg     112d <tick_osc+0xd>
xorps  %xmm3,%xmm3
jmp    1030 <tick_osc_square@plt>
cmp    $0x3f,%esi
ja     113f <tick_osc+0x1f>
movsd  0xec6(%rip),%xmm3
jmp    1030 <tick_osc_square@plt>
jmp    1040 <tick_osc_saw@plt>

LLVM IR (-O0):
%struct.osc_state = type { i32 }
define double @tick_osc(%struct.osc_state* %0, i32 %1, double %2, double %3, double %4) {
%6 = alloca double
%7 = alloca %struct.osc_state*
%8 = alloca i32
%9 = alloca double
%10 = alloca double
%11 = alloca double
store %struct.osc_state* %0, %struct.osc_state** %7
store i32 %1, i32* %8
store double %2, double* %9
store double %3, double* %10
store double %4, double* %11
%12 = load i32, i32* %8
%13 = icmp slt i32 %12, 32
br i1 %13, label %14, label %20
14: ; preds = %5
%15 = load %struct.osc_state*, %struct.osc_state** %7
%16 = load double, double* %9
%17 = load double, double* %10
%18 = load double, double* %11
%19 = call double @tick_osc_square(%struct.osc_state* %15, double %16, double %17, double %18, double 0.000000e+00)
store double %19, double* %6
br label %35
20: ; preds = %5
%21 = load i32, i32* %8
%22 = icmp slt i32 %21, 64
br i1 %22, label %23, label %29
23: ; preds = %20
%24 = load %struct.osc_state*, %struct.osc_state** %7
%25 = load double, double* %9
%26 = load double, double* %10
%27 = load double, double* %11
%28 = call double @tick_osc_square(%struct.osc_state* %24, double %25, double %26, double %27, double -2.500000e-01)
store double %28, double* %6
br label %35
29: ; preds = %20
%30 = load %struct.osc_state*, %struct.osc_state** %7
%31 = load double, double* %9
%32 = load double, double* %10
%33 = load double, double* %11
%34 = call double @tick_osc_saw(%struct.osc_state* %30, double %31, double %32, double %33)
store double %34, double* %6
br label %35
35: ; preds = %29, %23, %14
%36 = load double, double* %6
ret double %36
}

LLVM IR (-O2):
%struct.osc_state = type { i32 }
define double @tick_osc(%struct.osc_state* %0, i32 %1, double %2, double %3, double %4) {
%6 = icmp slt i32 %1, 32
br i1 %6, label %7, label %9
7: ; preds = %5
%8 = tail call double @tick_osc_square(%struct.osc_state* %0, double %2, double %3, double %4, double 0.000000e+00)
br label %15
9: ; preds = %5
%10 = icmp ult i32 %1, 64
br i1 %10, label %11, label %13
11: ; preds = %9
%12 = tail call double @tick_osc_square(%struct.osc_state* %0, double %2, double %3, double %4, double -2.500000e-01)
br label %15
13: ; preds = %9
%14 = tail call double @tick_osc_saw(%struct.osc_state* %0, double %2, double %3, double %4)
br label %15
15: ; preds = %13, %11, %7
%16 = phi double [ %8, %7 ], [ %12, %11 ], [ %14, %13 ]
ret double %16
}