void fshift(float *indata, float *outdata, int arrlen, double shift,
            double overlap) {
  static double lopart, hipart;
  static int firsttime = 1;
  int ii;
  if (firsttime) {
    if (shift < 0.0) {
      lopart = -shift;
      hipart = 1.0 + shift;
    } else {
      lopart = 1.0 - shift;
      hipart = shift;
    }
    firsttime = 0;
  }
  outdata[0] = overlap + lopart * indata[0];
  outdata[arrlen] = hipart * indata[arrlen - 1];
  for (ii = 1; ii < arrlen; ii++)
    outdata[ii] = lopart * indata[ii] + hipart * indata[ii - 1];
}


x86 assembly (clang, -O0):
<fshift>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movsd  %xmm0,-0x20(%rbp)
movsd  %xmm1,-0x28(%rbp)
cmpl   $0x0,0x2f00(%rip)
je     119e <fshift+0x9e>
xorps  %xmm0,%xmm0
ucomisd -0x20(%rbp),%xmm0
jbe    1172 <fshift+0x72>
movsd  -0x20(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,0x2ed8(%rip)
movsd  0xea0(%rip),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,0x2ecb(%rip)
jmp    1194 <fshift+0x94>
movsd  0xe86(%rip),%xmm0
subsd  -0x20(%rbp),%xmm0
movsd  %xmm0,0x2ea9(%rip)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,0x2ea4(%rip)
movl   $0x0,0x2e82(%rip)
movsd  -0x28(%rbp),%xmm1
movsd  0x2e85(%rip),%xmm0
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm2
cvtss2sd %xmm2,%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x10(%rbp),%rax
movss  %xmm0,(%rax)
movsd  0x2e65(%rip),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm1
cvtss2sd %xmm1,%xmm1
mulsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
movl   $0x1,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    1273 <fshift+0x173>
movsd  0x2e17(%rip),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm1
cvtss2sd %xmm1,%xmm2
movsd  0x2e06(%rip),%xmm1
mov    -0x8(%rbp),%rax
mov    -0x2c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm3
cvtss2sd %xmm3,%xmm3
mulsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x10(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1205 <fshift+0x105>
pop    %rbp
ret

x86 assembly (clang, -O2):
<fshift>:
cmpb   $0x1,0x2f31(%rip)
jne    111b <fshift+0x1b>
movsd  0x2f17(%rip),%xmm2
movsd  0x2f17(%rip),%xmm0
jmp    1166 <fshift+0x66>
xorpd  %xmm2,%xmm2
ucomisd %xmm0,%xmm2
jbe    1143 <fshift+0x43>
movapd 0xee3(%rip),%xmm2
xorpd  %xmm0,%xmm2
movlpd %xmm2,0x2eef(%rip)
addsd  0xebf(%rip),%xmm0
jmp    1157 <fshift+0x57>
movsd  0xeb5(%rip),%xmm2
subsd  %xmm0,%xmm2
movsd  %xmm2,0x2ed1(%rip)
movsd  %xmm0,0x2ed1(%rip)
movb   $0x1,0x2ed2(%rip)
movss  (%rdi),%xmm3
cvtss2sd %xmm3,%xmm3
mulsd  %xmm2,%xmm3
addsd  %xmm1,%xmm3
xorps  %xmm1,%xmm1
cvtsd2ss %xmm3,%xmm1
movss  %xmm1,(%rsi)
movslq %edx,%rax
movss  -0x4(%rdi,%rax,4),%xmm1
cvtss2sd %xmm1,%xmm1
mulsd  %xmm0,%xmm1
cvtsd2ss %xmm1,%xmm1
movss  %xmm1,(%rsi,%rax,4)
cmp    $0x2,%eax
jl     13a0 <fshift+0x2a0>
mov    %edx,%r10d
lea    -0x1(%r10),%r8
mov    $0x1,%ecx
cmp    $0x4,%r8
jb     12f3 <fshift+0x1f3>
lea    0x4(%rsi),%rax
lea    (%rdi,%r10,4),%rdx
cmp    %rdx,%rax
jae    11d4 <fshift+0xd4>
lea    (%rsi,%r10,4),%rax
cmp    %rdi,%rax
ja     12f3 <fshift+0x1f3>
mov    %r8,%rcx
and    $0xfffffffffffffffc,%rcx
movapd %xmm0,%xmm3
unpcklpd %xmm0,%xmm3
movapd %xmm2,%xmm1
unpcklpd %xmm2,%xmm1
lea    -0x4(%rcx),%rax
mov    %rax,%r9
shr    $0x2,%r9
add    $0x1,%r9
test   %rax,%rax
je     13a1 <fshift+0x2a1>
mov    %r9,%rax
and    $0xfffffffffffffffe,%rax
xor    %edx,%edx
nopl   0x0(%rax)
cvtps2pd 0xc(%rdi,%rdx,4),%xmm4
cvtps2pd 0x4(%rdi,%rdx,4),%xmm5
cvtps2pd (%rdi,%rdx,4),%xmm6
cvtps2pd 0x8(%rdi,%rdx,4),%xmm7
mulpd  %xmm3,%xmm7
mulpd  %xmm3,%xmm6
mulpd  %xmm1,%xmm5
addpd  %xmm6,%xmm5
mulpd  %xmm1,%xmm4
addpd  %xmm7,%xmm4
cvtpd2ps %xmm4,%xmm4
cvtpd2ps %xmm5,%xmm5
unpcklpd %xmm4,%xmm5
movupd %xmm5,0x4(%rsi,%rdx,4)
cvtps2pd 0x1c(%rdi,%rdx,4),%xmm4
cvtps2pd 0x14(%rdi,%rdx,4),%xmm5
cvtps2pd 0x10(%rdi,%rdx,4),%xmm6
cvtps2pd 0x18(%rdi,%rdx,4),%xmm7
mulpd  %xmm3,%xmm7
mulpd  %xmm3,%xmm6
mulpd  %xmm1,%xmm5
addpd  %xmm6,%xmm5
mulpd  %xmm1,%xmm4
addpd  %xmm7,%xmm4
cvtpd2ps %xmm4,%xmm4
cvtpd2ps %xmm5,%xmm5
unpcklpd %xmm4,%xmm5
movupd %xmm5,0x14(%rsi,%rdx,4)
add    $0x8,%rdx
add    $0xfffffffffffffffe,%rax
jne    1210 <fshift+0x110>
test   $0x1,%r9b
je     12e6 <fshift+0x1e6>
lea    0x0(,%rdx,4),%rax
or     $0x4,%rax
cvtps2pd 0x8(%rdi,%rax,1),%xmm4
cvtps2pd (%rdi,%rax,1),%xmm5
cvtps2pd (%rdi,%rdx,4),%xmm6
cvtps2pd 0x8(%rdi,%rdx,4),%xmm7
mulpd  %xmm3,%xmm7
mulpd  %xmm3,%xmm6
mulpd  %xmm1,%xmm5
addpd  %xmm6,%xmm5
mulpd  %xmm1,%xmm4
addpd  %xmm7,%xmm4
cvtpd2ps %xmm4,%xmm1
cvtpd2ps %xmm5,%xmm3
unpcklpd %xmm1,%xmm3
movupd %xmm3,(%rsi,%rax,1)
cmp    %rcx,%r8
je     13a0 <fshift+0x2a0>
or     $0x1,%rcx
mov    %rcx,%rax
not    %rax
test   $0x1,%r10b
jne    132e <fshift+0x22e>
movss  -0x4(%rdi,%rcx,4),%xmm1
movss  (%rdi,%rcx,4),%xmm3
cvtss2sd %xmm3,%xmm3
cvtss2sd %xmm1,%xmm1
mulsd  %xmm0,%xmm1
mulsd  %xmm2,%xmm3
addsd  %xmm1,%xmm3
xorps  %xmm1,%xmm1
cvtsd2ss %xmm3,%xmm1
movss  %xmm1,(%rsi,%rcx,4)
add    $0x1,%rcx
add    %r10,%rax
je     13a0 <fshift+0x2a0>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movss  -0x4(%rdi,%rcx,4),%xmm1
movss  (%rdi,%rcx,4),%xmm3
cvtss2sd %xmm3,%xmm3
cvtss2sd %xmm1,%xmm1
mulsd  %xmm0,%xmm1
mulsd  %xmm2,%xmm3
addsd  %xmm1,%xmm3
xorps  %xmm1,%xmm1
cvtsd2ss %xmm3,%xmm1
movss  %xmm1,(%rsi,%rcx,4)
movss  (%rdi,%rcx,4),%xmm1
movss  0x4(%rdi,%rcx,4),%xmm3
cvtss2sd %xmm3,%xmm3
cvtss2sd %xmm1,%xmm1
mulsd  %xmm0,%xmm1
mulsd  %xmm2,%xmm3
addsd  %xmm1,%xmm3
xorps  %xmm1,%xmm1
cvtsd2ss %xmm3,%xmm1
movss  %xmm1,0x4(%rsi,%rcx,4)
add    $0x2,%rcx
cmp    %rcx,%r10
jne    1340 <fshift+0x240>
ret
xor    %edx,%edx
test   $0x1,%r9b
jne    129f <fshift+0x19f>
jmp    12e6 <fshift+0x1e6>

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

LLVM IR (-O2):
@fshift.lopart = internal unnamed_addr global double 0.000000e+00
@fshift.hipart = internal unnamed_addr global double 0.000000e+00
@fshift.firsttime = internal unnamed_addr global i1 false
define void @fshift(float* nocapture %0, float* nocapture writeonly %1, i32 %2, double %3, double %4) {
%6 = load i1, i1* @fshift.firsttime
br i1 %6, label %7, label %10
7: ; preds = %5
%8 = load double, double* @fshift.lopart
%9 = load double, double* @fshift.hipart
br label %20
10: ; preds = %5
%11 = fcmp olt double %3, 0.000000e+00
br i1 %11, label %12, label %15
12: ; preds = %10
%13 = fneg double %3
store double %13, double* @fshift.lopart
%14 = fadd double %3, 1.000000e+00
br label %17
15: ; preds = %10
%16 = fsub double 1.000000e+00, %3
store double %16, double* @fshift.lopart
br label %17
17: ; preds = %15, %12
%18 = phi double [ %16, %15 ], [ %13, %12 ]
%19 = phi double [ %3, %15 ], [ %14, %12 ]
store double %19, double* @fshift.hipart
store i1 true, i1* @fshift.firsttime
br label %20
20: ; preds = %7, %17
%21 = phi double [ %9, %7 ], [ %19, %17 ]
%22 = phi double [ %8, %7 ], [ %18, %17 ]
%23 = load float, float* %0
%24 = fpext float %23 to double
%25 = tail call double @llvm.fmuladd.f64(double %22, double %24, double %4)
%26 = fptrunc double %25 to float
store float %26, float* %1
%27 = add nsw i32 %2, -1
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds float, float* %0, i64 %28
%30 = load float, float* %29
%31 = fpext float %30 to double
%32 = fmul double %21, %31
%33 = fptrunc double %32 to float
%34 = sext i32 %2 to i64
%35 = getelementptr inbounds float, float* %1, i64 %34
store float %33, float* %35
%36 = icmp sgt i32 %2, 1
br i1 %36, label %37, label %165
37: ; preds = %20
%38 = zext i32 %2 to i64
%39 = add nsw i64 %38, -1
%40 = icmp ult i64 %39, 4
br i1 %40, label %117, label %41
41: ; preds = %37
%42 = getelementptr float, float* %1, i64 1
%43 = getelementptr float, float* %1, i64 %38
%44 = getelementptr float, float* %0, i64 %38
%45 = icmp ult float* %42, %44
%46 = icmp ugt float* %43, %0
%47 = and i1 %45, %46
br i1 %47, label %117, label %48
48: ; preds = %41
%49 = and i64 %39, -4
%50 = or i64 %49, 1
%51 = insertelement <4 x double> poison, double %21, i64 0
%52 = shufflevector <4 x double> %51, <4 x double> poison, <4 x i32> zeroinitializer
%53 = insertelement <4 x double> poison, double %22, i64 0
%54 = shufflevector <4 x double> %53, <4 x double> poison, <4 x i32> zeroinitializer
%55 = add nsw i64 %49, -4
%56 = lshr exact i64 %55, 2
%57 = add nuw nsw i64 %56, 1
%58 = and i64 %57, 1
%59 = icmp eq i64 %55, 0
br i1 %59, label %97, label %60
60: ; preds = %48
%61 = and i64 %57, 9223372036854775806
br label %62
62: ; preds = %62, %60
%63 = phi i64 [ 0, %60 ], [ %94, %62 ]
%64 = phi i64 [ 0, %60 ], [ %95, %62 ]
%65 = or i64 %63, 1
%66 = getelementptr inbounds float, float* %0, i64 %65
%67 = bitcast float* %66 to <4 x float>*
%68 = load <4 x float>, <4 x float>* %67
%69 = fpext <4 x float> %68 to <4 x double>
%70 = getelementptr inbounds float, float* %0, i64 %63
%71 = bitcast float* %70 to <4 x float>*
%72 = load <4 x float>, <4 x float>* %71
%73 = fpext <4 x float> %72 to <4 x double>
%74 = fmul <4 x double> %52, %73
%75 = call <4 x double> @llvm.fmuladd.v4f64(<4 x double> %54, <4 x double> %69, <4 x double> %74)
%76 = fptrunc <4 x double> %75 to <4 x float>
%77 = getelementptr inbounds float, float* %1, i64 %65
%78 = bitcast float* %77 to <4 x float>*
store <4 x float> %76, <4 x float>* %78
%79 = or i64 %63, 4
%80 = or i64 %63, 5
%81 = getelementptr inbounds float, float* %0, i64 %80
%82 = bitcast float* %81 to <4 x float>*
%83 = load <4 x float>, <4 x float>* %82
%84 = fpext <4 x float> %83 to <4 x double>
%85 = getelementptr inbounds float, float* %0, i64 %79
%86 = bitcast float* %85 to <4 x float>*
%87 = load <4 x float>, <4 x float>* %86
%88 = fpext <4 x float> %87 to <4 x double>
%89 = fmul <4 x double> %52, %88
%90 = call <4 x double> @llvm.fmuladd.v4f64(<4 x double> %54, <4 x double> %84, <4 x double> %89)
%91 = fptrunc <4 x double> %90 to <4 x float>
%92 = getelementptr inbounds float, float* %1, i64 %80
%93 = bitcast float* %92 to <4 x float>*
store <4 x float> %91, <4 x float>* %93
%94 = add nuw i64 %63, 8
%95 = add i64 %64, 2
%96 = icmp eq i64 %95, %61
br i1 %96, label %97, label %62
97: ; preds = %62, %48
%98 = phi i64 [ 0, %48 ], [ %94, %62 ]
%99 = icmp eq i64 %58, 0
br i1 %99, label %115, label %100
100: ; preds = %97
%101 = or i64 %98, 1
%102 = getelementptr inbounds float, float* %0, i64 %101
%103 = bitcast float* %102 to <4 x float>*
%104 = load <4 x float>, <4 x float>* %103
%105 = fpext <4 x float> %104 to <4 x double>
%106 = getelementptr inbounds float, float* %0, i64 %98
%107 = bitcast float* %106 to <4 x float>*
%108 = load <4 x float>, <4 x float>* %107
%109 = fpext <4 x float> %108 to <4 x double>
%110 = fmul <4 x double> %52, %109
%111 = call <4 x double> @llvm.fmuladd.v4f64(<4 x double> %54, <4 x double> %105, <4 x double> %110)
%112 = fptrunc <4 x double> %111 to <4 x float>
%113 = getelementptr inbounds float, float* %1, i64 %101
%114 = bitcast float* %113 to <4 x float>*
store <4 x float> %112, <4 x float>* %114
br label %115
115: ; preds = %97, %100
%116 = icmp eq i64 %39, %49
br i1 %116, label %165, label %117
117: ; preds = %41, %37, %115
%118 = phi i64 [ 1, %41 ], [ 1, %37 ], [ %50, %115 ]
%119 = xor i64 %118, -1
%120 = and i64 %38, 1
%121 = icmp eq i64 %120, 0
br i1 %121, label %122, label %135
122: ; preds = %117
%123 = getelementptr inbounds float, float* %0, i64 %118
%124 = load float, float* %123
%125 = fpext float %124 to double
%126 = add nsw i64 %118, -1
%127 = getelementptr inbounds float, float* %0, i64 %126
%128 = load float, float* %127
%129 = fpext float %128 to double
%130 = fmul double %21, %129
%131 = tail call double @llvm.fmuladd.f64(double %22, double %125, double %130)
%132 = fptrunc double %131 to float
%133 = getelementptr inbounds float, float* %1, i64 %118
store float %132, float* %133
%134 = add nuw nsw i64 %118, 1
br label %135
135: ; preds = %122, %117
%136 = phi i64 [ %118, %117 ], [ %134, %122 ]
%137 = sub nsw i64 0, %38
%138 = icmp eq i64 %119, %137
br i1 %138, label %165, label %139
139: ; preds = %135, %139
%140 = phi i64 [ %163, %139 ], [ %136, %135 ]
%141 = getelementptr inbounds float, float* %0, i64 %140
%142 = load float, float* %141
%143 = fpext float %142 to double
%144 = add nsw i64 %140, -1
%145 = getelementptr inbounds float, float* %0, i64 %144
%146 = load float, float* %145
%147 = fpext float %146 to double
%148 = fmul double %21, %147
%149 = tail call double @llvm.fmuladd.f64(double %22, double %143, double %148)
%150 = fptrunc double %149 to float
%151 = getelementptr inbounds float, float* %1, i64 %140
store float %150, float* %151
%152 = add nuw nsw i64 %140, 1
%153 = getelementptr inbounds float, float* %0, i64 %152
%154 = load float, float* %153
%155 = fpext float %154 to double
%156 = getelementptr inbounds float, float* %0, i64 %140
%157 = load float, float* %156
%158 = fpext float %157 to double
%159 = fmul double %21, %158
%160 = tail call double @llvm.fmuladd.f64(double %22, double %155, double %159)
%161 = fptrunc double %160 to float
%162 = getelementptr inbounds float, float* %1, i64 %152
store float %161, float* %162
%163 = add nuw nsw i64 %140, 2
%164 = icmp eq i64 %163, %38
br i1 %164, label %165, label %139
165: ; preds = %135, %139, %115, %20
ret void
}