void dctsub4(int n, double *a) {
  int m;
  double wki, wdr, wdi, xr;
  wki = 0.707106781186547524400844362104849039284835937688;
  m = n >> 1;
  if (m == 2) {
    wdr = wki * 0.382683432365089771728459984030398866761344562485;
    wdi = wki * 0.923879532511286756128183189396788286822416625863;
    xr = wdi * a[1] - wdr * a[3];
    a[1] = wdr * a[1] + wdi * a[3];
    a[3] = xr;
  }
  a[m] *= wki;
}


x86 assembly (clang, -O0):
<dctsub4>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
movsd  0xeed(%rip),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x4(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x14(%rbp)
cmpl   $0x2,-0x14(%rbp)
jne    11ca <dctsub4+0xca>
movsd  0xedd(%rip),%xmm0
mulsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  0xec3(%rip),%xmm0
mulsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm2
movsd  -0x28(%rbp),%xmm1
mov    -0x10(%rbp),%rax
mulsd  0x18(%rax),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm2
movsd  -0x30(%rbp),%xmm1
mov    -0x10(%rbp),%rax
mulsd  0x18(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x8(%rax)
movsd  -0x38(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x18(%rax)
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
pop    %rbp
ret

x86 assembly (clang, -O2):
<dctsub4>:
sar    %edi
cmp    $0x2,%edi
jne    114b <dctsub4+0x4b>
movsd  0x8(%rsi),%xmm0
movsd  0x18(%rsi),%xmm1
movsd  0xee7(%rip),%xmm2
mulsd  %xmm1,%xmm2
movsd  0xee3(%rip),%xmm3
movapd %xmm0,%xmm4
mulsd  %xmm3,%xmm4
addsd  %xmm2,%xmm4
mulsd  0xed7(%rip),%xmm0
mulsd  %xmm3,%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,0x8(%rsi)
movsd  %xmm4,0x18(%rsi)
movslq %edi,%rax
movsd  (%rsi,%rax,8),%xmm0
mulsd  0xebd(%rip),%xmm0
movsd  %xmm0,(%rsi,%rax,8)
ret

LLVM IR (-O0):
define void @dctsub4(i32 %0, double* %1) {
%3 = alloca i32
%4 = alloca double*
%5 = alloca i32
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
store i32 %0, i32* %3
store double* %1, double** %4
store double 0x3FE6A09E667F3BCD, double* %6
%10 = load i32, i32* %3
%11 = ashr i32 %10, 1
store i32 %11, i32* %5
%12 = load i32, i32* %5
%13 = icmp eq i32 %12, 2
br i1 %13, label %14, label %45
14: ; preds = %2
%15 = load double, double* %6
%16 = fmul double %15, 0x3FD87DE2A6AEA963
store double %16, double* %7
%17 = load double, double* %6
%18 = fmul double %17, 0x3FED906BCF328D46
store double %18, double* %8
%19 = load double, double* %8
%20 = load double*, double** %4
%21 = getelementptr inbounds double, double* %20, i64 1
%22 = load double, double* %21
%23 = load double, double* %7
%24 = load double*, double** %4
%25 = getelementptr inbounds double, double* %24, i64 3
%26 = load double, double* %25
%27 = fmul double %23, %26
%28 = fneg double %27
%29 = call double @llvm.fmuladd.f64(double %19, double %22, double %28)
store double %29, double* %9
%30 = load double, double* %7
%31 = load double*, double** %4
%32 = getelementptr inbounds double, double* %31, i64 1
%33 = load double, double* %32
%34 = load double, double* %8
%35 = load double*, double** %4
%36 = getelementptr inbounds double, double* %35, i64 3
%37 = load double, double* %36
%38 = fmul double %34, %37
%39 = call double @llvm.fmuladd.f64(double %30, double %33, double %38)
%40 = load double*, double** %4
%41 = getelementptr inbounds double, double* %40, i64 1
store double %39, double* %41
%42 = load double, double* %9
%43 = load double*, double** %4
%44 = getelementptr inbounds double, double* %43, i64 3
store double %42, double* %44
br label %45
45: ; preds = %14, %2
%46 = load double, double* %6
%47 = load double*, double** %4
%48 = load i32, i32* %5
%49 = sext i32 %48 to i64
%50 = getelementptr inbounds double, double* %47, i64 %49
%51 = load double, double* %50
%52 = fmul double %51, %46
store double %52, double* %50
ret void
}

LLVM IR (-O2):
define void @dctsub4(i32 %0, double* nocapture %1) {
%3 = ashr i32 %0, 1
%4 = icmp eq i32 %3, 2
br i1 %4, label %5, label %14
5: ; preds = %2
%6 = getelementptr inbounds double, double* %1, i64 1
%7 = load double, double* %6
%8 = getelementptr inbounds double, double* %1, i64 3
%9 = load double, double* %8
%10 = fmul double %9, 0xBFD1517A7BDB3895
%11 = tail call double @llvm.fmuladd.f64(double %7, double 0x3FE4E7AE9144F0FC, double %10)
%12 = fmul double %9, 0x3FE4E7AE9144F0FC
%13 = tail call double @llvm.fmuladd.f64(double %7, double 0x3FD1517A7BDB3895, double %12)
store double %13, double* %6
store double %11, double* %8
br label %14
14: ; preds = %5, %2
%15 = sext i32 %3 to i64
%16 = getelementptr inbounds double, double* %1, i64 %15
%17 = load double, double* %16
%18 = fmul double %17, 0x3FE6A09E667F3BCD
store double %18, double* %16
ret void
}