double correc(int i, int n) {
  static double c1[7] = {9.5, 28.7, 1.9, 0.0, -7.0, -6.2, -1.6};
  static double c2[7] = {-6.195e3, -9.569e3, -6.728e3, -17.614e3,
                         -8.278e3, -3.570e3, 1.075e3};
  static double c3[7] = {9.338e4, 1.7516e5, 4.1040e5, 2.157e6,
                         2.376e6, 2.065e6,  2.065e6};
  static double mic = 1.0e-6, c14 = 1.9e-5;
  double an;
  if (i * n == 4)
    return c14;
  if (i < 1 || i > 7)
    return 0.0;
  else if (i != 4 && n > 20)
    return 0.0;
  else if (i == 4 && n > 40)
    return 0.0;
  an = 1.0 / (double)(n * n);
  return (c1[i - 1] + an * (c2[i - 1] + an * c3[i - 1])) * mic;
}


x86 assembly (clang, -O0):
<correc>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0xc(%rbp)
mov    %esi,-0x10(%rbp)
mov    -0xc(%rbp),%eax
imul   -0x10(%rbp),%eax
cmp    $0x4,%eax
jne    112c <correc+0x2c>
movsd  0x2fce(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    121b <correc+0x11b>
cmpl   $0x1,-0xc(%rbp)
jl     1140 <correc+0x40>
cmpl   $0x7,-0xc(%rbp)
jle    114d <correc+0x4d>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    121b <correc+0x11b>
cmpl   $0x4,-0xc(%rbp)
je     116e <correc+0x6e>
cmpl   $0x14,-0x10(%rbp)
jle    116e <correc+0x6e>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    121b <correc+0x11b>
cmpl   $0x4,-0xc(%rbp)
jne    118f <correc+0x8f>
cmpl   $0x28,-0x10(%rbp)
jle    118f <correc+0x8f>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    121b <correc+0x11b>
jmp    1194 <correc+0x94>
jmp    1199 <correc+0x99>
mov    -0x10(%rbp),%eax
imul   -0x10(%rbp),%eax
cvtsi2sd %eax,%xmm1
movsd  0xe54(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
movslq %eax,%rcx
lea    0x2e6b(%rip),%rax
movsd  (%rax,%rcx,8),%xmm1
movsd  -0x18(%rbp),%xmm0
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
movslq %eax,%rcx
lea    0x2e91(%rip),%rax
movsd  (%rax,%rcx,8),%xmm3
movsd  -0x18(%rbp),%xmm2
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
movslq %eax,%rcx
lea    0x2eb7(%rip),%rax
movsd  (%rax,%rcx,8),%xmm4
mulsd  %xmm4,%xmm2
addsd  %xmm3,%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mulsd  0x2ed2(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<correc>:
mov    %esi,%eax
imul   %edi,%eax
cmp    $0x4,%eax
jne    1113 <correc+0x13>
movsd  0xeee(%rip),%xmm0
ret
lea    -0x8(%rdi),%eax
xorps  %xmm0,%xmm0
cmp    $0xfffffff9,%eax
jb     1128 <correc+0x28>
cmp    $0x4,%edi
je     1129 <correc+0x29>
cmp    $0x14,%esi
jle    1129 <correc+0x29>
ret
cmp    $0x4,%edi
jne    1133 <correc+0x33>
cmp    $0x28,%esi
jg     1128 <correc+0x28>
imul   %esi,%esi
xorps  %xmm0,%xmm0
cvtsi2sd %esi,%xmm0
movsd  0xec3(%rip),%xmm1
divsd  %xmm0,%xmm1
add    $0xffffffff,%edi
lea    0xecd(%rip),%rax
lea    0xf06(%rip),%rcx
lea    0xf3f(%rip),%rdx
movsd  (%rdx,%rdi,8),%xmm0
mulsd  %xmm1,%xmm0
addsd  (%rcx,%rdi,8),%xmm0
mulsd  %xmm1,%xmm0
addsd  (%rax,%rdi,8),%xmm0
mulsd  0xe90(%rip),%xmm0
ret

LLVM IR (-O0):
@correc.c1 = internal global [7 x double] [double 9.500000e+00, double 2.870000e+01, double 1.900000e+00, double 0.000000e+00, double -7.000000e+00, double -6.200000e+00, double -1.600000e+00]
@correc.c2 = internal global [7 x double] [double -6.195000e+03, double -9.569000e+03, double -6.728000e+03, double -1.761400e+04, double -8.278000e+03, double -3.570000e+03, double 1.075000e+03]
@correc.c3 = internal global [7 x double] [double 9.338000e+04, double 1.751600e+05, double 4.104000e+05, double 2.157000e+06, double 2.376000e+06, double 2.065000e+06, double 2.065000e+06]
@correc.mic = internal global double 0x3EB0C6F7A0B5ED8D
@correc.c14 = internal global double 1.900000e-05
define double @correc(i32 %0, i32 %1) {
%3 = alloca double
%4 = alloca i32
%5 = alloca i32
%6 = alloca double
store i32 %0, i32* %4
store i32 %1, i32* %5
%7 = load i32, i32* %4
%8 = load i32, i32* %5
%9 = mul nsw i32 %7, %8
%10 = icmp eq i32 %9, 4
br i1 %10, label %11, label %13
11: ; preds = %2
%12 = load double, double* @correc.c14
store double %12, double* %3
br label %63
13: ; preds = %2
%14 = load i32, i32* %4
%15 = icmp slt i32 %14, 1
br i1 %15, label %19, label %16
16: ; preds = %13
%17 = load i32, i32* %4
%18 = icmp sgt i32 %17, 7
br i1 %18, label %19, label %20
19: ; preds = %16, %13
store double 0.000000e+00, double* %3
br label %63
20: ; preds = %16
%21 = load i32, i32* %4
%22 = icmp ne i32 %21, 4
br i1 %22, label %23, label %27
23: ; preds = %20
%24 = load i32, i32* %5
%25 = icmp sgt i32 %24, 20
br i1 %25, label %26, label %27
26: ; preds = %23
store double 0.000000e+00, double* %3
br label %63
27: ; preds = %23, %20
%28 = load i32, i32* %4
%29 = icmp eq i32 %28, 4
br i1 %29, label %30, label %34
30: ; preds = %27
%31 = load i32, i32* %5
%32 = icmp sgt i32 %31, 40
br i1 %32, label %33, label %34
33: ; preds = %30
store double 0.000000e+00, double* %3
br label %63
34: ; preds = %30, %27
br label %35
35: ; preds = %34
br label %36
36: ; preds = %35
%37 = load i32, i32* %5
%38 = load i32, i32* %5
%39 = mul nsw i32 %37, %38
%40 = sitofp i32 %39 to double
%41 = fdiv double 1.000000e+00, %40
store double %41, double* %6
%42 = load i32, i32* %4
%43 = sub nsw i32 %42, 1
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds [7 x double], [7 x double]* @correc.c1, i64 0, i64 %44
%46 = load double, double* %45
%47 = load double, double* %6
%48 = load i32, i32* %4
%49 = sub nsw i32 %48, 1
%50 = sext i32 %49 to i64
%51 = getelementptr inbounds [7 x double], [7 x double]* @correc.c2, i64 0, i64 %50
%52 = load double, double* %51
%53 = load double, double* %6
%54 = load i32, i32* %4
%55 = sub nsw i32 %54, 1
%56 = sext i32 %55 to i64
%57 = getelementptr inbounds [7 x double], [7 x double]* @correc.c3, i64 0, i64 %56
%58 = load double, double* %57
%59 = call double @llvm.fmuladd.f64(double %53, double %58, double %52)
%60 = call double @llvm.fmuladd.f64(double %47, double %59, double %46)
%61 = load double, double* @correc.mic
%62 = fmul double %60, %61
store double %62, double* %3
br label %63
63: ; preds = %36, %33, %26, %19, %11
%64 = load double, double* %3
ret double %64
}

LLVM IR (-O2):
@correc.c1 = internal unnamed_addr constant [7 x double] [double 9.500000e+00, double 2.870000e+01, double 1.900000e+00, double 0.000000e+00, double -7.000000e+00, double -6.200000e+00, double -1.600000e+00]
@correc.c2 = internal unnamed_addr constant [7 x double] [double -6.195000e+03, double -9.569000e+03, double -6.728000e+03, double -1.761400e+04, double -8.278000e+03, double -3.570000e+03, double 1.075000e+03]
@correc.c3 = internal unnamed_addr constant [7 x double] [double 9.338000e+04, double 1.751600e+05, double 4.104000e+05, double 2.157000e+06, double 2.376000e+06, double 2.065000e+06, double 2.065000e+06]
define double @correc(i32 %0, i32 %1) {
%3 = mul nsw i32 %1, %0
%4 = icmp eq i32 %3, 4
br i1 %4, label %31, label %5
5: ; preds = %2
%6 = add i32 %0, -8
%7 = icmp ult i32 %6, -7
br i1 %7, label %31, label %8
8: ; preds = %5
%9 = icmp ne i32 %0, 4
%10 = icmp sgt i32 %1, 20
%11 = and i1 %9, %10
br i1 %11, label %31, label %12
12: ; preds = %8
%13 = icmp eq i32 %0, 4
%14 = icmp sgt i32 %1, 40
%15 = and i1 %13, %14
br i1 %15, label %31, label %16
16: ; preds = %12
%17 = mul nsw i32 %1, %1
%18 = sitofp i32 %17 to double
%19 = fdiv double 1.000000e+00, %18
%20 = add nsw i32 %0, -1
%21 = zext i32 %20 to i64
%22 = getelementptr inbounds [7 x double], [7 x double]* @correc.c1, i64 0, i64 %21
%23 = load double, double* %22
%24 = getelementptr inbounds [7 x double], [7 x double]* @correc.c2, i64 0, i64 %21
%25 = load double, double* %24
%26 = getelementptr inbounds [7 x double], [7 x double]* @correc.c3, i64 0, i64 %21
%27 = load double, double* %26
%28 = tail call double @llvm.fmuladd.f64(double %19, double %27, double %25)
%29 = tail call double @llvm.fmuladd.f64(double %19, double %28, double %23)
%30 = fmul double %29, 0x3EB0C6F7A0B5ED8D
br label %31
31: ; preds = %12, %8, %5, %2, %16
%32 = phi double [ %30, %16 ], [ 1.900000e-05, %2 ], [ 0.000000e+00, %5 ], [ 0.000000e+00, %8 ], [ 0.000000e+00, %12 ]
ret double %32
}