int rhs_fill(double *rhs, double *G, double *w, long *kk, int n) {
  int j;
  long i, i4;
  for (i = 0; i < n; ++i) {
    i4 = i * 4;
    for (j = 0; j < 4; ++j)
      rhs[kk[i] + j] += w[i] * G[i4 + j];
  }
  return 0;
}


x86 assembly (clang, -O0):
<rhs_fill>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8d,-0x24(%rbp)
movq   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%rax
movslq -0x24(%rbp),%rcx
cmp    %rcx,%rax
jge    11bc <rhs_fill+0xbc>
mov    -0x30(%rbp),%rax
shl    $0x2,%rax
mov    %rax,-0x38(%rbp)
movl   $0x0,-0x28(%rbp)
cmpl   $0x4,-0x28(%rbp)
jge    11a6 <rhs_fill+0xa6>
mov    -0x18(%rbp),%rax
mov    -0x30(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
movslq -0x28(%rbp),%rdx
add    %rdx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    -0x30(%rbp),%rdx
mov    (%rcx,%rdx,8),%rcx
movslq -0x28(%rbp),%rdx
add    %rdx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    1144 <rhs_fill+0x44>
jmp    11ab <rhs_fill+0xab>
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
jmp    1120 <rhs_fill+0x20>
xor    %eax,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<rhs_fill>:
test   %r8d,%r8d
jle    117a <rhs_fill+0x7a>
movslq %r8d,%r8
add    $0x18,%rsi
xor    %r9d,%r9d
nop
mov    (%rcx,%r9,8),%rax
movsd  (%rdx,%r9,8),%xmm0
mulsd  -0x18(%rsi),%xmm0
addsd  (%rdi,%rax,8),%xmm0
movsd  %xmm0,(%rdi,%rax,8)
movsd  (%rdx,%r9,8),%xmm0
mulsd  -0x10(%rsi),%xmm0
addsd  0x8(%rdi,%rax,8),%xmm0
movsd  %xmm0,0x8(%rdi,%rax,8)
movsd  (%rdx,%r9,8),%xmm0
mulsd  -0x8(%rsi),%xmm0
addsd  0x10(%rdi,%rax,8),%xmm0
movsd  %xmm0,0x10(%rdi,%rax,8)
movsd  (%rdx,%r9,8),%xmm0
mulsd  (%rsi),%xmm0
addsd  0x18(%rdi,%rax,8),%xmm0
movsd  %xmm0,0x18(%rdi,%rax,8)
add    $0x1,%r9
add    $0x20,%rsi
cmp    %r9,%r8
jne    1110 <rhs_fill+0x10>
xor    %eax,%eax
ret

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

LLVM IR (-O2):
define i32 @rhs_fill(double* nocapture %0, double* nocapture %1, double* nocapture %2, i64* nocapture %3, i32 %4) {
%6 = sext i32 %4 to i64
%7 = icmp sgt i32 %4, 0
br i1 %7, label %8, label %46
8: ; preds = %5, %8
%9 = phi i64 [ %44, %8 ], [ 0, %5 ]
%10 = shl nsw i64 %9, 2
%11 = getelementptr inbounds double, double* %2, i64 %9
%12 = getelementptr inbounds i64, i64* %3, i64 %9
%13 = load i64, i64* %12
%14 = load double, double* %11
%15 = getelementptr inbounds double, double* %1, i64 %10
%16 = load double, double* %15
%17 = getelementptr inbounds double, double* %0, i64 %13
%18 = load double, double* %17
%19 = tail call double @llvm.fmuladd.f64(double %14, double %16, double %18)
store double %19, double* %17
%20 = load double, double* %11
%21 = or i64 %10, 1
%22 = getelementptr inbounds double, double* %1, i64 %21
%23 = load double, double* %22
%24 = add nsw i64 %13, 1
%25 = getelementptr inbounds double, double* %0, i64 %24
%26 = load double, double* %25
%27 = tail call double @llvm.fmuladd.f64(double %20, double %23, double %26)
store double %27, double* %25
%28 = load double, double* %11
%29 = or i64 %10, 2
%30 = getelementptr inbounds double, double* %1, i64 %29
%31 = load double, double* %30
%32 = add nsw i64 %13, 2
%33 = getelementptr inbounds double, double* %0, i64 %32
%34 = load double, double* %33
%35 = tail call double @llvm.fmuladd.f64(double %28, double %31, double %34)
store double %35, double* %33
%36 = load double, double* %11
%37 = or i64 %10, 3
%38 = getelementptr inbounds double, double* %1, i64 %37
%39 = load double, double* %38
%40 = add nsw i64 %13, 3
%41 = getelementptr inbounds double, double* %0, i64 %40
%42 = load double, double* %41
%43 = tail call double @llvm.fmuladd.f64(double %36, double %39, double %42)
store double %43, double* %41
%44 = add nuw nsw i64 %9, 1
%45 = icmp eq i64 %44, %6
br i1 %45, label %46, label %8
46: ; preds = %8, %5
ret i32 0
}