float AsymwExtension(const float *Src, int Stride, int N, int n) {
  float Jump, Offset;
  if (0 <= n) {
    if (n < N)
      return Src[Stride * n];
    else if (n < 2 * N - 1)
      return 2 * Src[Stride * (N - 1)] - Src[Stride * (2 * (N - 1) - n)];
  } else if (-N < n)
    return 2 * Src[0] - Src[Stride * (-n)];
  if (N == 1)
    return Src[0];
  Jump = 2 * (Src[Stride * (N - 1)] - Src[0]);
  Offset = 0;
  if (n >= N) {
    do {
      Offset += Jump;
      n -= 2 * (N - 1);
    } while (n >= N);
  } else {
    while (n <= -N) {
      Offset -= Jump;
      n += 2 * (N - 1);
    }
  }
  if (n >= 0)
    return Src[Stride * n] + Offset;
  else
    return 2 * Src[0] - Src[Stride * (-n)] + Offset;
}


x86 assembly (clang, -O0):
<AsymwExtension>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %edx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
xor    %eax,%eax
cmp    -0x1c(%rbp),%eax
jg     11b8 <AsymwExtension+0xb8>
mov    -0x1c(%rbp),%eax
cmp    -0x18(%rbp),%eax
jge    1145 <AsymwExtension+0x45>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
imul   -0x1c(%rbp),%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    134b <AsymwExtension+0x24b>
mov    -0x1c(%rbp),%eax
mov    -0x18(%rbp),%ecx
shl    $0x1,%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    11ae <AsymwExtension+0xae>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
mov    -0x18(%rbp),%edx
sub    $0x1,%edx
imul   %edx,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
mov    -0x18(%rbp),%edx
sub    $0x1,%edx
shl    $0x1,%edx
sub    -0x1c(%rbp),%edx
imul   %edx,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
addss  %xmm0,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    134b <AsymwExtension+0x24b>
jmp    11b3 <AsymwExtension+0xb3>
jmp    1209 <AsymwExtension+0x109>
xor    %eax,%eax
sub    -0x18(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1204 <AsymwExtension+0x104>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
xor    %edx,%edx
sub    -0x1c(%rbp),%edx
imul   %edx,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
addss  %xmm0,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    134b <AsymwExtension+0x24b>
jmp    1209 <AsymwExtension+0x109>
cmpl   $0x1,-0x18(%rbp)
jne    1225 <AsymwExtension+0x125>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    134b <AsymwExtension+0x24b>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
mov    -0x18(%rbp),%edx
sub    $0x1,%edx
imul   %edx,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm1
mov    -0x10(%rbp),%rax
subss  (%rax),%xmm1
movss  0xdb3(%rip),%xmm0
mulss  %xmm1,%xmm0
movss  %xmm0,-0x20(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x18(%rbp),%eax
jl     12a0 <AsymwExtension+0x1a0>
jmp    126f <AsymwExtension+0x16f>
movss  -0x20(%rbp),%xmm0
addss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x18(%rbp),%ecx
sub    $0x1,%ecx
shl    $0x1,%ecx
mov    -0x1c(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x18(%rbp),%eax
jge    126f <AsymwExtension+0x16f>
jmp    12e1 <AsymwExtension+0x1e1>
jmp    12a5 <AsymwExtension+0x1a5>
mov    -0x1c(%rbp),%eax
xor    %ecx,%ecx
sub    -0x18(%rbp),%ecx
cmp    %ecx,%eax
jg     12dc <AsymwExtension+0x1dc>
movss  -0x20(%rbp),%xmm1
movss  -0x24(%rbp),%xmm0
subss  %xmm1,%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x18(%rbp),%eax
sub    $0x1,%eax
shl    $0x1,%eax
add    -0x1c(%rbp),%eax
mov    %eax,-0x1c(%rbp)
jmp    12a5 <AsymwExtension+0x1a5>
jmp    12e1 <AsymwExtension+0x1e1>
cmpl   $0x0,-0x1c(%rbp)
jl     130d <AsymwExtension+0x20d>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
imul   -0x1c(%rbp),%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
addss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    134b <AsymwExtension+0x24b>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
xor    %edx,%edx
sub    -0x1c(%rbp),%edx
imul   %edx,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
addss  %xmm0,%xmm0
addss  %xmm1,%xmm0
addss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<AsymwExtension>:
test   %ecx,%ecx
js     1114 <AsymwExtension+0x14>
cmp    %edx,%ecx
jge    112a <AsymwExtension+0x2a>
imul   %esi,%ecx
movslq %ecx,%rax
movss  (%rdi,%rax,4),%xmm0
ret
mov    %edx,%eax
neg    %eax
cmp    %ecx,%eax
jge    1158 <AsymwExtension+0x58>
movss  (%rdi),%xmm0
imul   %esi,%ecx
neg    %ecx
movslq %ecx,%rax
jmp    114e <AsymwExtension+0x4e>
lea    (%rdx,%rdx,1),%eax
add    $0xffffffff,%eax
cmp    %ecx,%eax
jle    1158 <AsymwExtension+0x58>
lea    -0x1(%rdx),%eax
imul   %esi,%eax
cltq
movss  (%rdi,%rax,4),%xmm0
lea    (%rdx,%rdx,1),%eax
add    $0xfffffffe,%eax
sub    %ecx,%eax
imul   %esi,%eax
cltq
addss  %xmm0,%xmm0
subss  (%rdi,%rax,4),%xmm0
ret
cmp    $0x1,%edx
jne    1162 <AsymwExtension+0x62>
movss  (%rdi),%xmm0
ret
lea    -0x1(%rdx),%r8d
mov    %r8d,%eax
imul   %esi,%eax
cltq
movss  (%rdi,%rax,4),%xmm2
movss  (%rdi),%xmm1
subss  %xmm1,%xmm2
addss  %xmm2,%xmm2
cmp    %edx,%ecx
jge    11ad <AsymwExtension+0xad>
neg    %edx
xorps  %xmm0,%xmm0
cmp    %ecx,%edx
jl     11cb <AsymwExtension+0xcb>
add    %r8d,%r8d
xorps  %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
add    %r8d,%ecx
subss  %xmm2,%xmm0
cmp    %edx,%ecx
jle    11a0 <AsymwExtension+0xa0>
jmp    11cb <AsymwExtension+0xcb>
add    %r8d,%r8d
neg    %r8d
xorps  %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
add    %r8d,%ecx
addss  %xmm2,%xmm0
cmp    %edx,%ecx
jge    11c0 <AsymwExtension+0xc0>
imul   %ecx,%esi
test   %ecx,%ecx
js     11db <AsymwExtension+0xdb>
movslq %esi,%rax
addss  (%rdi,%rax,4),%xmm0
ret
neg    %esi
movslq %esi,%rax
addss  %xmm1,%xmm1
subss  (%rdi,%rax,4),%xmm1
addss  %xmm1,%xmm0
ret

LLVM IR (-O0):
define float @AsymwExtension(float* %0, i32 %1, i32 %2, i32 %3) {
%5 = alloca float
%6 = alloca float*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca float
%11 = alloca float
store float* %0, float** %6
store i32 %1, i32* %7
store i32 %2, i32* %8
store i32 %3, i32* %9
%12 = load i32, i32* %9
%13 = icmp sle i32 0, %12
br i1 %13, label %14, label %56
14: ; preds = %4
%15 = load i32, i32* %9
%16 = load i32, i32* %8
%17 = icmp slt i32 %15, %16
br i1 %17, label %18, label %26
18: ; preds = %14
%19 = load float*, float** %6
%20 = load i32, i32* %7
%21 = load i32, i32* %9
%22 = mul nsw i32 %20, %21
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds float, float* %19, i64 %23
%25 = load float, float* %24
store float %25, float* %5
br label %160
26: ; preds = %14
%27 = load i32, i32* %9
%28 = load i32, i32* %8
%29 = mul nsw i32 2, %28
%30 = sub nsw i32 %29, 1
%31 = icmp slt i32 %27, %30
br i1 %31, label %32, label %54
32: ; preds = %26
%33 = load float*, float** %6
%34 = load i32, i32* %7
%35 = load i32, i32* %8
%36 = sub nsw i32 %35, 1
%37 = mul nsw i32 %34, %36
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds float, float* %33, i64 %38
%40 = load float, float* %39
%41 = load float*, float** %6
%42 = load i32, i32* %7
%43 = load i32, i32* %8
%44 = sub nsw i32 %43, 1
%45 = mul nsw i32 2, %44
%46 = load i32, i32* %9
%47 = sub nsw i32 %45, %46
%48 = mul nsw i32 %42, %47
%49 = sext i32 %48 to i64
%50 = getelementptr inbounds float, float* %41, i64 %49
%51 = load float, float* %50
%52 = fneg float %51
%53 = call float @llvm.fmuladd.f32(float 2.000000e+00, float %40, float %52)
store float %53, float* %5
br label %160
54: ; preds = %26
br label %55
55: ; preds = %54
br label %76
56: ; preds = %4
%57 = load i32, i32* %8
%58 = sub nsw i32 0, %57
%59 = load i32, i32* %9
%60 = icmp slt i32 %58, %59
br i1 %60, label %61, label %75
61: ; preds = %56
%62 = load float*, float** %6
%63 = getelementptr inbounds float, float* %62, i64 0
%64 = load float, float* %63
%65 = load float*, float** %6
%66 = load i32, i32* %7
%67 = load i32, i32* %9
%68 = sub nsw i32 0, %67
%69 = mul nsw i32 %66, %68
%70 = sext i32 %69 to i64
%71 = getelementptr inbounds float, float* %65, i64 %70
%72 = load float, float* %71
%73 = fneg float %72
%74 = call float @llvm.fmuladd.f32(float 2.000000e+00, float %64, float %73)
store float %74, float* %5
br label %160
75: ; preds = %56
br label %76
76: ; preds = %75, %55
%77 = load i32, i32* %8
%78 = icmp eq i32 %77, 1
br i1 %78, label %79, label %83
79: ; preds = %76
%80 = load float*, float** %6
%81 = getelementptr inbounds float, float* %80, i64 0
%82 = load float, float* %81
store float %82, float* %5
br label %160
83: ; preds = %76
%84 = load float*, float** %6
%85 = load i32, i32* %7
%86 = load i32, i32* %8
%87 = sub nsw i32 %86, 1
%88 = mul nsw i32 %85, %87
%89 = sext i32 %88 to i64
%90 = getelementptr inbounds float, float* %84, i64 %89
%91 = load float, float* %90
%92 = load float*, float** %6
%93 = getelementptr inbounds float, float* %92, i64 0
%94 = load float, float* %93
%95 = fsub float %91, %94
%96 = fmul float 2.000000e+00, %95
store float %96, float* %10
store float 0.000000e+00, float* %11
%97 = load i32, i32* %9
%98 = load i32, i32* %8
%99 = icmp sge i32 %97, %98
br i1 %99, label %100, label %115
100: ; preds = %83
br label %101
101: ; preds = %110, %100
%102 = load float, float* %10
%103 = load float, float* %11
%104 = fadd float %103, %102
store float %104, float* %11
%105 = load i32, i32* %8
%106 = sub nsw i32 %105, 1
%107 = mul nsw i32 2, %106
%108 = load i32, i32* %9
%109 = sub nsw i32 %108, %107
store i32 %109, i32* %9
br label %110
110: ; preds = %101
%111 = load i32, i32* %9
%112 = load i32, i32* %8
%113 = icmp sge i32 %111, %112
br i1 %113, label %101, label %114
114: ; preds = %110
br label %131
115: ; preds = %83
br label %116
116: ; preds = %121, %115
%117 = load i32, i32* %9
%118 = load i32, i32* %8
%119 = sub nsw i32 0, %118
%120 = icmp sle i32 %117, %119
br i1 %120, label %121, label %130
121: ; preds = %116
%122 = load float, float* %10
%123 = load float, float* %11
%124 = fsub float %123, %122
store float %124, float* %11
%125 = load i32, i32* %8
%126 = sub nsw i32 %125, 1
%127 = mul nsw i32 2, %126
%128 = load i32, i32* %9
%129 = add nsw i32 %128, %127
store i32 %129, i32* %9
br label %116
130: ; preds = %116
br label %131
131: ; preds = %130, %114
%132 = load i32, i32* %9
%133 = icmp sge i32 %132, 0
br i1 %133, label %134, label %144
134: ; preds = %131
%135 = load float*, float** %6
%136 = load i32, i32* %7
%137 = load i32, i32* %9
%138 = mul nsw i32 %136, %137
%139 = sext i32 %138 to i64
%140 = getelementptr inbounds float, float* %135, i64 %139
%141 = load float, float* %140
%142 = load float, float* %11
%143 = fadd float %141, %142
store float %143, float* %5
br label %160
144: ; preds = %131
%145 = load float*, float** %6
%146 = getelementptr inbounds float, float* %145, i64 0
%147 = load float, float* %146
%148 = load float*, float** %6
%149 = load i32, i32* %7
%150 = load i32, i32* %9
%151 = sub nsw i32 0, %150
%152 = mul nsw i32 %149, %151
%153 = sext i32 %152 to i64
%154 = getelementptr inbounds float, float* %148, i64 %153
%155 = load float, float* %154
%156 = fneg float %155
%157 = call float @llvm.fmuladd.f32(float 2.000000e+00, float %147, float %156)
%158 = load float, float* %11
%159 = fadd float %157, %158
store float %159, float* %5
br label %160
160: ; preds = %144, %134, %79, %61, %32, %18
%161 = load float, float* %5
ret float %161
}

LLVM IR (-O2):
define float @AsymwExtension(float* nocapture %0, i32 %1, i32 %2, i32 %3) {
%5 = icmp sgt i32 %3, -1
br i1 %5, label %6, label %31
6: ; preds = %4
%7 = icmp slt i32 %3, %2
br i1 %7, label %8, label %13
8: ; preds = %6
%9 = mul nsw i32 %3, %1
%10 = sext i32 %9 to i64
%11 = getelementptr inbounds float, float* %0, i64 %10
%12 = load float, float* %11
br label %94
13: ; preds = %6
%14 = shl nsw i32 %2, 1
%15 = add nsw i32 %14, -1
%16 = icmp sgt i32 %15, %3
br i1 %16, label %17, label %43
17: ; preds = %13
%18 = add nsw i32 %2, -1
%19 = mul nsw i32 %18, %1
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds float, float* %0, i64 %20
%22 = load float, float* %21
%23 = shl nsw i32 %18, 1
%24 = sub nsw i32 %23, %3
%25 = mul nsw i32 %24, %1
%26 = sext i32 %25 to i64
%27 = getelementptr inbounds float, float* %0, i64 %26
%28 = load float, float* %27
%29 = fneg float %28
%30 = tail call float @llvm.fmuladd.f32(float %22, float 2.000000e+00, float %29)
br label %94
31: ; preds = %4
%32 = sub nsw i32 0, %2
%33 = icmp slt i32 %32, %3
br i1 %33, label %34, label %43
34: ; preds = %31
%35 = load float, float* %0
%36 = mul i32 %3, %1
%37 = sub i32 0, %36
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds float, float* %0, i64 %38
%40 = load float, float* %39
%41 = fneg float %40
%42 = tail call float @llvm.fmuladd.f32(float %35, float 2.000000e+00, float %41)
br label %94
43: ; preds = %31, %13
%44 = icmp eq i32 %2, 1
br i1 %44, label %45, label %47
45: ; preds = %43
%46 = load float, float* %0
br label %94
47: ; preds = %43
%48 = add nsw i32 %2, -1
%49 = mul nsw i32 %48, %1
%50 = sext i32 %49 to i64
%51 = getelementptr inbounds float, float* %0, i64 %50
%52 = load float, float* %51
%53 = load float, float* %0
%54 = fsub float %52, %53
%55 = fmul float %54, 2.000000e+00
%56 = icmp slt i32 %3, %2
br i1 %56, label %59, label %57
57: ; preds = %47
%58 = mul i32 %48, -2
br label %64
59: ; preds = %47
%60 = sub nsw i32 0, %2
%61 = icmp slt i32 %60, %3
br i1 %61, label %76, label %62
62: ; preds = %59
%63 = shl nsw i32 %48, 1
br label %70
64: ; preds = %57, %64
%65 = phi i32 [ %68, %64 ], [ %3, %57 ]
%66 = phi float [ %67, %64 ], [ 0.000000e+00, %57 ]
%67 = fadd float %55, %66
%68 = add i32 %65, %58
%69 = icmp slt i32 %68, %2
br i1 %69, label %76, label %64
70: ; preds = %62, %70
%71 = phi float [ 0.000000e+00, %62 ], [ %73, %70 ]
%72 = phi i32 [ %3, %62 ], [ %74, %70 ]
%73 = fsub float %71, %55
%74 = add nsw i32 %72, %63
%75 = icmp sgt i32 %74, %60
br i1 %75, label %76, label %70
76: ; preds = %64, %70, %59
%77 = phi i32 [ %3, %59 ], [ %74, %70 ], [ %68, %64 ]
%78 = phi float [ 0.000000e+00, %59 ], [ %73, %70 ], [ %67, %64 ]
%79 = icmp sgt i32 %77, -1
%80 = mul i32 %77, %1
br i1 %79, label %81, label %86
81: ; preds = %76
%82 = sext i32 %80 to i64
%83 = getelementptr inbounds float, float* %0, i64 %82
%84 = load float, float* %83
%85 = fadd float %78, %84
br label %94
86: ; preds = %76
%87 = sub i32 0, %80
%88 = sext i32 %87 to i64
%89 = getelementptr inbounds float, float* %0, i64 %88
%90 = load float, float* %89
%91 = fneg float %90
%92 = tail call float @llvm.fmuladd.f32(float %53, float 2.000000e+00, float %91)
%93 = fadd float %78, %92
br label %94
94: ; preds = %86, %81, %45, %34, %17, %8
%95 = phi float [ %12, %8 ], [ %30, %17 ], [ %46, %45 ], [ %85, %81 ], [ %93, %86 ], [ %42, %34 ]
ret float %95
}