double kernel(int n, double *t, double t0, double dt, double *softr) {
  int i;
  double norm = 0.0, val = 0.0, k, delta;
  for (i = 0; i < n; ++i) {
    delta = t[i] - t0;
    if (delta >= -dt && delta <= dt) {
      if (delta >= 0.0) {
        k = delta / dt - 1.0;
        k *= k;
      } else {
        k = delta / dt + 1.0;
        k *= -k;
      }
      norm += k * k;
      val += k * softr[i];
    }
  }
  val /= norm;
  return val * val;
}


x86 assembly (clang, -O0):
<kernel>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
movsd  %xmm1,-0x20(%rbp)
mov    %rdx,-0x28(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    1267 <kernel+0x167>
mov    -0x10(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
subsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x50(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
ucomisd %xmm1,%xmm0
jb     1254 <kernel+0x154>
movsd  -0x50(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jb     1254 <kernel+0x154>
movsd  -0x50(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     11d3 <kernel+0xd3>
movsd  -0x50(%rbp),%xmm0
divsd  -0x20(%rbp),%xmm0
movsd  0xe4a(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
mulsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
jmp    1214 <kernel+0x114>
movsd  -0x50(%rbp),%xmm0
divsd  -0x20(%rbp),%xmm0
movsd  0xe1b(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm2
movsd  -0x38(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x48(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x40(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
jmp    1259 <kernel+0x159>
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1130 <kernel+0x30>
movsd  -0x38(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
mulsd  -0x40(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<kernel>:
test   %edi,%edi
jle    11aa <kernel+0xaa>
movapd 0xf10(%rip),%xmm2
xorpd  %xmm1,%xmm2
mov    %edi,%eax
xorpd  %xmm3,%xmm3
xor    %ecx,%ecx
xorpd  %xmm4,%xmm4
movsd  0xee7(%rip),%xmm8
movapd 0xeee(%rip),%xmm9
movsd  0xece(%rip),%xmm7
jmp    1170 <kernel+0x70>
nopl   0x0(%rax)
addsd  %xmm8,%xmm6
movapd %xmm6,%xmm5
xorpd  %xmm9,%xmm5
mulsd  %xmm5,%xmm6
movapd %xmm6,%xmm5
unpcklpd %xmm6,%xmm5
movhpd (%rdx,%rcx,8),%xmm6
mulpd  %xmm5,%xmm6
addpd  %xmm6,%xmm3
add    $0x1,%rcx
cmp    %rcx,%rax
je     1199 <kernel+0x99>
movsd  (%rsi,%rcx,8),%xmm6
subsd  %xmm0,%xmm6
ucomisd %xmm2,%xmm6
jb     1167 <kernel+0x67>
ucomisd %xmm6,%xmm1
jb     1167 <kernel+0x67>
ucomisd %xmm4,%xmm6
divsd  %xmm1,%xmm6
jb     1140 <kernel+0x40>
addsd  %xmm7,%xmm6
mulsd  %xmm6,%xmm6
jmp    1152 <kernel+0x52>
movapd %xmm3,%xmm0
unpckhpd %xmm3,%xmm0
divsd  %xmm3,%xmm0
mulsd  %xmm0,%xmm0
ret
movsd  0xe4e(%rip),%xmm0
mulsd  %xmm0,%xmm0
ret

LLVM IR (-O0):
define double @kernel(i32 %0, double* %1, double %2, double %3, double* %4) {
%6 = alloca i32
%7 = alloca double*
%8 = alloca double
%9 = alloca double
%10 = alloca double*
%11 = alloca i32
%12 = alloca double
%13 = alloca double
%14 = alloca double
%15 = alloca double
store i32 %0, i32* %6
store double* %1, double** %7
store double %2, double* %8
store double %3, double* %9
store double* %4, double** %10
store double 0.000000e+00, double* %12
store double 0.000000e+00, double* %13
store i32 0, i32* %11
br label %16
16: ; preds = %70, %5
%17 = load i32, i32* %11
%18 = load i32, i32* %6
%19 = icmp slt i32 %17, %18
br i1 %19, label %20, label %73
20: ; preds = %16
%21 = load double*, double** %7
%22 = load i32, i32* %11
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds double, double* %21, i64 %23
%25 = load double, double* %24
%26 = load double, double* %8
%27 = fsub double %25, %26
store double %27, double* %15
%28 = load double, double* %15
%29 = load double, double* %9
%30 = fneg double %29
%31 = fcmp oge double %28, %30
br i1 %31, label %32, label %69
32: ; preds = %20
%33 = load double, double* %15
%34 = load double, double* %9
%35 = fcmp ole double %33, %34
br i1 %35, label %36, label %69
36: ; preds = %32
%37 = load double, double* %15
%38 = fcmp oge double %37, 0.000000e+00
br i1 %38, label %39, label %47
39: ; preds = %36
%40 = load double, double* %15
%41 = load double, double* %9
%42 = fdiv double %40, %41
%43 = fsub double %42, 1.000000e+00
store double %43, double* %14
%44 = load double, double* %14
%45 = load double, double* %14
%46 = fmul double %45, %44
store double %46, double* %14
br label %56
47: ; preds = %36
%48 = load double, double* %15
%49 = load double, double* %9
%50 = fdiv double %48, %49
%51 = fadd double %50, 1.000000e+00
store double %51, double* %14
%52 = load double, double* %14
%53 = fneg double %52
%54 = load double, double* %14
%55 = fmul double %54, %53
store double %55, double* %14
br label %56
56: ; preds = %47, %39
%57 = load double, double* %14
%58 = load double, double* %14
%59 = load double, double* %12
%60 = call double @llvm.fmuladd.f64(double %57, double %58, double %59)
store double %60, double* %12
%61 = load double, double* %14
%62 = load double*, double** %10
%63 = load i32, i32* %11
%64 = sext i32 %63 to i64
%65 = getelementptr inbounds double, double* %62, i64 %64
%66 = load double, double* %65
%67 = load double, double* %13
%68 = call double @llvm.fmuladd.f64(double %61, double %66, double %67)
store double %68, double* %13
br label %69
69: ; preds = %56, %32, %20
br label %70
70: ; preds = %69
%71 = load i32, i32* %11
%72 = add nsw i32 %71, 1
store i32 %72, i32* %11
br label %16
73: ; preds = %16
%74 = load double, double* %12
%75 = load double, double* %13
%76 = fdiv double %75, %74
store double %76, double* %13
%77 = load double, double* %13
%78 = load double, double* %13
%79 = fmul double %77, %78
ret double %79
}

LLVM IR (-O2):
define double @kernel(i32 %0, double* nocapture %1, double %2, double %3, double* nocapture %4) {
%6 = icmp sgt i32 %0, 0
br i1 %6, label %7, label %45
7: ; preds = %5
%8 = fneg double %3
%9 = zext i32 %0 to i64
br label %10
10: ; preds = %7, %37
%11 = phi i64 [ 0, %7 ], [ %39, %37 ]
%12 = phi <2 x double> [ zeroinitializer, %7 ], [ %38, %37 ]
%13 = getelementptr inbounds double, double* %1, i64 %11
%14 = load double, double* %13
%15 = fsub double %14, %2
%16 = fcmp ult double %15, %8
%17 = fcmp ugt double %15, %3
%18 = or i1 %16, %17
br i1 %18, label %37, label %19
19: ; preds = %10
%20 = fcmp ult double %15, 0.000000e+00
%21 = fdiv double %15, %3
br i1 %20, label %25, label %22
22: ; preds = %19
%23 = fadd double %21, -1.000000e+00
%24 = fmul double %23, %23
br label %29
25: ; preds = %19
%26 = fadd double %21, 1.000000e+00
%27 = fneg double %26
%28 = fmul double %26, %27
br label %29
29: ; preds = %25, %22
%30 = phi double [ %24, %22 ], [ %28, %25 ]
%31 = getelementptr inbounds double, double* %4, i64 %11
%32 = load double, double* %31
%33 = insertelement <2 x double> poison, double %30, i64 0
%34 = shufflevector <2 x double> %33, <2 x double> poison, <2 x i32> zeroinitializer
%35 = insertelement <2 x double> %33, double %32, i64 1
%36 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %34, <2 x double> %35, <2 x double> %12)
br label %37
37: ; preds = %10, %29
%38 = phi <2 x double> [ %36, %29 ], [ %12, %10 ]
%39 = add nuw nsw i64 %11, 1
%40 = icmp eq i64 %39, %9
br i1 %40, label %41, label %10
41: ; preds = %37
%42 = extractelement <2 x double> %38, i64 0
%43 = extractelement <2 x double> %38, i64 1
%44 = fdiv double %43, %42
br label %45
45: ; preds = %41, %5
%46 = phi double [ %44, %41 ], [ 0x7FF8000000000000, %5 ]
%47 = fmul double %46, %46
ret double %47
}