#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 */
typedef size_t ssize_t;

/* Variables and functions */
double fabs(double);
int filters_trapezoidal(size_t wavLen, const float *inWav, float *outWav,
                        size_t k, size_t l, double M) {
  double s, pp;
  ssize_t i, j, jk, jl, jkl;
  double vj, vjk, vjl, vjkl, dkl;
  s = 0.0;
  pp = 0.0;
  for (i = 0; i < wavLen; i++) {
    j = i;
    jk = j - k;
    jl = j - l;
    jkl = j - k - l;
    vj = j >= 0 ? inWav[j] : inWav[0];
    vjk = jk >= 0 ? inWav[jk] : inWav[0];
    vjl = jl >= 0 ? inWav[jl] : inWav[0];
    vjkl = jkl >= 0 ? inWav[jkl] : inWav[0];
    dkl = vj - vjk - vjl + vjkl;
    pp = pp + dkl;
    if (M >= 0.0) {
      s = s + pp + dkl * M;
    } else {
      s = s + dkl;
    }
    outWav[i] = s / (fabs(M) * (double)k);
  }
  return 0;
}


x86 assembly (clang, -O0):
<filters_trapezoidal>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
movsd  %xmm0,-0x30(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
movq   $0x0,-0x48(%rbp)
mov    -0x48(%rbp),%rax
cmp    -0x8(%rbp),%rax
jae    1376 <filters_trapezoidal+0x276>
mov    -0x48(%rbp),%rax
mov    %rax,-0x50(%rbp)
mov    -0x50(%rbp),%rax
sub    -0x20(%rbp),%rax
mov    %rax,-0x58(%rbp)
mov    -0x50(%rbp),%rax
sub    -0x28(%rbp),%rax
mov    %rax,-0x60(%rbp)
mov    -0x50(%rbp),%rax
sub    -0x20(%rbp),%rax
sub    -0x28(%rbp),%rax
mov    %rax,-0x68(%rbp)
cmpq   $0x0,-0x50(%rbp)
jb     119c <filters_trapezoidal+0x9c>
mov    -0x10(%rbp),%rax
mov    -0x50(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x94(%rbp)
ff
jmp    11ac <filters_trapezoidal+0xac>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x94(%rbp)
ff
movss  -0x94(%rbp),%xmm0
ff
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x70(%rbp)
cmpq   $0x0,-0x58(%rbp)
jb     11e2 <filters_trapezoidal+0xe2>
mov    -0x10(%rbp),%rax
mov    -0x58(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x98(%rbp)
ff
jmp    11f2 <filters_trapezoidal+0xf2>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x98(%rbp)
ff
movss  -0x98(%rbp),%xmm0
ff
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x78(%rbp)
cmpq   $0x0,-0x60(%rbp)
jb     1228 <filters_trapezoidal+0x128>
mov    -0x10(%rbp),%rax
mov    -0x60(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x9c(%rbp)
ff
jmp    1238 <filters_trapezoidal+0x138>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x9c(%rbp)
ff
movss  -0x9c(%rbp),%xmm0
ff
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x80(%rbp)
cmpq   $0x0,-0x68(%rbp)
jb     126e <filters_trapezoidal+0x16e>
mov    -0x10(%rbp),%rax
mov    -0x68(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0xa0(%rbp)
ff
jmp    127e <filters_trapezoidal+0x17e>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0xa0(%rbp)
ff
movss  -0xa0(%rbp),%xmm0
ff
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
movsd  -0x70(%rbp),%xmm0
subsd  -0x78(%rbp),%xmm0
subsd  -0x80(%rbp),%xmm0
addsd  -0x88(%rbp),%xmm0
ff
movsd  %xmm0,-0x90(%rbp)
ff
movsd  -0x40(%rbp),%xmm0
addsd  -0x90(%rbp),%xmm0
ff
movsd  %xmm0,-0x40(%rbp)
movsd  -0x30(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     12fe <filters_trapezoidal+0x1fe>
movsd  -0x38(%rbp),%xmm1
addsd  -0x40(%rbp),%xmm1
movsd  -0x90(%rbp),%xmm0
ff
movsd  -0x30(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
jmp    1310 <filters_trapezoidal+0x210>
movsd  -0x38(%rbp),%xmm0
addsd  -0x90(%rbp),%xmm0
ff
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
movaps 0xce4(%rip),%xmm2
movsd  -0x30(%rbp),%xmm1
pand   %xmm2,%xmm1
movaps 0xce4(%rip),%xmm3
movq   -0x20(%rbp),%xmm2
punpckldq %xmm3,%xmm2
movapd 0xce3(%rip),%xmm3
subpd  %xmm3,%xmm2
movaps %xmm2,%xmm3
unpckhpd %xmm2,%xmm2
addsd  %xmm3,%xmm2
mulsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x18(%rbp),%rax
mov    -0x48(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x48(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x48(%rbp)
jmp    1139 <filters_trapezoidal+0x39>
xor    %eax,%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<filters_trapezoidal>:
test   %rdi,%rdi
je     11d6 <filters_trapezoidal+0xd6>
movapd 0xeef(%rip),%xmm2
andpd  %xmm0,%xmm2
movq   %rcx,%xmm3
punpckldq 0xeee(%rip),%xmm3
subpd  0xef6(%rip),%xmm3
movapd %xmm3,%xmm1
unpckhpd %xmm3,%xmm1
addsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm1
shl    $0x2,%r8
neg    %r8
shl    $0x2,%rcx
mov    %r8,%rax
sub    %rcx,%rax
neg    %rcx
xorpd  %xmm2,%xmm2
xorpd  %xmm3,%xmm3
cmpnlesd %xmm0,%xmm3
xorpd  %xmm4,%xmm4
nop
movss  (%rsi),%xmm5
cvtss2sd %xmm5,%xmm5
movss  (%rsi,%rcx,1),%xmm6
cvtss2sd %xmm6,%xmm6
subsd  %xmm6,%xmm5
movss  (%rsi,%r8,1),%xmm6
cvtss2sd %xmm6,%xmm6
subsd  %xmm6,%xmm5
movss  (%rsi,%rax,1),%xmm6
cvtss2sd %xmm6,%xmm6
addsd  %xmm5,%xmm6
addsd  %xmm6,%xmm4
movapd %xmm2,%xmm5
addsd  %xmm4,%xmm5
addsd  %xmm6,%xmm2
mulsd  %xmm0,%xmm6
addsd  %xmm5,%xmm6
movapd %xmm3,%xmm5
andnpd %xmm6,%xmm5
andpd  %xmm3,%xmm2
orpd   %xmm5,%xmm2
movapd %xmm2,%xmm5
divsd  %xmm1,%xmm5
cvtsd2ss %xmm5,%xmm5
movss  %xmm5,(%rdx)
add    $0x4,%rdx
add    $0x4,%rsi
add    $0xffffffffffffffff,%rdi
jne    1160 <filters_trapezoidal+0x60>
xor    %eax,%eax
ret

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

LLVM IR (-O2):
define i32 @filters_trapezoidal(i64 %0, float* nocapture %1, float* nocapture writeonly %2, i64 %3, i64 %4, double %5) {
%7 = icmp eq i64 %0, 0
br i1 %7, label %45, label %8
8: ; preds = %6
%9 = fcmp ult double %5, 0.000000e+00
%10 = tail call double @llvm.fabs.f64(double %5)
%11 = uitofp i64 %3 to double
%12 = fmul double %10, %11
br label %13
13: ; preds = %8, %13
%14 = phi double [ 0.000000e+00, %8 ], [ %39, %13 ]
%15 = phi double [ 0.000000e+00, %8 ], [ %35, %13 ]
%16 = phi i64 [ 0, %8 ], [ %43, %13 ]
%17 = sub i64 %16, %3
%18 = sub i64 %16, %4
%19 = sub i64 %17, %4
%20 = getelementptr inbounds float, float* %1, i64 %16
%21 = load float, float* %20
%22 = fpext float %21 to double
%23 = getelementptr inbounds float, float* %1, i64 %17
%24 = load float, float* %23
%25 = fpext float %24 to double
%26 = getelementptr inbounds float, float* %1, i64 %18
%27 = load float, float* %26
%28 = fpext float %27 to double
%29 = getelementptr inbounds float, float* %1, i64 %19
%30 = load float, float* %29
%31 = fpext float %30 to double
%32 = fsub double %22, %25
%33 = fsub double %32, %28
%34 = fadd double %33, %31
%35 = fadd double %15, %34
%36 = fadd double %14, %35
%37 = tail call double @llvm.fmuladd.f64(double %34, double %5, double %36)
%38 = fadd double %14, %34
%39 = select i1 %9, double %38, double %37
%40 = fdiv double %39, %12
%41 = fptrunc double %40 to float
%42 = getelementptr inbounds float, float* %2, i64 %16
store float %41, float* %42
%43 = add nuw i64 %16, 1
%44 = icmp eq i64 %43, %0
br i1 %44, label %45, label %13
45: ; preds = %13, %6
ret i32 0
}