void updateSolution_CFP64(float _Complex *mat, double _Complex *x,
                          double _Complex *r, int n, long long *Idxs) {
  int i, j, offset;
  double _Complex t;
  for (i = 0; i < n; ++i) {
    t = 0.0;
    offset = i * n;
    for (j = 0; j < n; ++j) {
      t += conj(mat[offset + j]) * r[j];
    }
    x[Idxs[i] - 1] += t;
  }
}


x86 assembly (clang, -O0):
<updateSolution_CFP64>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    %r8,-0x28(%rbp)
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    12c5 <updateSolution_CFP64+0x1c5>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x2c(%rbp),%eax
imul   -0x1c(%rbp),%eax
mov    %eax,-0x34(%rbp)
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1278 <updateSolution_CFP64+0x178>
mov    -0x8(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    -0x30(%rbp),%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,8),%xmm1
movss  0x4(%rax,%rcx,8),%xmm0
cvtss2sd %xmm1,%xmm1
movsd  %xmm1,-0x88(%rbp)
ff
cvtss2sd %xmm0,%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm2
movsd  %xmm2,-0x80(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x30(%rbp),%rcx
shl    $0x4,%rcx
add    %rcx,%rax
movsd  (%rax),%xmm4
movsd  %xmm4,-0x78(%rbp)
movsd  0x8(%rax),%xmm5
movsd  %xmm5,-0x70(%rbp)
movaps %xmm1,%xmm0
mulsd  %xmm4,%xmm0
movaps %xmm2,%xmm3
mulsd  %xmm5,%xmm3
mulsd  %xmm5,%xmm1
mulsd  %xmm4,%xmm2
subsd  %xmm3,%xmm0
movsd  %xmm0,-0x68(%rbp)
addsd  %xmm2,%xmm1
movsd  %xmm1,-0x60(%rbp)
ucomisd %xmm0,%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  %xmm1,-0x50(%rbp)
jnp    1244 <updateSolution_CFP64+0x144>
movsd  -0x60(%rbp),%xmm1
movsd  -0x68(%rbp),%xmm0
ucomisd %xmm1,%xmm1
movsd  %xmm0,-0x58(%rbp)
movsd  %xmm1,-0x50(%rbp)
jnp    1244 <updateSolution_CFP64+0x144>
movsd  -0x70(%rbp),%xmm3
movsd  -0x78(%rbp),%xmm2
movsd  -0x80(%rbp),%xmm1
movsd  -0x88(%rbp),%xmm0
ff
call   12d0 <__muldc3>
movsd  %xmm0,-0x58(%rbp)
movsd  %xmm1,-0x50(%rbp)
movsd  -0x58(%rbp),%xmm3
movsd  -0x50(%rbp),%xmm2
movsd  -0x48(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm0
addsd  %xmm3,%xmm1
addsd  %xmm2,%xmm0
movsd  %xmm1,-0x48(%rbp)
movsd  %xmm0,-0x40(%rbp)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    1152 <updateSolution_CFP64+0x52>
movsd  -0x48(%rbp),%xmm3
movsd  -0x40(%rbp),%xmm2
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
movslq -0x2c(%rbp),%rdx
mov    (%rcx,%rdx,8),%rcx
sub    $0x1,%rcx
shl    $0x4,%rcx
add    %rcx,%rax
movsd  (%rax),%xmm1
movsd  0x8(%rax),%xmm0
addsd  %xmm3,%xmm1
addsd  %xmm2,%xmm0
movsd  %xmm1,(%rax)
movsd  %xmm0,0x8(%rax)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1125 <updateSolution_CFP64+0x25>
add    $0x90,%rsp
pop    %rbp
ret
xchg   %ax,%ax

x86 assembly (clang, -O2):
<updateSolution_CFP64>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
test   %ecx,%ecx
jle    122e <updateSolution_CFP64+0x12e>
mov    %rdx,%r12
mov    %rsi,%r15
mov    %rdi,%rbx
mov    %ecx,%ecx
add    $0x4,%rbx
lea    0x0(,%rcx,8),%rbp
xor    %r14d,%r14d
movaps 0xec9(%rip),%xmm7
jmp    116b <updateSolution_CFP64+0x6b>
nopl   0x0(%rax)
mov    (%r8,%r14,8),%rax
shl    $0x4,%rax
movupd -0x10(%rax,%r15,1),%xmm0
addpd  %xmm0,%xmm8
movupd %xmm8,-0x10(%rax,%r15,1)
add    $0x1,%r14
add    %rbp,%rbx
cmp    %rcx,%r14
je     122e <updateSolution_CFP64+0x12e>
xorpd  %xmm8,%xmm8
xor    %r13d,%r13d
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movss  -0x4(%rbx,%r13,1),%xmm0
movss  (%rbx,%r13,1),%xmm1
cvtss2sd %xmm0,%xmm0
cvtss2sd %xmm1,%xmm1
movupd (%r12,%r13,2),%xmm2
movaps %xmm0,%xmm4
movlhps %xmm0,%xmm4
mulpd  %xmm2,%xmm4
movaps %xmm1,%xmm3
movlhps %xmm1,%xmm3
movapd %xmm2,%xmm5
shufpd $0x1,%xmm2,%xmm5
mulpd  %xmm3,%xmm5
movapd %xmm4,%xmm6
addpd  %xmm5,%xmm6
subpd  %xmm5,%xmm4
movapd %xmm4,%xmm3
movsd  %xmm6,%xmm3
ucomisd %xmm6,%xmm6
jp     11e5 <updateSolution_CFP64+0xe5>
addpd  %xmm3,%xmm8
add    $0x8,%r13
cmp    %r13,%rbp
jne    1180 <updateSolution_CFP64+0x80>
jmp    1140 <updateSolution_CFP64+0x40>
unpckhpd %xmm4,%xmm4
ucomisd %xmm4,%xmm4
jnp    11d2 <updateSolution_CFP64+0xd2>
xorps  %xmm7,%xmm1
movapd %xmm2,%xmm3
unpckhpd %xmm2,%xmm3
mov    %r8,0x8(%rsp)
mov    %rcx,(%rsp)
movapd %xmm8,0x10(%rsp)
call   1240 <__muldc3>
movapd 0x10(%rsp),%xmm8
movaps 0xde3(%rip),%xmm7
mov    (%rsp),%rcx
mov    0x8(%rsp),%r8
movaps %xmm0,%xmm3
movlhps %xmm1,%xmm3
jmp    11d2 <updateSolution_CFP64+0xd2>
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
nopl   (%rax)

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

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