float LFOtrp(float step, float period, float knee) {
  if (step < (knee * period) / 2.0f) {
    return (step / period) * 2.0f / knee;
  } else if (step >= (knee * period) / 2.0f &&
             step < period * (1.0f - knee) / 2.0f) {
    return 1.0f;
  } else if (step >= period * (1.0f - knee) / 2.0f &&
             step < period * (1.0f + knee) / 2.0f) {
    return (1.0f - step / (period / 2.0f)) * 1.0f / knee;
  } else if (step >= period * (1.0f + knee) / 2.0f &&
             step < period - (knee * period) / 2.0f) {
    return -1.0f;
  } else {
    return (step / period - 1.0f) * 2.0f / knee;
  }
}


x86 assembly (clang, -O0):
<LFOtrp>:
push   %rbp
mov    %rsp,%rbp
movss  %xmm0,-0x8(%rbp)
movss  %xmm1,-0xc(%rbp)
movss  %xmm2,-0x10(%rbp)
movss  -0x8(%rbp),%xmm1
movss  -0x10(%rbp),%xmm0
mulss  -0xc(%rbp),%xmm0
movss  0xed6(%rip),%xmm2
divss  %xmm2,%xmm0
ucomiss %xmm1,%xmm0
jbe    115c <LFOtrp+0x5c>
movss  -0x8(%rbp),%xmm0
divss  -0xc(%rbp),%xmm0
movss  0xeb7(%rip),%xmm1
mulss  %xmm1,%xmm0
divss  -0x10(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    12fe <LFOtrp+0x1fe>
movss  -0x8(%rbp),%xmm0
movss  -0x10(%rbp),%xmm1
mulss  -0xc(%rbp),%xmm1
movss  0xe8d(%rip),%xmm2
divss  %xmm2,%xmm1
ucomiss %xmm1,%xmm0
jb     11c2 <LFOtrp+0xc2>
movss  -0x8(%rbp),%xmm1
movss  -0xc(%rbp),%xmm0
movss  0xe72(%rip),%xmm2
subss  -0x10(%rbp),%xmm2
mulss  %xmm2,%xmm0
movss  0xe5d(%rip),%xmm2
divss  %xmm2,%xmm0
ucomiss %xmm1,%xmm0
jbe    11c2 <LFOtrp+0xc2>
movss  0xe4c(%rip),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    12fe <LFOtrp+0x1fe>
movss  -0x8(%rbp),%xmm0
movss  -0xc(%rbp),%xmm1
movss  0xe30(%rip),%xmm2
subss  -0x10(%rbp),%xmm2
mulss  %xmm2,%xmm1
movss  0xe1b(%rip),%xmm2
divss  %xmm2,%xmm1
ucomiss %xmm1,%xmm0
jb     1263 <LFOtrp+0x163>
movss  -0x8(%rbp),%xmm1
movss  -0xc(%rbp),%xmm0
movss  0xe00(%rip),%xmm2
addss  -0x10(%rbp),%xmm2
mulss  %xmm2,%xmm0
movss  0xdeb(%rip),%xmm2
divss  %xmm2,%xmm0
ucomiss %xmm1,%xmm0
jbe    1263 <LFOtrp+0x163>
movss  -0x8(%rbp),%xmm1
movss  -0xc(%rbp),%xmm0
movss  0xdcc(%rip),%xmm2
divss  %xmm2,%xmm0
divss  %xmm0,%xmm1
movss  0xdc0(%rip),%xmm0
subss  %xmm1,%xmm0
movss  0xdb4(%rip),%xmm1
mulss  %xmm1,%xmm0
divss  -0x10(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    12fe <LFOtrp+0x1fe>
movss  -0x8(%rbp),%xmm0
movss  -0xc(%rbp),%xmm1
movss  0xd8f(%rip),%xmm2
addss  -0x10(%rbp),%xmm2
mulss  %xmm2,%xmm1
movss  0xd7a(%rip),%xmm2
divss  %xmm2,%xmm1
ucomiss %xmm1,%xmm0
jb     12d2 <LFOtrp+0x1d2>
movss  -0x8(%rbp),%xmm1
movss  -0xc(%rbp),%xmm0
movss  -0x10(%rbp),%xmm2
mulss  -0xc(%rbp),%xmm2
movss  0xd51(%rip),%xmm3
divss  %xmm3,%xmm2
subss  %xmm2,%xmm0
ucomiss %xmm1,%xmm0
jbe    12d2 <LFOtrp+0x1d2>
movss  0xd40(%rip),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    12fe <LFOtrp+0x1fe>
movss  -0x8(%rbp),%xmm0
divss  -0xc(%rbp),%xmm0
movss  0xd20(%rip),%xmm1
subss  %xmm1,%xmm0
movss  0xd10(%rip),%xmm1
mulss  %xmm1,%xmm0
divss  -0x10(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<LFOtrp>:
movaps %xmm1,%xmm4
mulss  %xmm2,%xmm4
mulss  0xef1(%rip),%xmm4
ucomiss %xmm0,%xmm4
jbe    1125 <LFOtrp+0x25>
divss  %xmm1,%xmm0
addss  %xmm0,%xmm0
divss  %xmm2,%xmm0
movaps %xmm0,%xmm3
jmp    114a <LFOtrp+0x4a>
ucomiss %xmm4,%xmm0
movss  0xed4(%rip),%xmm3
movaps %xmm3,%xmm5
subss  %xmm2,%xmm5
mulss  %xmm1,%xmm5
mulss  0xebd(%rip),%xmm5
jb     114e <LFOtrp+0x4e>
ucomiss %xmm0,%xmm5
jbe    114e <LFOtrp+0x4e>
movaps %xmm3,%xmm0
ret
ucomiss %xmm5,%xmm0
movss  0xeab(%rip),%xmm3
addss  %xmm2,%xmm3
mulss  %xmm1,%xmm3
mulss  0xe97(%rip),%xmm3
jb     1186 <LFOtrp+0x86>
ucomiss %xmm0,%xmm3
jbe    1186 <LFOtrp+0x86>
mulss  0xe94(%rip),%xmm1
divss  %xmm1,%xmm0
addss  0xe80(%rip),%xmm0
jmp    111c <LFOtrp+0x1c>
ucomiss %xmm3,%xmm0
jb     11a0 <LFOtrp+0xa0>
movaps %xmm1,%xmm3
subss  %xmm4,%xmm3
ucomiss %xmm0,%xmm3
jbe    11a0 <LFOtrp+0xa0>
movss  0xe69(%rip),%xmm0
ret
divss  %xmm1,%xmm0
addss  0xe5c(%rip),%xmm0
jmp    1118 <LFOtrp+0x18>

LLVM IR (-O0):
define float @LFOtrp(float %0, float %1, float %2) {
%4 = alloca float
%5 = alloca float
%6 = alloca float
%7 = alloca float
store float %0, float* %5
store float %1, float* %6
store float %2, float* %7
%8 = load float, float* %5
%9 = load float, float* %7
%10 = load float, float* %6
%11 = fmul float %9, %10
%12 = fdiv float %11, 2.000000e+00
%13 = fcmp olt float %8, %12
br i1 %13, label %14, label %21
14: ; preds = %3
%15 = load float, float* %5
%16 = load float, float* %6
%17 = fdiv float %15, %16
%18 = fmul float %17, 2.000000e+00
%19 = load float, float* %7
%20 = fdiv float %18, %19
store float %20, float* %4
br label %88
21: ; preds = %3
%22 = load float, float* %5
%23 = load float, float* %7
%24 = load float, float* %6
%25 = fmul float %23, %24
%26 = fdiv float %25, 2.000000e+00
%27 = fcmp oge float %22, %26
br i1 %27, label %28, label %37
28: ; preds = %21
%29 = load float, float* %5
%30 = load float, float* %6
%31 = load float, float* %7
%32 = fsub float 1.000000e+00, %31
%33 = fmul float %30, %32
%34 = fdiv float %33, 2.000000e+00
%35 = fcmp olt float %29, %34
br i1 %35, label %36, label %37
36: ; preds = %28
store float 1.000000e+00, float* %4
br label %88
37: ; preds = %28, %21
%38 = load float, float* %5
%39 = load float, float* %6
%40 = load float, float* %7
%41 = fsub float 1.000000e+00, %40
%42 = fmul float %39, %41
%43 = fdiv float %42, 2.000000e+00
%44 = fcmp oge float %38, %43
br i1 %44, label %45, label %62
45: ; preds = %37
%46 = load float, float* %5
%47 = load float, float* %6
%48 = load float, float* %7
%49 = fadd float 1.000000e+00, %48
%50 = fmul float %47, %49
%51 = fdiv float %50, 2.000000e+00
%52 = fcmp olt float %46, %51
br i1 %52, label %53, label %62
53: ; preds = %45
%54 = load float, float* %5
%55 = load float, float* %6
%56 = fdiv float %55, 2.000000e+00
%57 = fdiv float %54, %56
%58 = fsub float 1.000000e+00, %57
%59 = fmul float %58, 1.000000e+00
%60 = load float, float* %7
%61 = fdiv float %59, %60
store float %61, float* %4
br label %88
62: ; preds = %45, %37
%63 = load float, float* %5
%64 = load float, float* %6
%65 = load float, float* %7
%66 = fadd float 1.000000e+00, %65
%67 = fmul float %64, %66
%68 = fdiv float %67, 2.000000e+00
%69 = fcmp oge float %63, %68
br i1 %69, label %70, label %80
70: ; preds = %62
%71 = load float, float* %5
%72 = load float, float* %6
%73 = load float, float* %7
%74 = load float, float* %6
%75 = fmul float %73, %74
%76 = fdiv float %75, 2.000000e+00
%77 = fsub float %72, %76
%78 = fcmp olt float %71, %77
br i1 %78, label %79, label %80
79: ; preds = %70
store float -1.000000e+00, float* %4
br label %88
80: ; preds = %70, %62
%81 = load float, float* %5
%82 = load float, float* %6
%83 = fdiv float %81, %82
%84 = fsub float %83, 1.000000e+00
%85 = fmul float %84, 2.000000e+00
%86 = load float, float* %7
%87 = fdiv float %85, %86
store float %87, float* %4
br label %88
88: ; preds = %80, %79, %53, %36, %14
%89 = load float, float* %4
ret float %89
}

LLVM IR (-O2):
define float @LFOtrp(float %0, float %1, float %2) {
%4 = fmul float %1, %2
%5 = fmul float %4, 5.000000e-01
%6 = fcmp ogt float %5, %0
br i1 %6, label %7, label %11
7: ; preds = %3
%8 = fdiv float %0, %1
%9 = fmul float %8, 2.000000e+00
%10 = fdiv float %9, %2
br label %40
11: ; preds = %3
%12 = fcmp ole float %5, %0
%13 = fsub float 1.000000e+00, %2
%14 = fmul float %13, %1
%15 = fmul float %14, 5.000000e-01
%16 = fcmp ogt float %15, %0
%17 = and i1 %12, %16
br i1 %17, label %40, label %18
18: ; preds = %11
%19 = fcmp ole float %15, %0
%20 = fadd float %2, 1.000000e+00
%21 = fmul float %20, %1
%22 = fmul float %21, 5.000000e-01
%23 = fcmp ogt float %22, %0
%24 = and i1 %19, %23
br i1 %24, label %25, label %30
25: ; preds = %18
%26 = fmul float %1, 5.000000e-01
%27 = fdiv float %0, %26
%28 = fsub float 1.000000e+00, %27
%29 = fdiv float %28, %2
br label %40
30: ; preds = %18
%31 = fcmp ole float %22, %0
%32 = fsub float %1, %5
%33 = fcmp ogt float %32, %0
%34 = and i1 %31, %33
br i1 %34, label %40, label %35
35: ; preds = %30
%36 = fdiv float %0, %1
%37 = fadd float %36, -1.000000e+00
%38 = fmul float %37, 2.000000e+00
%39 = fdiv float %38, %2
br label %40
40: ; preds = %11, %30, %35, %25, %7
%41 = phi float [ %10, %7 ], [ %29, %25 ], [ %39, %35 ], [ -1.000000e+00, %30 ], [ 1.000000e+00, %11 ]
ret float %41
}