void pre_emph(double *x, double *y, const double alpha, const int leng) {
  int k;
  y[0] = x[0] * (1.0 - alpha);
  for (k = 1; k < leng; k++)
    y[k] = x[k] - x[k - 1] * alpha;
}


x86 assembly (clang, -O0):
<pre_emph>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xedc(%rip),%xmm1
subsd  -0x18(%rbp),%xmm1
mulsd  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,(%rax)
movl   $0x1,-0x20(%rbp)
mov    -0x20(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    11a6 <pre_emph+0xa6>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  -0x18(%rbp),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    113c <pre_emph+0x3c>
pop    %rbp
ret

x86 assembly (clang, -O2):
<pre_emph>:
movsd  0xef8(%rip),%xmm1
subsd  %xmm0,%xmm1
mulsd  (%rdi),%xmm1
movsd  %xmm1,(%rsi)
cmp    $0x2,%edx
jl     120a <pre_emph+0x10a>
mov    %edx,%r9d
lea    -0x1(%r9),%r8
mov    $0x1,%ecx
cmp    $0x4,%r8
jb     11a1 <pre_emph+0xa1>
lea    0x8(%rsi),%rax
lea    (%rdi,%r9,8),%rdx
cmp    %rdx,%rax
jae    1145 <pre_emph+0x45>
lea    (%rsi,%r9,8),%rax
cmp    %rdi,%rax
ja     11a1 <pre_emph+0xa1>
mov    %r8,%rdx
and    $0xfffffffffffffffc,%rdx
lea    0x1(%rdx),%rcx
movapd %xmm0,%xmm1
unpcklpd %xmm0,%xmm1
xor    %eax,%eax
nopw   0x0(%rax,%rax,1)
movupd (%rdi,%rax,8),%xmm2
movupd 0x8(%rdi,%rax,8),%xmm3
movupd 0x10(%rdi,%rax,8),%xmm4
movupd 0x18(%rdi,%rax,8),%xmm5
mulpd  %xmm1,%xmm2
subpd  %xmm2,%xmm3
mulpd  %xmm1,%xmm4
subpd  %xmm4,%xmm5
movupd %xmm3,0x8(%rsi,%rax,8)
movupd %xmm5,0x18(%rsi,%rax,8)
add    $0x4,%rax
cmp    %rax,%rdx
jne    1160 <pre_emph+0x60>
cmp    %rdx,%r8
je     120a <pre_emph+0x10a>
mov    %rcx,%rax
not    %rax
test   $0x1,%r9b
jne    11c9 <pre_emph+0xc9>
movsd  (%rdi,%rcx,8),%xmm1
movsd  -0x8(%rdi,%rcx,8),%xmm2
mulsd  %xmm0,%xmm2
subsd  %xmm2,%xmm1
movsd  %xmm1,(%rsi,%rcx,8)
add    $0x1,%rcx
add    %r9,%rax
je     120a <pre_emph+0x10a>
xchg   %ax,%ax
movsd  (%rdi,%rcx,8),%xmm1
movsd  -0x8(%rdi,%rcx,8),%xmm2
mulsd  %xmm0,%xmm2
subsd  %xmm2,%xmm1
movsd  %xmm1,(%rsi,%rcx,8)
movsd  0x8(%rdi,%rcx,8),%xmm1
movsd  (%rdi,%rcx,8),%xmm2
mulsd  %xmm0,%xmm2
subsd  %xmm2,%xmm1
movsd  %xmm1,0x8(%rsi,%rcx,8)
add    $0x2,%rcx
cmp    %rcx,%r9
jne    11d0 <pre_emph+0xd0>
ret

LLVM IR (-O0):
define void @pre_emph(double* %0, double* %1, double %2, i32 %3) {
%5 = alloca double*
%6 = alloca double*
%7 = alloca double
%8 = alloca i32
%9 = alloca i32
store double* %0, double** %5
store double* %1, double** %6
store double %2, double* %7
store i32 %3, i32* %8
%10 = load double*, double** %5
%11 = getelementptr inbounds double, double* %10, i64 0
%12 = load double, double* %11
%13 = load double, double* %7
%14 = fsub double 1.000000e+00, %13
%15 = fmul double %12, %14
%16 = load double*, double** %6
%17 = getelementptr inbounds double, double* %16, i64 0
store double %15, double* %17
store i32 1, i32* %9
br label %18
18: ; preds = %41, %4
%19 = load i32, i32* %9
%20 = load i32, i32* %8
%21 = icmp slt i32 %19, %20
br i1 %21, label %22, label %44
22: ; preds = %18
%23 = load double*, double** %5
%24 = load i32, i32* %9
%25 = sext i32 %24 to i64
%26 = getelementptr inbounds double, double* %23, i64 %25
%27 = load double, double* %26
%28 = load double*, double** %5
%29 = load i32, i32* %9
%30 = sub nsw i32 %29, 1
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds double, double* %28, i64 %31
%33 = load double, double* %32
%34 = load double, double* %7
%35 = fneg double %33
%36 = call double @llvm.fmuladd.f64(double %35, double %34, double %27)
%37 = load double*, double** %6
%38 = load i32, i32* %9
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds double, double* %37, i64 %39
store double %36, double* %40
br label %41
41: ; preds = %22
%42 = load i32, i32* %9
%43 = add nsw i32 %42, 1
store i32 %43, i32* %9
br label %18
44: ; preds = %18
ret void
}

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