void fft_output(const float *re, const float *im, float *output) {
  float *p_output = output;
  const float *p_real = re;
  const float *p_imag = im;
  float *p_end = output + (1 << 9) / 2;
  while (p_output <= p_end) {
    *p_output = (*p_real * *p_real) + (*p_imag * *p_imag);
    p_output++;
    p_real++;
    p_imag++;
  }
  *output /= 4;
  *p_end /= 4;
}


x86 assembly (clang, -O0):
<fft_output>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x18(%rbp),%rax
add    $0x400,%rax
mov    %rax,-0x38(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x38(%rbp),%rax
ja     119d <fft_output+0x9d>
mov    -0x28(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x28(%rbp),%rax
movss  (%rax),%xmm2
mov    -0x30(%rbp),%rax
movss  (%rax),%xmm1
mov    -0x30(%rbp),%rax
mulss  (%rax),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
movss  %xmm0,(%rax)
mov    -0x20(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x20(%rbp)
mov    -0x28(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x28(%rbp)
mov    -0x30(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x30(%rbp)
jmp    1136 <fft_output+0x36>
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm0
movss  0xe53(%rip),%xmm1
divss  %xmm1,%xmm0
movss  %xmm0,(%rax)
mov    -0x38(%rbp),%rax
movss  (%rax),%xmm0
movss  0xe3b(%rip),%xmm1
divss  %xmm1,%xmm0
movss  %xmm0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<fft_output>:
lea    0x404(%rdx),%rax
lea    0x404(%rdi),%rcx
lea    0x404(%rsi),%r8
cmp    %rdx,%rcx
seta   %r9b
cmp    %rdi,%rax
seta   %cl
and    %r9b,%cl
cmp    %rdx,%r8
seta   %r8b
cmp    %rsi,%rax
seta   %al
and    %r8b,%al
or     %cl,%al
je     1140 <fft_output+0x40>
xor    %ecx,%ecx
jmp    11c5 <fft_output+0xc5>
lea    0x400(%rsi),%r9
lea    0x400(%rdi),%r8
xor    %ecx,%ecx
movups (%rdi,%rcx,4),%xmm0
movups 0x10(%rdi,%rcx,4),%xmm1
movups (%rsi,%rcx,4),%xmm2
movups 0x10(%rsi,%rcx,4),%xmm3
mulps  %xmm2,%xmm2
mulps  %xmm3,%xmm3
mulps  %xmm0,%xmm0
addps  %xmm2,%xmm0
mulps  %xmm1,%xmm1
addps  %xmm3,%xmm1
movups %xmm0,(%rdx,%rcx,4)
movups %xmm1,0x10(%rdx,%rcx,4)
movups 0x20(%rdi,%rcx,4),%xmm0
movups 0x30(%rdi,%rcx,4),%xmm1
movups 0x20(%rsi,%rcx,4),%xmm2
movups 0x30(%rsi,%rcx,4),%xmm3
mulps  %xmm2,%xmm2
mulps  %xmm3,%xmm3
mulps  %xmm0,%xmm0
addps  %xmm2,%xmm0
mulps  %xmm1,%xmm1
addps  %xmm3,%xmm1
movups %xmm0,0x20(%rdx,%rcx,4)
movups %xmm1,0x30(%rdx,%rcx,4)
add    $0x10,%rcx
cmp    $0x100,%rcx
jne    1150 <fft_output+0x50>
mov    $0x100,%ecx
mov    %r9,%rsi
mov    %r8,%rdi
movss  (%rdi),%xmm0
movss  (%rsi),%xmm1
mulss  %xmm1,%xmm1
mulss  %xmm0,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,(%rdx,%rcx,4)
test   %al,%al
je     1244 <fft_output+0x144>
mov    $0x100,%r8d
sub    %rcx,%r8
lea    (%rdx,%rcx,4),%rcx
add    $0x8,%rcx
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
nop
movss  0x4(%rdi,%rax,4),%xmm0
movss  0x4(%rsi,%rax,4),%xmm1
mulss  %xmm1,%xmm1
mulss  %xmm0,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x4(%rcx,%rax,4)
movss  0x8(%rdi,%rax,4),%xmm0
movss  0x8(%rsi,%rax,4),%xmm1
mulss  %xmm1,%xmm1
mulss  %xmm0,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,(%rcx,%rax,4)
add    $0x2,%rax
cmp    %rax,%r8
jne    1200 <fft_output+0x100>
movss  0xdb4(%rip),%xmm0
movss  (%rdx),%xmm1
mulss  %xmm0,%xmm1
movss  %xmm1,(%rdx)
mulss  0x400(%rdx),%xmm0
movss  %xmm0,0x400(%rdx)
ret

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

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