void updateSolutionLocal_CFP32(float _Complex *mat, float _Complex *x,
                               float _Complex *r, int n) {
  int i, j;
  float _Complex t;
  for (i = 0; i < n; ++i) {
    t = 0.0;
    for (j = 0; j < n; ++j) {
      t += conj(mat[i * n + j]) * r[j];
    }
    x[i] = t;
  }
}


x86 assembly (clang, -O0):
<updateSolutionLocal_CFP32>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
movl   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    12a3 <updateSolutionLocal_CFP32+0x1a3>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x30(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x2c(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1278 <updateSolutionLocal_CFP32+0x178>
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
imul   -0x1c(%rbp),%ecx
add    -0x24(%rbp),%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,8),%xmm1
movss  0x4(%rax,%rcx,8),%xmm0
cvtss2sd %xmm1,%xmm1
movsd  %xmm1,-0x70(%rbp)
cvtss2sd %xmm0,%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm2
movsd  %xmm2,-0x68(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
movss  (%rax,%rcx,8),%xmm3
movss  0x4(%rax,%rcx,8),%xmm0
cvtss2sd %xmm3,%xmm4
movsd  %xmm4,-0x60(%rbp)
cvtss2sd %xmm0,%xmm5
movsd  %xmm5,-0x58(%rbp)
movaps %xmm1,%xmm0
mulsd  %xmm4,%xmm0
movaps %xmm2,%xmm3
mulsd  %xmm5,%xmm3
mulsd  %xmm5,%xmm1
mulsd  %xmm4,%xmm2
subsd  %xmm3,%xmm0
movsd  %xmm0,-0x50(%rbp)
addsd  %xmm2,%xmm1
movsd  %xmm1,-0x48(%rbp)
ucomisd %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  %xmm1,-0x38(%rbp)
jnp    1234 <updateSolutionLocal_CFP32+0x134>
movsd  -0x48(%rbp),%xmm1
movsd  -0x50(%rbp),%xmm0
ucomisd %xmm1,%xmm1
movsd  %xmm0,-0x40(%rbp)
movsd  %xmm1,-0x38(%rbp)
jnp    1234 <updateSolutionLocal_CFP32+0x134>
movsd  -0x58(%rbp),%xmm3
movsd  -0x60(%rbp),%xmm2
movsd  -0x68(%rbp),%xmm1
movsd  -0x70(%rbp),%xmm0
call   12b0 <__muldc3>
movsd  %xmm0,-0x40(%rbp)
movsd  %xmm1,-0x38(%rbp)
movsd  -0x40(%rbp),%xmm3
movsd  -0x38(%rbp),%xmm2
movss  -0x30(%rbp),%xmm1
movss  -0x2c(%rbp),%xmm0
cvtss2sd %xmm1,%xmm1
cvtss2sd %xmm0,%xmm0
addsd  %xmm3,%xmm1
addsd  %xmm2,%xmm0
cvtsd2ss %xmm1,%xmm1
cvtsd2ss %xmm0,%xmm0
movss  %xmm1,-0x30(%rbp)
movss  %xmm0,-0x2c(%rbp)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    1141 <updateSolutionLocal_CFP32+0x41>
movss  -0x30(%rbp),%xmm1
movss  -0x2c(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
movss  %xmm1,(%rax,%rcx,8)
movss  %xmm0,0x4(%rax,%rcx,8)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    111e <updateSolutionLocal_CFP32+0x1e>
add    $0x70,%rsp
pop    %rbp
ret
nopl   0x0(%rax)

x86 assembly (clang, -O2):
<updateSolutionLocal_CFP32>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
test   %ecx,%ecx
jle    1231 <updateSolutionLocal_CFP32+0x131>
mov    %rdx,%r15
mov    %rsi,%r14
mov    %rdi,%rbx
mov    %ecx,%r12d
lea    0x0(,%r12,8),%rax
xor    %ebp,%ebp
movapd 0xecc(%rip),%xmm5
jmp    115d <updateSolutionLocal_CFP32+0x5d>
cs nopw 0x0(%rax,%rax,1)
movss  %xmm6,(%r14,%rbp,8)
movss  %xmm7,0x4(%r14,%rbp,8)
add    $0x1,%rbp
add    %rax,%rbx
cmp    %r12,%rbp
je     1231 <updateSolutionLocal_CFP32+0x131>
xorps  %xmm6,%xmm6
xor    %r13d,%r13d
xorps  %xmm7,%xmm7
cs nopw 0x0(%rax,%rax,1)
cvtps2pd (%rbx,%r13,8),%xmm0
cvtps2pd (%r15,%r13,8),%xmm2
movapd %xmm0,%xmm1
mulpd  %xmm2,%xmm1
movapd %xmm1,%xmm3
unpckhpd %xmm1,%xmm3
addsd  %xmm1,%xmm3
movapd %xmm2,%xmm1
shufpd $0x1,%xmm2,%xmm1
mulpd  %xmm0,%xmm1
movapd %xmm1,%xmm4
unpckhpd %xmm1,%xmm4
subsd  %xmm4,%xmm1
ucomisd %xmm3,%xmm3
jp     11df <updateSolutionLocal_CFP32+0xdf>
xorps  %xmm0,%xmm0
cvtss2sd %xmm6,%xmm0
addsd  %xmm3,%xmm0
xorps  %xmm2,%xmm2
cvtss2sd %xmm7,%xmm2
addsd  %xmm1,%xmm2
xorps  %xmm6,%xmm6
cvtsd2ss %xmm0,%xmm6
xorps  %xmm7,%xmm7
cvtsd2ss %xmm2,%xmm7
add    $0x1,%r13
cmp    %r13,%r12
jne    1170 <updateSolutionLocal_CFP32+0x70>
jmp    1140 <updateSolutionLocal_CFP32+0x40>
ucomisd %xmm1,%xmm1
jnp    11ad <updateSolutionLocal_CFP32+0xad>
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
xorpd  %xmm5,%xmm1
movapd %xmm2,%xmm3
unpckhpd %xmm2,%xmm3
mov    %rax,0x10(%rsp)
movss  %xmm6,0xc(%rsp)
movss  %xmm7,0x8(%rsp)
call   1240 <__muldc3>
movss  0x8(%rsp),%xmm7
movss  0xc(%rsp),%xmm6
movapd 0xddd(%rip),%xmm5
mov    0x10(%rsp),%rax
movapd %xmm0,%xmm3
jmp    11ad <updateSolutionLocal_CFP32+0xad>
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define void @updateSolutionLocal_CFP32({ float, float }* nocapture %0, { float, float }* nocapture writeonly %1, { float, float }* nocapture %2, i32 %3) {
%5 = icmp sgt i32 %3, 0
br i1 %5, label %6, label %62
6: ; preds = %4
%7 = zext i32 %3 to i64
%8 = zext i32 %3 to i64
br label %9
9: ; preds = %57, %6
%10 = phi i64 [ 0, %6 ], [ %60, %57 ]
%11 = mul nsw i64 %10, %7
br label %12
12: ; preds = %9, %46
%13 = phi i64 [ 0, %9 ], [ %55, %46 ]
%14 = phi float [ 0.000000e+00, %9 ], [ %53, %46 ]
%15 = phi float [ 0.000000e+00, %9 ], [ %54, %46 ]
%16 = add nuw nsw i64 %13, %11
%17 = getelementptr inbounds { float, float }, { float, float }* %0, i64 %16, i32 0
%18 = bitcast float* %17 to <2 x float>*
%19 = load <2 x float>, <2 x float>* %18
%20 = fpext <2 x float> %19 to <2 x double>
%21 = extractelement <2 x double> %20, i64 1
%22 = fneg double %21
%23 = getelementptr inbounds { float, float }, { float, float }* %2, i64 %13, i32 0
%24 = bitcast float* %23 to <2 x float>*
%25 = load <2 x float>, <2 x float>* %24
%26 = fpext <2 x float> %25 to <2 x double>
%27 = fmul <2 x double> %20, %26
%28 = shufflevector <2 x double> %27, <2 x double> poison, <2 x i32> <i32 1, i32 undef>
%29 = fadd <2 x double> %27, %28
%30 = extractelement <2 x double> %29, i64 0
%31 = shufflevector <2 x double> %26, <2 x double> poison, <2 x i32> <i32 1, i32 0>
%32 = fmul <2 x double> %31, %20
%33 = shufflevector <2 x double> %32, <2 x double> poison, <2 x i32> <i32 1, i32 undef>
%34 = fsub <2 x double> %32, %33
%35 = extractelement <2 x double> %34, i64 0
%36 = fcmp uno double %30, 0.000000e+00
br i1 %36, label %37, label %46
37: ; preds = %12
%38 = fcmp uno double %35, 0.000000e+00
br i1 %38, label %39, label %46
39: ; preds = %37
%40 = extractelement <2 x double> %20, i64 0
%41 = extractelement <2 x double> %26, i64 0
%42 = extractelement <2 x double> %26, i64 1
%43 = tail call { double, double } @__muldc3(double %40, double %22, double %41, double %42)
%44 = extractvalue { double, double } %43, 0
%45 = extractvalue { double, double } %43, 1
br label %46
46: ; preds = %39, %37, %12
%47 = phi double [ %30, %12 ], [ %30, %37 ], [ %44, %39 ]
%48 = phi double [ %35, %12 ], [ %35, %37 ], [ %45, %39 ]
%49 = fpext float %14 to double
%50 = fpext float %15 to double
%51 = fadd double %47, %49
%52 = fadd double %48, %50
%53 = fptrunc double %51 to float
%54 = fptrunc double %52 to float
%55 = add nuw nsw i64 %13, 1
%56 = icmp eq i64 %55, %8
br i1 %56, label %57, label %12
57: ; preds = %46
%58 = getelementptr inbounds { float, float }, { float, float }* %1, i64 %10, i32 0
%59 = getelementptr inbounds { float, float }, { float, float }* %1, i64 %10, i32 1
store float %53, float* %58
store float %54, float* %59
%60 = add nuw nsw i64 %10, 1
%61 = icmp eq i64 %60, %8
br i1 %61, label %62, label %9
62: ; preds = %57, %4
ret void
}