#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 */
float fmodf(float, float);
float wave_harmonic(float i, float h1, float h2, float h3, float h4,
                    float (*f_wave)(float i)) {
  float s0 = f_wave(i);
  float s1 = f_wave(fmodf(2.0f * i, 1.0f));
  float s2 = f_wave(fmodf(3.0f * i, 1.0f));
  float s3 = f_wave(fmodf(4.0f * i, 1.0f));
  float s4 = f_wave(fmodf(5.0f * i, 1.0f));
  return s0 + h1 * s1 + h2 * s2 + h3 * s3 + h4 * s4;
}


x86 assembly (clang, -O0):
<wave_harmonic>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
movss  %xmm0,-0x4(%rbp)
movss  %xmm1,-0x8(%rbp)
movss  %xmm2,-0xc(%rbp)
movss  %xmm3,-0x10(%rbp)
movss  %xmm4,-0x14(%rbp)
mov    %rdi,-0x20(%rbp)
mov    -0x20(%rbp),%rax
movss  -0x4(%rbp),%xmm0
call   *%rax
movss  %xmm0,-0x24(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x58(%rbp)
movss  0xebb(%rip),%xmm0
mulss  -0x4(%rbp),%xmm0
movss  0xe9e(%rip),%xmm1
call   1030 <fmodf@plt>
mov    -0x58(%rbp),%rax
call   *%rax
movss  %xmm0,-0x28(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x50(%rbp)
movss  0xe8a(%rip),%xmm0
mulss  -0x4(%rbp),%xmm0
movss  0xe71(%rip),%xmm1
call   1030 <fmodf@plt>
mov    -0x50(%rbp),%rax
call   *%rax
movss  %xmm0,-0x2c(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x48(%rbp)
movss  0xe59(%rip),%xmm0
mulss  -0x4(%rbp),%xmm0
movss  0xe44(%rip),%xmm1
call   1030 <fmodf@plt>
mov    -0x48(%rbp),%rax
call   *%rax
movss  %xmm0,-0x30(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x40(%rbp)
movss  0xe28(%rip),%xmm0
mulss  -0x4(%rbp),%xmm0
movss  0xe17(%rip),%xmm1
call   1030 <fmodf@plt>
mov    -0x40(%rbp),%rax
call   *%rax
movss  %xmm0,-0x34(%rbp)
movss  -0x24(%rbp),%xmm0
movss  -0x8(%rbp),%xmm1
movss  -0x28(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0xc(%rbp),%xmm0
movss  -0x2c(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x10(%rbp),%xmm1
movss  -0x30(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x14(%rbp),%xmm0
movss  -0x34(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<wave_harmonic>:
push   %rbx
sub    $0x30,%rsp
mov    %rdi,%rbx
movss  %xmm4,0x2c(%rsp)
movss  %xmm3,0x28(%rsp)
movss  %xmm2,0x24(%rsp)
movss  %xmm1,0x20(%rsp)
movss  %xmm0,0xc(%rsp)
call   *%rdi
movss  %xmm0,0x1c(%rsp)
movss  0xc(%rsp),%xmm0
addss  %xmm0,%xmm0
movss  0xeb0(%rip),%xmm1
call   1030 <fmodf@plt>
call   *%rbx
movss  %xmm0,0x18(%rsp)
movss  0xe9f(%rip),%xmm0
mulss  0xc(%rsp),%xmm0
movss  0xe8d(%rip),%xmm1
call   1030 <fmodf@plt>
call   *%rbx
movss  %xmm0,0x14(%rsp)
movss  0xe80(%rip),%xmm0
mulss  0xc(%rsp),%xmm0
movss  0xe6a(%rip),%xmm1
call   1030 <fmodf@plt>
call   *%rbx
movss  %xmm0,0x10(%rsp)
movss  0xc(%rsp),%xmm0
mulss  0xe5b(%rip),%xmm0
movss  0xe47(%rip),%xmm1
call   1030 <fmodf@plt>
call   *%rbx
movss  0x18(%rsp),%xmm1
mulss  0x20(%rsp),%xmm1
addss  0x1c(%rsp),%xmm1
movss  0x14(%rsp),%xmm2
mulss  0x24(%rsp),%xmm2
addss  %xmm1,%xmm2
movss  0x10(%rsp),%xmm1
mulss  0x28(%rsp),%xmm1
addss  %xmm2,%xmm1
mulss  0x2c(%rsp),%xmm0
addss  %xmm1,%xmm0
add    $0x30,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define float @wave_harmonic(float %0, float %1, float %2, float %3, float %4, float (float)* %5) {
%7 = alloca float
%8 = alloca float
%9 = alloca float
%10 = alloca float
%11 = alloca float
%12 = alloca float (float)*
%13 = alloca float
%14 = alloca float
%15 = alloca float
%16 = alloca float
%17 = alloca float
store float %0, float* %7
store float %1, float* %8
store float %2, float* %9
store float %3, float* %10
store float %4, float* %11
store float (float)* %5, float (float)** %12
%18 = load float (float)*, float (float)** %12
%19 = load float, float* %7
%20 = call float %18(float %19)
store float %20, float* %13
%21 = load float (float)*, float (float)** %12
%22 = load float, float* %7
%23 = fmul float 2.000000e+00, %22
%24 = call float @fmodf(float %23, float 1.000000e+00)
%25 = call float %21(float %24)
store float %25, float* %14
%26 = load float (float)*, float (float)** %12
%27 = load float, float* %7
%28 = fmul float 3.000000e+00, %27
%29 = call float @fmodf(float %28, float 1.000000e+00)
%30 = call float %26(float %29)
store float %30, float* %15
%31 = load float (float)*, float (float)** %12
%32 = load float, float* %7
%33 = fmul float 4.000000e+00, %32
%34 = call float @fmodf(float %33, float 1.000000e+00)
%35 = call float %31(float %34)
store float %35, float* %16
%36 = load float (float)*, float (float)** %12
%37 = load float, float* %7
%38 = fmul float 5.000000e+00, %37
%39 = call float @fmodf(float %38, float 1.000000e+00)
%40 = call float %36(float %39)
store float %40, float* %17
%41 = load float, float* %13
%42 = load float, float* %8
%43 = load float, float* %14
%44 = call float @llvm.fmuladd.f32(float %42, float %43, float %41)
%45 = load float, float* %9
%46 = load float, float* %15
%47 = call float @llvm.fmuladd.f32(float %45, float %46, float %44)
%48 = load float, float* %10
%49 = load float, float* %16
%50 = call float @llvm.fmuladd.f32(float %48, float %49, float %47)
%51 = load float, float* %11
%52 = load float, float* %17
%53 = call float @llvm.fmuladd.f32(float %51, float %52, float %50)
ret float %53
}

LLVM IR (-O2):
define float @wave_harmonic(float %0, float %1, float %2, float %3, float %4, float (float)* nocapture %5) {
%7 = tail call float %5(float %0)
%8 = fmul float %0, 2.000000e+00
%9 = tail call float @fmodf(float %8, float 1.000000e+00)
%10 = tail call float %5(float %9)
%11 = fmul float %0, 3.000000e+00
%12 = tail call float @fmodf(float %11, float 1.000000e+00)
%13 = tail call float %5(float %12)
%14 = fmul float %0, 4.000000e+00
%15 = tail call float @fmodf(float %14, float 1.000000e+00)
%16 = tail call float %5(float %15)
%17 = fmul float %0, 5.000000e+00
%18 = tail call float @fmodf(float %17, float 1.000000e+00)
%19 = tail call float %5(float %18)
%20 = tail call float @llvm.fmuladd.f32(float %1, float %10, float %7)
%21 = tail call float @llvm.fmuladd.f32(float %2, float %13, float %20)
%22 = tail call float @llvm.fmuladd.f32(float %3, float %16, float %21)
%23 = tail call float @llvm.fmuladd.f32(float %4, float %19, float %22)
ret float %23
}