float calculate_corrosion_speed(float corrosion_voltage) {
  if (corrosion_voltage < 0)
    return 0;
  float lander_curve_x[13] = {0,     0.5,   1.576, 1.598, 1.664, 1.686, 1.709,
                              1.739, 1.950, 2.029, 2.099, 2.151, 2.184};
  float lander_curve_y[13] = {0.053305, 0.055084, 0.346755, 0.666663, 0.368389,
                              0.347145, 0.048716, 0.016842, 0.017591, 0.177787,
                              0.615137, 2.00125,  5.00777};
  int i = 0;
  while (corrosion_voltage >= lander_curve_x[i])
    i++;
  if (i >= 13)
    return 5;
  float slope = (lander_curve_y[i] - lander_curve_y[i - 1]) /
                (lander_curve_x[i] - lander_curve_x[i - 1]);
  return (lander_curve_y[i - 1] +
          slope * (corrosion_voltage - lander_curve_x[i - 1]));
}


x86 assembly (clang, -O0):
<calculate_corrosion_speed>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
movss  %xmm0,-0x8(%rbp)
xorps  %xmm0,%xmm0
ucomiss -0x8(%rbp),%xmm0
jbe    113a <calculate_corrosion_speed+0x2a>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    123c <calculate_corrosion_speed+0x12c>
lea    -0x40(%rbp),%rdi
lea    0xecb(%rip),%rsi
mov    $0x34,%edx
call   1030 <memcpy@plt>
lea    -0x80(%rbp),%rdi
lea    0xef6(%rip),%rsi
mov    $0x34,%edx
call   1030 <memcpy@plt>
movl   $0x0,-0x84(%rbp)
movss  -0x8(%rbp),%xmm0
movslq -0x84(%rbp),%rax
ucomiss -0x40(%rbp,%rax,4),%xmm0
jb     1199 <calculate_corrosion_speed+0x89>
mov    -0x84(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x84(%rbp)
jmp    116e <calculate_corrosion_speed+0x5e>
cmpl   $0xd,-0x84(%rbp)
jl     11b8 <calculate_corrosion_speed+0xa8>
movss  0xe52(%rip),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    123c <calculate_corrosion_speed+0x12c>
movslq -0x84(%rbp),%rax
movss  -0x80(%rbp,%rax,4),%xmm0
mov    -0x84(%rbp),%eax
sub    $0x1,%eax
cltq
subss  -0x80(%rbp,%rax,4),%xmm0
movslq -0x84(%rbp),%rax
movss  -0x40(%rbp,%rax,4),%xmm1
mov    -0x84(%rbp),%eax
sub    $0x1,%eax
cltq
subss  -0x40(%rbp,%rax,4),%xmm1
divss  %xmm1,%xmm0
movss  %xmm0,-0x88(%rbp)
ff
mov    -0x84(%rbp),%eax
sub    $0x1,%eax
cltq
movss  -0x80(%rbp,%rax,4),%xmm1
movss  -0x88(%rbp),%xmm0
ff
movss  -0x8(%rbp),%xmm2
mov    -0x84(%rbp),%eax
sub    $0x1,%eax
cltq
subss  -0x40(%rbp,%rax,4),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<calculate_corrosion_speed>:
xorps  %xmm1,%xmm1
ucomiss %xmm0,%xmm1
ja     1151 <calculate_corrosion_speed+0x51>
movabs $0xfffffffe00000000,%rax
ff ff ff
mov    $0xffffffffffffffff,%rcx
lea    0xef0(%rip),%rdx
movabs $0x100000000,%rsi
nopw   0x0(%rax,%rax,1)
add    %rsi,%rax
movss  (%rdx),%xmm1
add    $0x1,%rcx
add    $0x4,%rdx
ucomiss %xmm1,%xmm0
jae    1130 <calculate_corrosion_speed+0x30>
cmp    $0xc,%ecx
jbe    1155 <calculate_corrosion_speed+0x55>
movss  0xeaf(%rip),%xmm1
movaps %xmm1,%xmm0
ret
mov    %ecx,%ecx
lea    0xef2(%rip),%rdx
movss  (%rdx,%rcx,4),%xmm2
sar    $0x1e,%rax
movss  (%rax,%rdx,1),%xmm3
subss  %xmm3,%xmm2
lea    0xe99(%rip),%rcx
movss  (%rax,%rcx,1),%xmm4
subss  %xmm4,%xmm1
divss  %xmm1,%xmm2
subss  %xmm4,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm3,%xmm0
ret

LLVM IR (-O0):
@__const.calculate_corrosion_speed.lander_curve_x = [13 x float] [float 0.000000e+00, float 5.000000e-01, float 0x3FF9374BC0000000, float 0x3FF9916880000000, float 0x3FFA9FBE80000000, float 0x3FFAF9DB20000000, float 0x3FFB581060000000, float 0x3FFBD2F1A0000000, float 0x3FFF333340000000, float 0x40003B6460000000, float 0x4000CAC080000000, float 0x4001353F80000000, float 0x400178D500000000]
@__const.calculate_corrosion_speed.lander_curve_y = [13 x float] [float 0x3FAB4ACB00000000, float 0x3FAC33F860000000, float 0x3FD6313BE0000000, float 0x3FE5554DA0000000, float 0x3FD793AF80000000, float 0x3FD6379FA0000000, float 0x3FA8F14DC0000000, float 0x3F913F0780000000, float 0x3F92036000000000, float 0x3FC6C1B980000000, float 0x3FE3AF33C0000000, float 0x4000028F60000000, float 0x401407F4E0000000]
define float @calculate_corrosion_speed(float %0) {
%2 = alloca float
%3 = alloca float
%4 = alloca [13 x float]
%5 = alloca [13 x float]
%6 = alloca i32
%7 = alloca float
store float %0, float* %3
%8 = load float, float* %3
%9 = fcmp olt float %8, 0.000000e+00
br i1 %9, label %10, label %11
10: ; preds = %1
store float 0.000000e+00, float* %2
br label %64
11: ; preds = %1
%12 = bitcast [13 x float]* %4 to i8*
%13 = bitcast [13 x float]* %5 to i8*
store i32 0, i32* %6
br label %14
14: ; preds = %21, %11
%15 = load float, float* %3
%16 = load i32, i32* %6
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds [13 x float], [13 x float]* %4, i64 0, i64 %17
%19 = load float, float* %18
%20 = fcmp oge float %15, %19
br i1 %20, label %21, label %24
21: ; preds = %14
%22 = load i32, i32* %6
%23 = add nsw i32 %22, 1
store i32 %23, i32* %6
br label %14
24: ; preds = %14
%25 = load i32, i32* %6
%26 = icmp sge i32 %25, 13
br i1 %26, label %27, label %28
27: ; preds = %24
store float 5.000000e+00, float* %2
br label %64
28: ; preds = %24
%29 = load i32, i32* %6
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds [13 x float], [13 x float]* %5, i64 0, i64 %30
%32 = load float, float* %31
%33 = load i32, i32* %6
%34 = sub nsw i32 %33, 1
%35 = sext i32 %34 to i64
%36 = getelementptr inbounds [13 x float], [13 x float]* %5, i64 0, i64 %35
%37 = load float, float* %36
%38 = fsub float %32, %37
%39 = load i32, i32* %6
%40 = sext i32 %39 to i64
%41 = getelementptr inbounds [13 x float], [13 x float]* %4, i64 0, i64 %40
%42 = load float, float* %41
%43 = load i32, i32* %6
%44 = sub nsw i32 %43, 1
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds [13 x float], [13 x float]* %4, i64 0, i64 %45
%47 = load float, float* %46
%48 = fsub float %42, %47
%49 = fdiv float %38, %48
store float %49, float* %7
%50 = load i32, i32* %6
%51 = sub nsw i32 %50, 1
%52 = sext i32 %51 to i64
%53 = getelementptr inbounds [13 x float], [13 x float]* %5, i64 0, i64 %52
%54 = load float, float* %53
%55 = load float, float* %7
%56 = load float, float* %3
%57 = load i32, i32* %6
%58 = sub nsw i32 %57, 1
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds [13 x float], [13 x float]* %4, i64 0, i64 %59
%61 = load float, float* %60
%62 = fsub float %56, %61
%63 = call float @llvm.fmuladd.f32(float %55, float %62, float %54)
store float %63, float* %2
br label %64
64: ; preds = %28, %27, %10
%65 = load float, float* %2
ret float %65
}

LLVM IR (-O2):
@__const.calculate_corrosion_speed.lander_curve_x = [13 x float] [float 0.000000e+00, float 5.000000e-01, float 0x3FF9374BC0000000, float 0x3FF9916880000000, float 0x3FFA9FBE80000000, float 0x3FFAF9DB20000000, float 0x3FFB581060000000, float 0x3FFBD2F1A0000000, float 0x3FFF333340000000, float 0x40003B6460000000, float 0x4000CAC080000000, float 0x4001353F80000000, float 0x400178D500000000]
@__const.calculate_corrosion_speed.lander_curve_y = [13 x float] [float 0x3FAB4ACB00000000, float 0x3FAC33F860000000, float 0x3FD6313BE0000000, float 0x3FE5554DA0000000, float 0x3FD793AF80000000, float 0x3FD6379FA0000000, float 0x3FA8F14DC0000000, float 0x3F913F0780000000, float 0x3F92036000000000, float 0x3FC6C1B980000000, float 0x3FE3AF33C0000000, float 0x4000028F60000000, float 0x401407F4E0000000]
define float @calculate_corrosion_speed(float %0) {
%2 = fcmp olt float %0, 0.000000e+00
br i1 %2, label %28, label %3
3: ; preds = %1, %3
%4 = phi i64 [ %8, %3 ], [ 0, %1 ]
%5 = getelementptr inbounds [13 x float], [13 x float]* @__const.calculate_corrosion_speed.lander_curve_x, i64 0, i64 %4
%6 = load float, float* %5
%7 = fcmp ugt float %6, %0
%8 = add nuw i64 %4, 1
br i1 %7, label %9, label %3
9: ; preds = %3
%10 = trunc i64 %4 to i32
%11 = icmp ugt i32 %10, 12
br i1 %11, label %28, label %12
12: ; preds = %9
%13 = and i64 %4, 4294967295
%14 = getelementptr inbounds [13 x float], [13 x float]* @__const.calculate_corrosion_speed.lander_curve_y, i64 0, i64 %13
%15 = load float, float* %14
%16 = shl i64 %4, 32
%17 = add i64 %16, -4294967296
%18 = ashr exact i64 %17, 32
%19 = getelementptr inbounds [13 x float], [13 x float]* @__const.calculate_corrosion_speed.lander_curve_y, i64 0, i64 %18
%20 = load float, float* %19
%21 = fsub float %15, %20
%22 = getelementptr inbounds [13 x float], [13 x float]* @__const.calculate_corrosion_speed.lander_curve_x, i64 0, i64 %18
%23 = load float, float* %22
%24 = fsub float %6, %23
%25 = fdiv float %21, %24
%26 = fsub float %0, %23
%27 = tail call float @llvm.fmuladd.f32(float %25, float %26, float %20)
br label %28
28: ; preds = %12, %9, %1
%29 = phi float [ 0.000000e+00, %1 ], [ %27, %12 ], [ 5.000000e+00, %9 ]
ret float %29
}